简体   繁体   中英

How to update adjacent field according to jComboBox selection in jTable?

I have a scenario where a jComboBox with a selection of colours in a jTable changes another field in the same row of the jTable with the name of the chosen colour.

在此处输入图片说明

When the jComboBox is selected the adjacent field changes accordingly but when I click another jComboBox instead of changing the adjacent field it changes the row that was previously selected.

在此处输入图片说明

This is the code that I have so far:

import javax.swing.DefaultCellEditor;
import javax.swing.table.*;

public class TestJTable extends javax.swing.JFrame {

    public TestJTable() {
        initComponents();

        String[] columnNames = {"Choose Colour", "Colour Chosen"};
        Object[][] data =
        {
            {"Red",    new String("Red Colour")},
            {"Blue",  new String("Blue Colour")},
            {"Green",    new String("Green Colour")},
            {"Yellow", new String("Yellow  Colour")}
        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        jTable.setModel(model);

        jTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(jCBColour));



    }

    /**
     * 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() {

        jCBColour = new javax.swing.JComboBox();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();

        jCBColour.setEditable(true);
        jCBColour.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Red", "Blue", "Green", "Yellow" }));
        jCBColour.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCBColourActionPerformed(evt);
            }
        });

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "Choose Colour", "Colour Chosen"
            }
        ));
        jScrollPane1.setViewportView(jTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(89, 89, 89)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 452, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(113, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(14, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(178, 178, 178))
        );

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

    private void jCBColourActionPerformed(java.awt.event.ActionEvent evt) {                                          

        System.out.println(evt.getActionCommand());
        System.out.println(jCBColour.getSelectedIndex());

        if (jCBColour.getSelectedIndex() != -1) {

        switch (jCBColour.getSelectedIndex()){
           case 0: jTable.setValueAt("Red Colour", jTable.getSelectedRow(), 1);
                    break;
           case 1: jTable.setValueAt("Blue Colour", jTable.getSelectedRow(), 1);
                    break;
           case 2: jTable.setValueAt("Green Colour", jTable.getSelectedRow(), 1);
                    break;
           case 3: jTable.setValueAt("Yellow Colour", jTable.getSelectedRow(), 1);
                    break;
           default:
                   break;
       }
       }

    }                                         

    /**
     * @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(TestJTable.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(TestJTable.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(TestJTable.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(TestJTable.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 TestJTable().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JComboBox jCBColour;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable;
    // End of variables declaration                   
}

Any help will be greatly appreciated :)

I can't duplicate your problem. It works fine for me using JDK8_u45 on Windows 7.

Having said that you should not be attempting to update the model from an ActionListener on the combo box.

Instead you should use a custom TableModel that updates the second column whenever the first column is changed. Something like:

DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
    @Override
    public void setValueAt(Object value, int row, int column)
    {
        super.setValueAt(value, row, column);

        if (column == 0)
        {
            String color = value.toString();

            switch (column)
            {
                case "Red": setValueAt("Red Color", row, 1); break;
                case "Blue": setValueAt("Blue Color", row, 1); break;
                ...
            }

        }
    }
};

This will make sure the data is correct whether the TableModel is update via the JTable or the TableModel directly.

Thanks for pointing me in the right direction. After using the TableModelListener instead of the action performed it finally worked. Here is the working copy of the code:

import java.util.ArrayList;
import javax.swing.DefaultCellEditor;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;

public class TestJTable extends javax.swing.JFrame {

    private TableModelListener tableModelListener;

    public TestJTable() {
        initComponents();

        String[] columnNames = {"Choose Colour", "Colour Chosen"};
        Object[][] data =
        {
            {"Red",    new String("Red Colour")},
            {"Blue",  new String("Blue Colour")},
            {"Green",    new String("Green Colour")},
            {"Yellow", new String("Yellow  Colour")}
        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        jTable.setModel(model);

        jTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(jCBColour));

        setTableModelListener();

    }

 private void setTableModelListener() {
    tableModelListener = new TableModelListener() {

        @Override
        public void tableChanged(TableModelEvent e) {
            if (e.getType() == TableModelEvent.UPDATE) {

                int row = e.getFirstRow();
                int column = e.getColumn();
                if (column == 0) {
                    TableModel model = jTable.getModel();
                    //ArrayList<String> itemRow = itemCodes.get(jTable.getSelectedIndex());
                    //String itemDescription = itemRow.get(1);
                    String colourChosen = "";
                    switch (jCBColour.getSelectedIndex()) {
                        case 0: colourChosen = "Red Colour";break;
                        case 1: colourChosen = "Blue Colour";break;
                        case 2: colourChosen = "Green Colour";break;
                        case 3: colourChosen = "Yellow Colour";break;
                }

                model.setValueAt(colourChosen,row,1);

                }
            }
        }
    };
    jTable.getModel().addTableModelListener(tableModelListener);
    }    

    /**
     * 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() {

        jCBColour = new javax.swing.JComboBox();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();

        jCBColour.setEditable(true);
        jCBColour.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Red", "Blue", "Green", "Yellow" }));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "Choose Colour", "Colour Chosen"
            }
        ));
        jScrollPane1.setViewportView(jTable);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(89, 89, 89)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 452, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(113, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(14, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(178, 178, 178))
        );

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

    /**
     * @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(TestJTable.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(TestJTable.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(TestJTable.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(TestJTable.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 TestJTable().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JComboBox jCBColour;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable;
    // End of variables declaration                   
}

changing the jCBColourActionPerformed method to following should also help solving the problem.

    private void jCBColourActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            if (jCBColour.getSelectedIndex() != -1) {
                jTable.setValueAt(jCBColour.getItemAt(jCBColour.getSelectedIndex()), jTable.getSelectedRow(), 1);
                jTable.repaint();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM