I am able to set the column's header but not able to set icon in all the rows of first column of JTable.
public class iconRenderer extends DefaultTableCellRenderer{
public Component getTableCellRendererComponent(JTable table,Object obj,boolean isSelected,boolean hasFocus,int row,int column){
imageicon i=(imageicon)obj;
if(obj==i)
setIcon(i.imageIcon);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(JLabel.CENTER);
return this;
}
}
public class imageicon{
ImageIcon imageIcon;
imageicon(ImageIcon icon){
imageIcon=icon;
}
}
and below lines in my BuildTable() method.
public void SetIcon(JTable table, int col_index, ImageIcon icon){
table.getTableHeader().getColumnModel().getColumn(col_index).setHeaderRenderer(new iconRenderer());
table.getColumnModel().getColumn(col_index).setHeaderValue(new imageicon(icon));
}
How can we set it for all rows of first columns? I have tried with for loop but didnt get yet for rows to iterate to set icon. Or is there any other way?
There is no need to create a custom render. JTable already supports an Icon renderer. YOu just need to tell the table to use this renderer. This is done by overriding the getColumnClass(...) method of the table model:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableIcon extends JPanel
{
public TableIcon()
{
Icon aboutIcon = new ImageIcon("about16.gif");
Icon addIcon = new ImageIcon("add16.gif");
Icon copyIcon = new ImageIcon("copy16.gif");
String[] columnNames = {"Picture", "Description"};
Object[][] data =
{
{aboutIcon, "About"},
{addIcon, "Add"},
{copyIcon, "Copy"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
switch (column)
{
case 0: return Icon.class;
default: return super.getColumnClass(column);
}
}
};
JTable table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Table Icon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableIcon());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
You are just using iconRenderer for the render of your header. Also set the Column's Cell Reneder to be an instance of iconRenderer as well. Call setCellRenderer on the column.
http://download.oracle.com/javase/6/docs/api/javax/swing/table/TableColumn.html#setCellRenderer(javax.swing.table.TableCellRenderer)
Side note: Java coding standards specify that class names should start with capital letters, so iconRenderer should be IconRenderer instead.
I know the post is a little old but it's never too late ...
I will post here how to insert an icon without using a DefaultTableCellRenderer class, I use this for when I will only show an icon on the screen in a simple way not very elaborate.
I do it in a simple way ... I always create some tablemodel creators in the classes that I inherit. I usually pass by parameter the list of titles and types of objects.
Method that creates the tablemodel in the upper class:
protected void createTableModel(String[] columns, Class[] types){
String[] vetStr = new String[columns.length];
boolean[] vetBoo = new boolean[columns.length];
Arrays.fill(vetStr, null);
Arrays.fill(vetBoo, false);
table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] { vetStr },
columns
) {
boolean[] canEdit = vetBoo;
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
table.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
}
Inherited class constructor:
"See that here I set the type as ImageIcon.class for the column"
.... constructor....
super("Balança");
String[] columns = {"#", "Nome", "Porta", "Padrão"};
Class[] types = {Long.class, String.class, String.class, ImageIcon.class};
**strong text**super.createTableModel(columns, types);
When I list the items on the tablemodel there I show the image.
list.forEach( obj -> {
tableModel.addRow(new Object[]{
obj.getId(),
obj.getName(),
obj.getPort(),
(obj.getId() == Global.standardScale)?
new ImageIcon(getClass().getResource("./br/com/valentin/img/accept.png")): ""
});
});
Related
I am able to set the column's header but not able to set icon in all the rows of first column of JTable.
public class iconRenderer extends DefaultTableCellRenderer{
public Component getTableCellRendererComponent(JTable table,Object obj,boolean isSelected,boolean hasFocus,int row,int column){
imageicon i=(imageicon)obj;
if(obj==i)
setIcon(i.imageIcon);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(JLabel.CENTER);
return this;
}
}
public class imageicon{
ImageIcon imageIcon;
imageicon(ImageIcon icon){
imageIcon=icon;
}
}
and below lines in my BuildTable() method.
public void SetIcon(JTable table, int col_index, ImageIcon icon){
table.getTableHeader().getColumnModel().getColumn(col_index).setHeaderRenderer(new iconRenderer());
table.getColumnModel().getColumn(col_index).setHeaderValue(new imageicon(icon));
}
How can we set it for all rows of first columns? I have tried with for loop but didnt get yet for rows to iterate to set icon. Or is there any other way?
There is no need to create a custom render. JTable already supports an Icon renderer. YOu just need to tell the table to use this renderer. This is done by overriding the getColumnClass(...) method of the table model:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableIcon extends JPanel
{
public TableIcon()
{
Icon aboutIcon = new ImageIcon("about16.gif");
Icon addIcon = new ImageIcon("add16.gif");
Icon copyIcon = new ImageIcon("copy16.gif");
String[] columnNames = {"Picture", "Description"};
Object[][] data =
{
{aboutIcon, "About"},
{addIcon, "Add"},
{copyIcon, "Copy"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
switch (column)
{
case 0: return Icon.class;
default: return super.getColumnClass(column);
}
}
};
JTable table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Table Icon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableIcon());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
You are just using iconRenderer for the render of your header. Also set the Column's Cell Reneder to be an instance of iconRenderer as well. Call setCellRenderer on the column.
http://download.oracle.com/javase/6/docs/api/javax/swing/table/TableColumn.html#setCellRenderer(javax.swing.table.TableCellRenderer)
Side note: Java coding standards specify that class names should start with capital letters, so iconRenderer should be IconRenderer instead.
I know the post is a little old but it's never too late ...
I will post here how to insert an icon without using a DefaultTableCellRenderer class, I use this for when I will only show an icon on the screen in a simple way not very elaborate.
I do it in a simple way ... I always create some tablemodel creators in the classes that I inherit. I usually pass by parameter the list of titles and types of objects.
Method that creates the tablemodel in the upper class:
protected void createTableModel(String[] columns, Class[] types){
String[] vetStr = new String[columns.length];
boolean[] vetBoo = new boolean[columns.length];
Arrays.fill(vetStr, null);
Arrays.fill(vetBoo, false);
table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] { vetStr },
columns
) {
boolean[] canEdit = vetBoo;
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
table.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
}
Inherited class constructor:
"See that here I set the type as ImageIcon.class for the column"
.... constructor....
super("Balança");
String[] columns = {"#", "Nome", "Porta", "Padrão"};
Class[] types = {Long.class, String.class, String.class, ImageIcon.class};
**strong text**super.createTableModel(columns, types);
When I list the items on the tablemodel there I show the image.
list.forEach( obj -> {
tableModel.addRow(new Object[]{
obj.getId(),
obj.getName(),
obj.getPort(),
(obj.getId() == Global.standardScale)?
new ImageIcon(getClass().getResource("./br/com/valentin/img/accept.png")): ""
});
});
So I am creating a project which has three columns; one is a check box column the second one is string (words form a neo4j database) and the third for progress bars.
All the columns are displayed and work fine but the progress bar column is invisible as it seems. Here is some code:
//CONSTRUCTOR
public BiogramTableJSedit2Jan9()
{
//*************************************************
//* SETTING UP THE FORM *
//*************************************************
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(200,200,800,300);
setTitle("Netword Data Table");
getContentPane().setLayout(null);
//*************************************************
//********************************************
//CREATING TABLE BLOCK *
//********************************************
//ADD SCROLLPANE
JScrollPane scroll=new JScrollPane();
scroll.setBounds(70,80,600,200);
getContentPane().add(scroll);
//THE TABLE
final JTable table=new JTable();
scroll.setViewportView(table);
//THE MODEL OF THE TABLE
DefaultTableModel model=new DefaultTableModel()
{
//****************************************
//* SETTING TABLE COLUMNS BLOCK *
//****************************************
public Class<?> getColumnClass(int column)
{
switch(column)
{
case 0: // |This is the first column
return Boolean.class; // |First column is set to Boolean as it will contain check boxes
case 1: // |This is the second column
return String.class; // |Second column set to String as it will contain strings
case 2:
return JProgressBar.class; // |This is for the progress bar column (IN PROGRESS - NOT DISPLAYED YET...)
default:
return String.class; // |The table is set to String as default
}
}
};
//Create and run the query in the table
neoQuery= Q1();
resultVariable = session.run(neoQuery.get());
//ASSIGN THE MODEL TO TABLE
table.setModel(model);
model.addColumn("Select"); // |Column for check boxes
model.addColumn("Bigrams"); // |Column for Bigrams
table.getColumn("Status").setCellRenderer(new ProgressCellRender());
//**********************************************
ProgressWorker worker = new ProgressWorker(model); //HAVE AN ERROR HERE
worker.execute();
This is the progress renderer class:
//a table cell renderer that displays a JProgressBar
public class ProgressCellRender extends JProgressBar implements TableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
int progress = 0;
if (value instanceof Float) {
progress = Math.round(((Float) value) * 100f);
} else if (value instanceof Integer) {
progress = (int) value;
}
setValue(progress);
return this;
}
}
Now you can see that I am using getColumn in order to display this column but when I run it you can see the first and second but not the progress bar column. I want it to look similar to this:
I also has a progress worker class that is not fully implemented.
private static class ProgressWorker extends SwingWorker<Void, Integer>
{ //Swing worker class for updating the progress bar
private BiogramTableJSedit2Jan9 model;
private final JProgressBar progress; //declaration for progress bar
public ProgressWorker(JProgressBar model)
{
this.progress = model;
}
#Override
protected Void doInBackground() throws Exception {
return null;
}
I would appreciate if anyone can explain to me why the thirst column is not being displayed. Thanks for any replies in advance.
Because your posted code was not self-contained I set up a minimal test together
with your already posted ProgressCellRender class.
The important bugfix is in method getColumnClass of the DefaultTableModel.
It needs to return Integer.class or Float.class because only those can be
handled by your ProgressCellRender.
And of course, the actual data in that column need to be Integer or Float.
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::initGUI);
}
private static void initGUI() {
JFrame frame = new JFrame("TableModel JProgressBar Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scroll = new JScrollPane();
frame.getContentPane().add(scroll);
final JTable table = new JTable();
scroll.setViewportView(table);
DefaultTableModel model = new DefaultTableModel() {
public Class<?> getColumnClass(int column) {
switch (column) {
case 0:
return Boolean.class;
case 1:
return String.class;
case 2:
return Integer.class; // !!!!
default:
return String.class;
}
}
};
table.setModel(model);
model.addColumn("Active");
model.addColumn("Name");
model.addColumn("Progress");
table.getColumn("Progress").setCellRenderer(new ProgressCellRender());
model.addRow(new Object[] { true, "aaaa", 14 });
model.addRow(new Object[] { false, "bbbbbbbb", 0 });
model.addRow(new Object[] { true, "ccccc", 2 });
frame.pack();
frame.setVisible(true);
}
}
Then the JProgressBars are rendered correctly in the table:
In your ProgessCellRender you may want to add setStringPainted(true); to get the percentage also rendered as text.
How can I put a JCheckbox or a JButton on a specific row and column of a JTable?
Not sure about a button, but here is a working example to put a checkbox:
import javax.swing.*;
import javax.swing.table.*;
public class Test {
public static void main(String [] args) throws Exception {
DefaultTableModel model = new DefaultTableModel(null, new String [] {"CheckMe", "Value"}) {
public Class getColumnClass(int c) {
switch (c) {
case 0: return Boolean.class;
default: return String.class;
}
} };
JTable table = new JTable(model);
JFrame frame = new JFrame("CheckBox Test");
frame.add(table);
model.addRow(new Object [] {true, "This is true"});
model.addRow(new Object [] {false, "This is false"});
frame.pack(); frame.validate();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
As you can tell from khachik's answer support for a check box is provided by a table based on the column class of the column.
However, if you only want a check box on a specific row of a specific column then you need to override the getCellRenderer(...) and getCellEditor(...) methods to return the renderer/editor for the given cell. Something like:
public TableCellEditor getCellEditor(int row, int column)
{
int modelColumn = convertColumnIndexToModel( column );
if (modelColumn == 1 && row < 3)
return getDefaultEditor(Boolean.class);
else
return super.getCellEditor(row, column);
}
For that, you'll have to write a TableCellRenderer and a TableCellEditor.
You can derive from default swing implementations to make it easier.
In each class, you'll have to override the one method of these interfaces, and in it, check the passed row and column arguments; if both row and column match your criteria, then return a JCheckBox or a JButton, otherwise return the JComponent returned by the super implementation (when using default swing implementations of these interfaces).
Can someone point me in the right direction on how to add an image into Java Table cell.
JTable already provides a default renderer for icons. You just need to tell the table what data is stored in a given column so it can choose the appropriate renderer. This is done by overriding the getColumnClass(...) method:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableIcon extends JPanel
{
public TableIcon()
{
Icon aboutIcon = new ImageIcon("about16.gif");
Icon addIcon = new ImageIcon("add16.gif");
Icon copyIcon = new ImageIcon("copy16.gif");
String[] columnNames = {"Picture", "Description"};
Object[][] data =
{
{aboutIcon, "About"},
{addIcon, "Add"},
{copyIcon, "Copy"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
};
JTable table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Table Icon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableIcon());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Either create the imageicon up front:
ImageIcon icon = new ImageIcon("image.gif");
table.setValueAt(icon, row, column);
Or you can try overriding the renderer for your icon field:
static class IconRenderer extends DefaultTableCellRenderer {
public IconRenderer() { super(); }
public void setValue(Object value) {
if (value == null) {
setText("");
}
else
{
setIcon(value);
}
}
1- add label to jtable ( create class for this)
class LabelRendar implements TableCellRenderer{
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return (Component)value;
}
}
2- code jButton to add image
DefaultTableModel m = (DefaultTableModel) jTable1.getModel();
jTable1.getColumn("image").setCellRenderer(new LabelRendar()); // call class
JLabel lebl=new JLabel("hello");
lebl.setIcon(new javax.swing.ImageIcon(getClass().getResource("/main/bslogo120.png"))); // NOI18N
m.addRow(new Object[]{"", "","",lebl});
I created my own class that implements TableCellRenderer. I can extend this class from JLabel, but I have preferred to keep it independent and used JLabel 'label' as a class component.
public class GLabel implements TableCellRenderer{
//The JLabel that is used to display image
private final JLabel label = new JLabel();
/**
*
* #param text
* #param image
*/
public GLabel(String text, ImageIcon image) {
label.setText(text);
label.setIcon(image);
}
public GLabel(){}
public JLabel getLabel() {
return label;
}
/**
*
* #param table the JTable that is asking the renderer to draw; can be null
* #param value the value of the cell to be rendered.
* It is up to the specific renderer to interpret and draw the value.
* For example, if value is the string "true", it could be rendered as a string or it could be rendered as a check box that is checked.
* null is a valid value
* #param isSelected true if the cell is to be rendered with the selection highlighted; otherwise false
* #param hasFocus if true, render cell appropriately. For example, put a special border on the cell, if the cell can be edited, render in the color used to indicate editing
* #param row the row index of the cell being drawn. When drawing the header, the value of row is -1
* #param column the column index of the cell being drawn
* #return
*/
#Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
GLabel gLabel = (GLabel)value;
return (Component) gLabel.getLabel();
}
}
I created a new DefaultTableModel object. I overrides getColumnClass() method to pass appropriate Class at runtime.
private final DefaultTableModel tblmodel = new DefaultTableModel() {
/**
* This method is called by table cell renderer.
* The method returns class of the cell data. This helps the renderer to display icons and
* other graphics in the table.
*/
#Override
public Class getColumnClass(int column)
{
for(int i = 0; i < tblmodel.getRowCount(); i++)
{
//The first valid value of a cell of given column is retrieved.
if(getValueAt(i,column) != null)
{
return getValueAt(i, column).getClass();
}
}
//if no valid value is found, default renderer is returned.
return super.getColumnClass(column);
}
};
I created JTable object using DefaultTableModel I created.
JTable jtable = new JTable(tblmodel);
I set default renderer for GLabel class
jtable.setDefaultRenderer(GLabel.class, new GLabel());
I created new GLabel object.
GLabel glabel = new GLabel("testing", new ImageIcon("c://imagepath"));
Finally, I used addRow(Object[] rowData) method of TableModel to add GLabel to the JTable.
How to make a JTable non-editable? I don't want my users to be able to edit the values in cells by double-clicking them.
You can override the method isCellEditable and implement as you want
for example:
//instance table model
DefaultTableModel tableModel = new DefaultTableModel() {
#Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
table.setModel(tableModel);
or
//instance table model
DefaultTableModel tableModel = new DefaultTableModel() {
#Override
public boolean isCellEditable(int row, int column) {
//Only the third column
return column == 3;
}
};
table.setModel(tableModel);
Note for if your JTable disappears
If your JTable is disappearing when you use this it is most likely because you need to use the DefaultTableModel(Object[][] data, Object[] columnNames) constructor instead.
//instance table model
DefaultTableModel tableModel = new DefaultTableModel(data, columnNames) {
#Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
table.setModel(tableModel);
table.setDefaultEditor(Object.class, null);
just add
table.setEnabled(false);
it works fine for me.
You can use a TableModel.
Define a class like this:
public class MyModel extends AbstractTableModel{
//not necessary
}
actually isCellEditable() is false by default so you may omit it. (see: http://docs.oracle.com/javase/6/docs/api/javax/swing/table/AbstractTableModel.html)
Then use the setModel() method of your JTable.
JTable myTable = new JTable();
myTable.setModel(new MyModel());
If you are creating the TableModel automatically from a set of values (with "new JTable(Vector, Vector)"), perhaps it is easier to remove editors from columns:
JTable table = new JTable(my_rows, my_header);
for (int c = 0; c < table.getColumnCount(); c++)
{
Class<?> col_class = table.getColumnClass(c);
table.setDefaultEditor(col_class, null); // remove editor
}
Without editors, data will be not editable.
I used this and it worked : it is very simple and works fine.
JTable myTable = new JTable();
myTable.setEnabled(false);
create new DefaultCellEditor class :
public static class Editor_name extends DefaultCellEditor {
public Editor_name(JCheckBox checkBox) {
super(checkBox);
}
#Override
public boolean isCellEditable(EventObject anEvent) {
return false;
}
}
and use setCellEditor :
JTable table = new JTable();
table.getColumn("columnName").setCellEditor(new Editor_name(new JCheckBox()));