58208

Setting jCheckBox invisible in jTable

Question:

I have a jTable with two columns.First column is set as Boolean(for checkbox) and second column has String value.As I am using Netbeans,checkbox got added into all rows of first column. I tried to add it only for those rows which have value in the second column. I used the code for trying that,

private class CustomCellRenderer extends DefaultTableCellRenderer { /* (non-Javadoc) * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) */ @Override public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) { Component rendererComp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row, column); for(int i=row;i<jTable1.getRowCount();i++){ if(jTable1.getValueAt(i, 1)==null){ jTable1.setValueAt(true, i, 0); //checkbox.setOpaque(false); } } return this ; } }

If I try to set value 'true' for all other checkbox in the above for loop it's working well. How can I set it invisible for rest of the rows.

<strong>EDIT:</strong>

I am adding my code in this

package e2; import java.awt.Component; import javax.swing.JCheckBox; import javax.swing.JTable; import javax.swing.table.TableCellRenderer; public class JTable_CheckBox extends javax.swing.JFrame { /** Creates new form JTable_CheckBox */ JCheckBox checkbox=new JCheckBox(); public JTable_CheckBox() { initComponents(); jTable1.setValueAt("John",0,1); jTable1.setValueAt("James",1,1); jTable1.setValueAt("Janet",2,1); jTable1.setValueAt("Tom",3,1); jTable1.getColumnModel().getColumn(0).setCellRenderer(new CheckboxCellRenderer()); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new JTable_CheckBox().setVisible(true); } }); } public class CheckboxCellRenderer extends JCheckBox implements TableCellRenderer { public CheckboxCellRenderer() { setOpaque(false); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { //here i am trying to set check box invisible,but here i am setting as selected for(int i=row;i<table.getRowCount();i++){ if(table.getValueAt(i, 1)==null){ table.setValueAt(true, i, 0); //checkbox.setOpaque(false); } } return this; } } // Variables declaration - do not modify private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable jTable1; // End of variables declaration }

Answer1:

TableCellRenderer are used in tables to paint the various cells of the table reusing the same component. The table automatically sets up the proper context, component bounds and invokes the getTableCellRendererComponent for each cell of the table that needs to be painted (the first time the table is displayed all visible cells are painted and then after, upon TableModel notification, the appropriate cells are repainted).

So in your TableCellRenderer you certainly do not need to iterate over the cells of the table trying to set values. This just does not make sense. Remember you are implementing the interface TableCellRender which has a contract you need to respect.

From the Javadoc:

<blockquote>

Returns the component used for drawing the cell. This method is used to configure the renderer appropriately before drawing.

</blockquote>

So all you need to do is return a component representing the value parameter properly. Possibly, you can modify the component to indicate that the cell has the focus or not, and wheter it is currently selected or not. Nothing more, nothing less.

Now, coming to your question: if you want to display a checkbox only for rows that have a value implement a TableCellRenderer returning a checkbox and modify its visibility according to the value in column 1 (second column).

This example is working:

import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.List; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; public class TestTable { public class CheckboxCellRenderer extends JPanel implements TableCellRenderer { private JCheckBox checkBox; public CheckboxCellRenderer() { super(new FlowLayout(FlowLayout.CENTER, 0, 0)); setOpaque(false); checkBox = new JCheckBox(); checkBox.setOpaque(false); checkBox.setHorizontalAlignment(JCheckBox.CENTER); add(checkBox); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Object valueInColumn1 = table.getValueAt(row, 1); checkBox.setVisible(valueInColumn1 != null); checkBox.setSelected(value instanceof Boolean && (Boolean) value); return this; } } private JFrame f; private JTable table; private class MyObject { private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); private String value; private boolean selected; public MyObject(String value) { this.value = value; } public PropertyChangeSupport getPropertyChangeSupport() { return propertyChangeSupport; } public String getValue() { return value; } public void setValue(String value) { this.value = value; propertyChangeSupport.firePropertyChange("value", null, value); } public boolean isSelected() { return selected; } public void setSelected(boolean selected) { if (this.selected != selected) { this.selected = selected; propertyChangeSupport.firePropertyChange("selected", !selected, selected); } } } protected void initUI() { List<MyObject> objects = new ArrayList<TestTable.MyObject>(); for (int i = 0; i < 200; i++) { MyObject object = new MyObject(i % 3 == 1 ? null : "Row " + (i + 1)); objects.add(object); } table = new JTable(new MyTableModel(objects)); table.setRowHeight(20); table.getColumnModel().getColumn(0).setCellRenderer(new CheckboxCellRenderer()); f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new JScrollPane(table), BorderLayout.CENTER); f.pack(); f.setVisible(true); } public class MyTableModel extends AbstractTableModel implements PropertyChangeListener { private List<MyObject> objects; public MyTableModel(List<MyObject> objects) { super(); this.objects = objects; for (MyObject object : objects) { object.getPropertyChangeSupport().addPropertyChangeListener(this); } } @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getSource() instanceof MyObject) { int index = objects.indexOf(evt.getSource()); fireTableRowsUpdated(index, index); } } @Override public int getColumnCount() { return 2; } @Override public int getRowCount() { return objects.size(); } public MyObject getValueAt(int row) { return objects.get(row); } @Override public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return getValueAt(rowIndex).isSelected(); case 1: return getValueAt(rowIndex).getValue(); } return null; } @Override public void setValueAt(Object value, int rowIndex, int columnIndex) { if (columnIndex == 0) { getValueAt(rowIndex).setSelected(Boolean.TRUE.equals(value)); } } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex == 0 && getValueAt(rowIndex).getValue() != null; } @Override public Class<?> getColumnClass(int column) { switch (column) { case 0: return Boolean.class; case 1: return String.class; } return Object.class; } @Override public String getColumnName(int column) { switch (column) { case 0: return "Selected"; case 1: return "Value"; } return null; } } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TestTable().initUI(); } }); } }

