0

How can I make a cell in a JTable change its background color when text is changed? I would like the color to change for a few seconds and then restore it to its initial background color. This is my code:

package GUI;

import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;


public class NewJFrame extends javax.swing.JFrame {

    private TableModel myTableModel;

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() {
        myTableModel = new MyTableModel();
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        button = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        button.setText("jButton1");
        button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonActionPerformed(evt);
            }
        });

        table.setModel(myTableModel);
        jScrollPane1.setViewportView(table);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(button)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(15, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(26, 26, 26)
                .addComponent(button)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void buttonActionPerformed(java.awt.event.ActionEvent evt) {                                       
        myTableModel.setValueAt(1.40, 0, 2);myTableModel.setValueAt(1.00, 1, 2);
    }                                      

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton button;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable table;
    // End of variables declaration                   

    private static class Rate {

        private String Currency1;

        public void setCurrency1(String Currency1) {
            this.Currency1 = Currency1;
        }

        public void setCurrency2(String Currency2) {
            this.Currency2 = Currency2;
        }

        public void setExchangeRate(Double ExchangeRate) {
            this.ExchangeRate = ExchangeRate;
        }

        public String getCurrency1() {
            return Currency1;
        }

        public String getCurrency2() {
            return Currency2;
        }

        public Double getExchangeRate() {
            return ExchangeRate;
        }
        private String Currency2;
        private Double ExchangeRate;

        public Rate() {

        }

        public Rate(String Currency1, String Currency2, Double ExchangeRate) {
            this.Currency1 = Currency1;
            this.Currency2 = Currency2;
            this.ExchangeRate = ExchangeRate;
        }

    }

    private static class MyTableModel extends AbstractTableModel {

        private final String[] columnNames = {"Currency1", "Currency2", "Exchange Rate"};
        private ArrayList<Rate> ratesList = new ArrayList<Rate>() {
            {
                add(new Rate("EUR", "USD", 1.13));
                add(new Rate("EUR", "GBP", 0.87));
                add(new Rate("EUR", "CHF", 1.09));
                add(new Rate("EUR", "JPY", 113.49));
                add(new Rate("EUR", "MAD", 10.86));
            }
        };

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            // TODO Auto-generated method stub
            Rate rate = ratesList.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    rate.setCurrency1((String) aValue);
                    fireTableCellUpdated(rowIndex, columnIndex);
                    break;
                case 1:
                    rate.setCurrency2((String) aValue);
                    fireTableCellUpdated(rowIndex, columnIndex);
                    break;
                case 2:
                    rate.setExchangeRate((Double) aValue);
                    fireTableCellUpdated(rowIndex, columnIndex);
                    break;
                default:
                    break;
            }
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Rate rate = ratesList.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    return rate.getCurrency1();
                case 1:
                    return rate.getCurrency2();
                case 2:
                    return rate.getExchangeRate();

                default:
                    return null;
            }
        }

        @Override
        public int getRowCount() {
            return ratesList.size();
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045

1 Answers1

1

Your example lacks several essential elements: in outline,

  • In a custom TableCellEditor, let your implementation of stopCellEditing(), seen here, start a javax.swing.Timer having the desired delay.

  • In the same implementation of stopCellEditing(), condition your TableCellRenderer to display the chosen highlight color. The subsequent invocation of setValueAt() should fire a suitable update event automatically.

  • In the timer's ActionListener, stop() the timer and condition your TableCellRenderer to display the default "Table.background" obtained by consulting the UIManager. You may need to update the view, ideally by firing an appropriate event from your TableModel.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • For more detailed guidance, please edit your question to include a [mcve] that shows your revised approach. – trashgod Aug 18 '16 at 01:31