JTable:JComboBox ItemListener在没有更改的情况下触发

时间:2015-07-17 09:25:39

标签: jtable jcombobox itemlistener

我在JTable中添加了一个JComboBox:

table.getColumnModel().getColumn(16).setCellEditor(new  DefaultCellEditor(c = new JComboBox()));
c.addItemListener(new CItemListener());

在(取消)选择项目时会触发监听器。没关系。然而,我的问题是:我已经在一行组合框中选择了“B”,而在另一行中选择了“A”。当我选择组合框+“B”行并现在选择带有“A”的行时,将取消选择项“B”并选择“A”来触发监听器,尽管我没有自己更改选择。这只有在我点击组合框(不改变选择)时才会出现,而不是我选择其他地方的行。

可以改变这种行为吗?如果是这样的话:怎么样?

目标:只有在进行选择时才会触发侦听器,而不是在未更改项目的情况下取消/选择组合框时触发。

监听器:

@Override
public void itemStateChanged(ItemEvent ie) {
    String s = "";

    if (ie.getStateChange() == ItemEvent.SELECTED){
        if (table.getSelectedRow() != -1){
            s = table.getModel().getValueAt(table.convertRowIndexToModel(table.getSelectedRow()), 1) );
            anotherTable.increaseCountFor(s);
            }
        } else if (ie.getStateChange() == ItemEvent.DESELECTED){
            if (table.getSelectedRow() != -1){
                s = table.getModel().getValueAt(table.convertRowIndexToModel(table.getSelectedRow()), 1) );
                anotherTable.decreaseCountFor(s);
            }
        }

1 个答案:

答案 0 :(得分:0)

您当前的方法出现问题

当您正在收听Combobox的itemStateChanged时,即使有一行被更改,也会调用所有行,因为这是预期的行为。[尝试在该侦听器中放置一个print语句来查看] < / p>

没有必要在表格的列更改中听取组合框改变你想听的内容

当您根据组合框值的某些值递增时。我想出了以下解决方案。

有一个mainTable,其中第二列[索引1]是一个下拉列表。 每当mainTable中任何行的组合框值发生变化时,旧值将递减,而新值将在counterTable中递增。

我已经覆盖了DefaultTableModel,因此无论何时调用setValue,它都将检查它是否是我们想要的列,如果是,它将对旧值进行减量并为计数器表中的新值增加

只需运行以下SSCCE代码,然后从第二列中选择值并查看更改

以下是您要求的内容

import java.awt.BorderLayout;
import java.util.Objects;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;


public class TableDropDown extends JFrame {

private JComboBox jComboBox1;
private JTable mainTable = new JTable();
private JTable counterTable = new JTable();

public TableDropDown() {
    initialize();
}

private void initialize() {

    //Loading the mainTable with sample values 
    DefaultTableModel model = new DefaultTableModel(new Object[][]{
        {"Test", null, null},
        {"Type", null, null},
        {"What", null, null},
        {"Which", null, null}
    },
            new String[]{
                "Title 1", "Title 2", "Title 3"
            }) {
                @Override
                //Main part that does the trick
                public void setValueAt(Object newValue, int row, int column) {
                    //check if this is our column
                    if (column == 1) {
                        Object oldvalue = getValueAt(row, column);
                        if (!Objects.equals(newValue, oldvalue)) {
                            if (oldvalue != null) {
                                decreaseCountFor(oldvalue.toString());
                            }
                            increaseCountFor(newValue.toString());
                        }
                    }
                    super.setValueAt(newValue, row, column);
                }
            };

    mainTable.setModel(model);

    //loading counterTable and combobox sample values A to J
    String[] contents = new String[10];
    DefaultTableModel cModel = new DefaultTableModel(null,
            new String[]{"Type", "Count"});
    for (int i = 0; i < 10; i++) {
        contents[i] = "" + (char) (i + 65);
        cModel.addRow(new Object[]{contents[i], 0});
    }
    counterTable.setModel(cModel);
    counterTable.setEnabled(false);//to disable editing

    jComboBox1 = new JComboBox(new DefaultComboBoxModel(contents));

    //setting cellEditor for Column 1
    mainTable.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(jComboBox1));

    //stuffs to add value to frame
    add(new javax.swing.JScrollPane(mainTable), BorderLayout.CENTER);
    add(new javax.swing.JScrollPane(counterTable), BorderLayout.EAST);
    pack();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public int getRowForValue(String val) {
    for (int i = 0; i < counterTable.getRowCount(); i++) {
        if (counterTable.getValueAt(i, 0).equals(val)) {
            return i;
        }
    }
    return -1;
}

public int getPrevoiusValue(int row) {
    return Integer.parseInt(counterTable.getValueAt(row, 1).toString());
}

public void increaseCountFor(String x) {
    int row = getRowForValue(x);
    counterTable.setValueAt(getPrevoiusValue(row) + 1, row, 1);
}

public void decreaseCountFor(String x) {
    int row = getRowForValue(x);
    counterTable.setValueAt(getPrevoiusValue(row) - 1, row, 1);
}

public static void main(String[] args) {
    new TableDropDown().setVisible(true);
}
}