PS: I did not take isSelected/hasFocus into account, if you want we can come to that later.

Answer2:

First, you <em>must</em> understand the renderer/editor mechanism. To achieve that, read f.i. the corresponding chapter in the online tutorial referenced in the <a href="https://stackoverflow.com/tags/swing/info" rel="nofollow">Swing tag description</a>.

Second, for best visual appearance, implement a custom renderer by re-using the defaults installed by the JTable itself, something like:

public class CompoundRenderer implements TableCellRenderer { TableCellRenderer booleanRenderer; TableCellRenderer defaultRenderer; public CompoundRenderer(TableCellRenderer booleanRenderer, TableCellRenderer defaultRenderer) { this.booleanRenderer = booleanRenderer; this.defaultRenderer = defaultRenderer; } @Override public Component getTableCellRendererComponent(..., Object value, ....) { if (value instanceof Boolean) { return booleanRenderer.getTableCellRendererComponent(...); } return defaultRenderer.getTableCellRendererComponent(...); } } // usage JTable myTable ... TableCellRenderer compound = new CompoundRenderer( myTable.getDefaultRenderer(Boolean.class), myTable.getDefaultRenderer(Object.class)); // either register for all booleans myTable.setDefaultRenderer(Boolean.class, compound); // or register for a particular column myTable.getColumnModel().getColumn(someIndex).setCellRenderer(compound);

Answer3:

As the saying goes: many ways lead to Rome.

I just had a similar problem, namely I have a table with a column containing checkboxes, and I want to hide the checkbox in the first row. After evaluating the other solutions I come up with something slightly different (adapted for the original question):

Create a specific CheckBoxRenderer class:

public class CheckBoxRenderer extends JCheckBox implements TableCellRenderer { CheckBoxRenderer() { setHorizontalAlignment(JLabel.CENTER); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Object valueInColumn1 = table.getValueAt(row, 1); if (valueInColumn1 == null) { JLabel x=new JLabel(); return x; } setSelected((value != null && ((Boolean) value).booleanValue())); return this; } }

Step number 2: attach the renderer to te column:

paramTable.getColumnModel().getColumn(3).setCellRenderer(new CheckBoxRenderer());

That's it.

Answer4:

I know this is an old thread, but I had a similar need and found sers answer quite helpful. One addition I found that I needed to include was to create a CheckBoxEditor. Otherwise, when I clicked on the cell, I saw the checkbox appear momentarily. So I added something like this:

public class CheckBoxEditor extends DefaultCellEditor { private JCheckBox checkBox = new JCheckBox(); CheckBoxEditor() { super( checkBox ); } @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column ) { if ( row != 1 ) { return super.getTableCellEditorComponent( table, value, isSelected, row, column ); } else { return null; } } }

Then you'd do something like:

paramTable.getColumnModel().getColumn(3).setCellEditor( new CheckBoxEditor() );

Worked for me, anyway.

Another note is that if your cells have a background color, you can extend sers answer by adding the lines:

x.setOpaque( true ); x.setBackground( MYCOLOR );

Setting the JLabel to opaque is the key, as can be found in other Stack Exchange answers on similar topics.

Recommend

  • How to support multicast network in Docker
  • Setting numpoints in matplotlib legend does not work
  • MultiDexApplication not recognized
  • What size buffer should be used for reading from a UDP socket?
  • Text comparison algorithm or program?
  • I want to toggle the table rows filter based on the text from buttons
  • Partial search on Encrypted field
  • python base64 encode to string
  • How to get superfish sub menus top-aligned?
  • Append list in a loop [duplicate]
  • How to generate a SHA256 hash of 32 bytes using nodejs (crypto) in order to avoid bad key size error
  • System.IO.IOException: Too many open files
  • How to enrich a TraversableOnce with my own generic map?
  • Caching of Google Cloud Endpoints?
  • Stop the background service after particular time in android
  • Sending in an object of type Object instead of String - Polymorphism
  • JQuery and PHP validation problem?
  • Was default_marker removed from mapbox-gl.js
  • How to create 2 svg's on one page?
  • WooCommerce get order quantity in thank you page and redirect
  • Hibernate Idempotent Update
  • CSS style for container with transparent border images
  • Is there a .NET method equivalent to NETWORKDAYS in Excel?
  • How to sort by Lucene.Net field and ignore common stop words such as 'a' and 'the
  • Can't hide status bar in AVPlayerViewController's portrait mode
  • Yii Bootstrap not loading JS files
  • Issue with Terrain Collision using Three.js
  • JQuery Mobile Ajax Navigation in Single-Page Template
  • AWS RDS Parameter Group not changing MySQL encoding
  • .Net core Hosted Services guaranteed to complete
  • Java Collections.shuffle() weird behaviour [closed]
  • All Event listing on specified date in Google Calender api (V3) in java?
  • Excel VBA : conditional formatting of sheet1 cells from sheet2 values in excel 2007
  • Why does Rails 3 think xE2x80x89 means â x80 x89
  • Access to a Matlab gui from the web