如何根据jTable中的jComboBox选择更新相邻字段?

时间:2015-10-10 11:38:33

标签: java jtable jcombobox

我有一个场景,其中jTable中具有颜色选择的jComboBox会使用所选颜色的名称更改jTable的同一行中的另一个字段。

enter image description here

当选择jComboBox时,相邻字段会相应更改,但是当我单击另一个jComboBox而不是更改相邻字段时,它会更改先前选择的行。

enter image description here

这是我到目前为止的代码:

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                   
}

任何帮助将不胜感激:)

3 个答案:

答案 0 :(得分:1)

我无法复制您的问题。它适用于我在Windows 7上使用JDK8_u45。

说过你不应该尝试从组合框上的ActionListener更新模型。

相反,您应该使用自定义TableModel,只要更改第一列,就会更新第二列。类似的东西:

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;
                ...
            }

        }
    }
};

这将确保数据是否正确无论TableModel是通过JTable还是TableModel直接更新。

答案 1 :(得分:0)

感谢您指点我正确的方向。使用TableModelListener而不是执行的操作后,它终于工作了。以下是代码的工作副本:

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                   
}

答案 2 :(得分:0)

jCBColourActionPerformed方法更改为以下方法也有助于解决问题。

    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();
        }
    }