2 Replies Latest reply: May 14, 2012 8:44 AM by Nitin Khare RSS

    setBackground() in JButton in JTable

    809490
      Hello

      I have a JTable which has a column with JButtons. After pressing a Button in the JTable i want to change the color of the Button, but it does not seem to work.

      I made an example with a JTable where the values of the cells are all initialized with "0". When one of the buttons gets pressed the value of the cell with the pressed button gets increased to "1" and so on...
      After this the Renderer should paint the buttons blue which have a value > 0, but the changes made to the DefaultTableModel in actionPerformed() with model.getValueAt() does not affect the value parameter of the getTableCellRendererComponent() method in the TableCellRenderer.
      Here is the example:
      import java.awt.BorderLayout;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      
      import javax.swing.JCheckBox;
      import javax.swing.JFrame;
      import javax.swing.JScrollPane;
      import javax.swing.JTable;
      import javax.swing.UIManager;
      import javax.swing.table.DefaultTableModel;
      import javax.swing.table.TableColumn;
      import javax.swing.table.TableColumnModel;
      
      public class TestTable implements ActionListener
      {
           private JTable table;
           
           TestTable()
           {
                String[] header = new String[5];
                String[][] vals = new String[header.length][];
                for(int i = 0; i < header.length; i++)
                {
                     header[i] = String.valueOf(i);
                     vals[i] = new String[5];
                     for(int j = 0; j < vals.length; j++)
                          vals[i][j] = String.valueOf(0);
                }
                DefaultTableModel model = new DefaultTableModel(vals, header);
                table = new JTable( model );
                TableColumnModel cmodel = table.getColumnModel();
                TableColumn butCol = cmodel.getColumn(0);
                butCol.setCellRenderer(new ButtonRenderer());
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table), BorderLayout.CENTER);
                ButtonEditor buttonEditor = new ButtonEditor( new JCheckBox() );
                buttonEditor.getButton().addActionListener( this );
                butCol.setCellEditor( buttonEditor );
                frame.pack();
                frame.setVisible(true);
           }
           
           public static void main(String[] args)
           {
                try
           {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
           }
           catch(Exception e) {
           System.out.println("Error setting Motif LAF: " + e);
           }
                javax.swing.SwingUtilities.invokeLater(new Runnable()
                {
      public void run() {
           
      createAndShowGUI();
      }
      });
           }
           
           private static void createAndShowGUI()
           {
                new TestTable();
           }
           
           @Override
           public void actionPerformed(ActionEvent e)
           {     
                DefaultTableModel model = ((DefaultTableModel) table.getModel());
                int row = table.getSelectedRow();
                if( model.getValueAt(row, 0) instanceof String )
                {
                     String number = (String) model.getValueAt(row, 0);
                     int newval = Integer.parseInt( number );
                     System.out.println("actionPerformed old " + newval);
                     newval++;
                     System.out.println("actionPerformed new " + newval);
                     model.setValueAt(String.valueOf(newval), row, 0);
                     model.fireTableCellUpdated(row, 0);
                }
           }
           
           public JTable getTable() {
                return table;
           }
      }

      import java.awt.Component;

      import javax.swing.DefaultCellEditor;
      import javax.swing.JButton;
      import javax.swing.JCheckBox;
      import javax.swing.JTable;


      public class ButtonEditor extends DefaultCellEditor
      {
           /**
           *
           */
           private static final long serialVersionUID = 1L;
           protected JButton button;
           
           ButtonEditor(JCheckBox checkBox)
           {
                super( checkBox );
                button = new JButton();
                button.setOpaque(true);
           }
           
           public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
           {
                return button;
           }

           public JButton getButton() {
                return button;
           }
      }

      import java.awt.Color;
      import java.awt.Component;

      import javax.swing.JButton;
      import javax.swing.JTable;
      import javax.swing.UIManager;
      import javax.swing.table.TableCellRenderer;

      public class ButtonRenderer extends JButton implements TableCellRenderer
      {
           /**
           *
           */
           private static final long serialVersionUID = -3643323587417887925L;
           
           public ButtonRenderer()
           {
           setOpaque(true);
           }
           
           public Component getTableCellRendererComponent(JTable table, Object value,
           boolean isSelected, boolean hasFocus, int row, int column)
           {
                System.out.println(row + " ### " + value + " " + (value instanceof String));
                setEnabled(true);
                if(value instanceof String)
                {
                     int val = Integer.parseInt((String) value);
                     if(val == 0)
                          setBackground(UIManager.getColor("Button.background"));
                     else
                          setBackground(Color.blue);
                     setText( String.valueOf(value) );
                }
                return this;
           }
      }


      I cannot find what's wrong here, so I would be happy if someone could help me with this.

      Regards,
      Chang
        • 1. Re: setBackground() in JButton in JTable
          809490
          Ok I just have to resize the frame and the button gets colored, but I need to call the renderer without resizing the whole frame. I thought model.fireTableCellUpdated(row, 0) should do this, but it does not seem so...
          • 2. Re: setBackground() in JButton in JTable
            Nitin Khare
            I think there is an issue with table cell renderer and editor which seems to be getting different button instances. Probably they need to managed in one implementation to better manage the renderer/editor states. You may want to look at the ButtonColumn implementation posted here.

            http://tips4java.wordpress.com/2009/07/12/table-button-column