簡體   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