JTable: JComboBox ItemListener 在没有改变的情况下被触发
JTable: JComboBox ItemListener triggered without change
我向 JTable 添加了一个 JComboBox:
table.getColumnModel().getColumn(16).setCellEditor(new DefaultCellEditor(c = new JComboBox()));
c.addItemListener(new CItemListener());
当 (de)selecting 一个项目时触发监听器。没关系。然而,我的问题是:我在一行组合框中得到 "B" selected,在另一行组合框中得到 "A"。当我有 "B" selected 的组合框 + 行,现在 select 有 "A" 的行时,Listener 被 Item "B" de[=29 触发=]ed 和 "A" selected,尽管我没有单独更改 selection。仅当我单击组合框(不更改 selection)时才会出现这种情况,如果我 select 其他地方的行则不会出现这种情况。
可以改变这种行为吗?如果是这样:如何?
目标:仅在创建 selection 时触发侦听器,而不是在组合框为 de/selected 且未更改项目时触发。
听众:
@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);
}
}
你目前的方法有问题
当您正在收听 Combobox 的 itemStateChanged
时,即使更改了一行,也会为所有行调用它,因为这是预期的行为。[尝试在该侦听器中放置打印语句以查看此内容]
在 table
的列更改中无需听组合框更改您想听的内容
当您根据组合框的某些值递增时 values.I 提出了以下解决方案。
有一个 mainTable
,其中第 2 列 [索引 1] 是一个下拉菜单。
每当 mainTable
中任何行的组合框值更改时,旧值都会递减,新值会递增 counterTable
.
我已经覆盖了 DefaultTableModel,这样每当调用 setValue 时,它都会检查它是否是我们想要的列,如果是,它将对计数器中的旧值进行递减,对新值进行递增 table
仅 运行 下面的 SSCCE 代码和第二列中的 select 值并查看更改
以下内容满足您的要求
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);
}
}
我向 JTable 添加了一个 JComboBox:
table.getColumnModel().getColumn(16).setCellEditor(new DefaultCellEditor(c = new JComboBox()));
c.addItemListener(new CItemListener());
当 (de)selecting 一个项目时触发监听器。没关系。然而,我的问题是:我在一行组合框中得到 "B" selected,在另一行组合框中得到 "A"。当我有 "B" selected 的组合框 + 行,现在 select 有 "A" 的行时,Listener 被 Item "B" de[=29 触发=]ed 和 "A" selected,尽管我没有单独更改 selection。仅当我单击组合框(不更改 selection)时才会出现这种情况,如果我 select 其他地方的行则不会出现这种情况。
可以改变这种行为吗?如果是这样:如何?
目标:仅在创建 selection 时触发侦听器,而不是在组合框为 de/selected 且未更改项目时触发。
听众:
@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);
}
}
你目前的方法有问题
当您正在收听 Combobox 的 itemStateChanged
时,即使更改了一行,也会为所有行调用它,因为这是预期的行为。[尝试在该侦听器中放置打印语句以查看此内容]
在 table
的列更改中无需听组合框更改您想听的内容当您根据组合框的某些值递增时 values.I 提出了以下解决方案。
有一个 mainTable
,其中第 2 列 [索引 1] 是一个下拉菜单。
每当 mainTable
中任何行的组合框值更改时,旧值都会递减,新值会递增 counterTable
.
我已经覆盖了 DefaultTableModel,这样每当调用 setValue 时,它都会检查它是否是我们想要的列,如果是,它将对计数器中的旧值进行递减,对新值进行递增 table
仅 运行 下面的 SSCCE 代码和第二列中的 select 值并查看更改
以下内容满足您的要求
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);
}
}