繁体   English   中英

JTable单元格中的JComboBox。 选择更改会影响其他行中的JComboBox

[英]JComboBox in JTable cell. Selection change affects JComboBox in other rows

我已经在这里潜伏了大约两年了,从来没有问过任何问题,因为我总是在别人的问题中找到答案。 谢谢!

我想潜伏已经结束了。 我在这里看到了类似的问题,但不完全是这种情况:我有一个两列的JTable,第一列有一个JComboBox,第二列有一个整数。 JComboBox设置了ItemListener,以便在更改JComboBox中的选择时,将Integer列中的值设置为comboBox所选索引。 右键单击该表将使用addRow()作为MouseEvent渲染JPopupMenu。

只要我在设置DefaultTableModel时添加所有想要的行,它就可以正常工作。 但是,如果我仅以一行开始模型,并使用MouseEvent(或在DefaultTableModel的参数中添加行而不是添加行的任何其他方法)添加行,则当我们开始更改组合框中的选择时,它将更改其他行中的整数值。

例如:如果我运行该程序并立即通过MouseEvent添加另外两行,则从第0行的组合中选择零,从第1行的组合中选择1,从第2行的组合中选择2。我回到第0行,并且一旦激活组合框(我还没有选择项目...),它就会将第2行中的整数更改为0。有人可以告诉我如何停止在此更改整数方式? 这是一个试用代码:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class JComboBoxInJTable {

    public static void main(String[] args) {
        new JComboBoxInJTable();
    }

    public JComboBoxInJTable() {
        EventQueue.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }

            DefaultTableModel model = new DefaultTableModel(new Object[]{"ComboBox", "Index"}, 1);
            JTable table = new JTable(model);

            //popup menu to add row
            JPopupMenu popup = new JPopupMenu();
            JMenuItem newRow;
            newRow = new JMenuItem("New Row");
            newRow.setToolTipText("Add new row.");
            newRow.addActionListener((ActionEvent nr) -> {
                model.addRow(new Object[]{"", ""});
            });
            popup.add(newRow);

            //set up right-click to open popup menu
            table.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent rc) {
                    if (SwingUtilities.isRightMouseButton(rc)) {
                        if (table.getSelectedRow() >= 0) {
                            popup.show(table, rc.getX(), rc.getY());
                        }
                    }
                }
            });

            JComboBox combo = new JComboBox(new Object[]{"Zero", "One", "Two", "Three"});
            combo.addItemListener((ItemEvent e) -> {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    //sets value of cell to left of combobox to comboboxe's selected index
                    table.setValueAt(combo.getSelectedIndex(), table.getSelectedRow(), 1);
                } else {
                    //do nothing...
                }
            });

            DefaultCellEditor comboEditor = new DefaultCellEditor(combo);

            TableColumnModel tcm = table.getColumnModel();
            tcm.getColumn(0).setCellEditor(comboEditor);

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new JScrollPane(table));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

像往常一样,我确信这是我所缺少的简单东西。 再次感谢您过去和将来的帮助!

  • 不要使用MouseListener来显示弹出菜单,不同的OS会对弹出窗口有不同的触发,并且并非所有触发都由mousePressed触发。 而是使用JComponent#setComponentPopupMenu并让API处理它
  • 不要从编辑器修改模型的状态。 像现在一样,这可能会使模型进入无效状态并引起其他副作用。 似乎正在发生的事情是,当选择了新行时,使用行单元格值更新了编辑器,但是尚未设置行选择,因此表仍认为仍在选择上一行。 相反,使用模型的setValueAt方法可以决定更改第一列的值后该怎么做。

例如...

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class JComboBoxInJTable {

    public static void main(String[] args) {
        new JComboBoxInJTable();
    }

    private List<String> comboData;

    public JComboBoxInJTable() {
        EventQueue.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }

            DefaultTableModel model = new DefaultTableModel(new Object[]{"ComboBox", "Index"}, 1) {

                @Override
                public void setValueAt(Object aValue, int row, int column) {
                    super.setValueAt(aValue, row, column);
                    if (column == 0) {
                        String value = aValue == null ? null : aValue.toString();
                        if (aValue == null) {
                            super.setValueAt(null, row, 1);
                        } else {
                            super.setValueAt(comboData.indexOf(aValue), row, 1);
                        }
                    }
                }

            };
            JTable table = new JTable(model);
            table.setFillsViewportHeight(true);
            table.setGridColor(Color.GRAY);

            //popup menu to add row
            JPopupMenu popup = new JPopupMenu();
            JMenuItem newRow;
            newRow = new JMenuItem("New Row");
            newRow.setToolTipText("Add new row.");
            newRow.addActionListener((ActionEvent nr) -> {
                model.addRow(new Object[]{"", ""});
            });
            popup.add(newRow);

            table.setComponentPopupMenu(popup);

            comboData = new ArrayList<>(Arrays.asList(new String[]{"Zero", "One", "Two", "Three"}));

            JComboBox combo = new JComboBox(comboData.toArray(new String[comboData.size()]));
//          combo.addItemListener((ItemEvent e) -> {
//              if (e.getStateChange() == ItemEvent.SELECTED) {
//                  //sets value of cell to left of combobox to comboboxe's selected index
//                  System.out.println("Selected row = " + table.getSelectedRow());
//                  table.setValueAt(combo.getSelectedIndex(), table.getSelectedRow(), 1);
//              } else {
//                  //do nothing...
//              }
//          });

            DefaultCellEditor comboEditor = new DefaultCellEditor(combo);

            TableColumnModel tcm = table.getColumnModel();
            tcm.getColumn(0).setCellEditor(comboEditor);

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new JScrollPane(table));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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