【问题标题】:How do I get the CellRow when there is an ItemEvent in the JComboBox within the cell当单元格内的 JComboBox 中有 ItemEvent 时,如何获取 CellRow
【发布时间】:2011-11-13 02:34:37
【问题描述】:

我有一个 JTable,其中有一列包含一个 JComboBox。

我有一个附加到 JComboBox 的 ItemListener,它会根据任何更改进行操作。

但是,ItemListener 没有获取更改后的 ComboBox 所在的 Row 的方法。

当 ComboBox 发生变化时,我需要行号以便对同一行中的另一列进行操作。

任何帮助将不胜感激。


这是我的简明代码。我想要完成的是,当 itemlistener 收到更改时获取 ComboBox 的表格行。

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class Example extends JFrame {

    private static final long serialVersionUID = 1L;
    public static int maxX, maxY;
    public static final String[] columnHeads = {"Col 1", "Col 2", "Col 3"};

    public static void main(String args[]) throws IOException {
        Example example = new Example();
    }

    public Example() {
        //Create Table Model
        DefaultTableModel model = new DefaultTableModel();

        for (int index = 0; index < columnHeads.length; index++) {
            model.addColumn(columnHeads[index]);
        }

        //Create Table
        JTable table = new JTable(model);
        JScrollPane scrollPane = new JScrollPane(table);

        //List for ComboBox
        String[] list = {"Item1", "Item2", "Item3"};

        //Create ComboBox
        JComboBox itemTypes = attachComboBoxRenderer(table, 2, list);

        //Attach Item Listener
        itemTypes.addItemListener(new ComboBoxListener());
        ((DefaultTableModel) table.getModel()).insertRow(
            table.getRowCount(), new Object[]{"C1", "C2", ""});
        this.setTitle("Example");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container container = getContentPane();

        //MAIN Panel
        final JPanel main = new JPanel();
        main.setLayout(new GridBagLayout());
        main.add(scrollPane);

        container.add(main);
        this.pack();
        this.setVisible(true);
    }

    public static JComboBox attachComboBoxRenderer(
        JTable table, int column, Object[] values) {
        JComboBox combo = new JComboBox(values);
        TableColumn col = table.getColumnModel().getColumn(column);
        col.setCellRenderer(new ComboBoxRenderer(values));
        col.setCellEditor(new DefaultCellEditor(combo));
        return combo;
    }
}

class ComboBoxListener implements ItemListener {

    private static final int SELECTED = 1;

    @Override
    public void itemStateChanged(ItemEvent e) {
        // Get the affected item
        Object item = e.getItem();
        if (item.toString() != null
            && !"".equals(item.toString())
            && e.getStateChange() == SELECTED) {
            System.out.println(item.toString() + " selected");
            //How do I get Row in the Table of the ComboBox that was changed?
        }
    }
}

class ComboBoxRenderer extends JComboBox implements TableCellRenderer {

    private static final long serialVersionUID = 1L;

    public ComboBoxRenderer(Object[] items) {
        super(items);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            super.setBackground(table.getSelectionBackground());
        } else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
        }
        // Select the current value
        setSelectedItem(value);
        return this;
    }
}

【问题讨论】:

  • “包含 JComboBox 的列”是什么意思?作为渲染组件,作为编辑组件,作为数据?

标签: java swing jtable jcombobox tablecelleditor


【解决方案1】:

听起来你是Using a Combo Box as an Editor。如果是这样,TableCellEditor 方法 getTableCellEditorComponent() 将包含 row 作为参数。有一个相关的例子here

附录:要更改您已编辑的同一行中的值,只需让模型根据该行中的相关值返回“其他列”的正确值。或者,在触发更新之前更新模型的setValueAt() 方法中的相关值,如example 所示。

附录:根据您的示例,下面的代码覆盖模型的getValueAt() 方法以保持依赖列与项目列同步。

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

/** @see http://stackoverflow.com/questions/7350445 */
public class DependentColumn extends JFrame {

    private static final int DEPENDENT_COL = 1;
    private static final int ITEM_COL = 2;
    private static final String[] columnNames = {"Col 1", "Col 2", "Col 3"};

    public static void main(String args[]) throws IOException {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                DependentColumn dc = new DependentColumn();
            }
        });
    }

    public DependentColumn() {
        this.setTitle("Example");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create Model & Table
        DefaultTableModel model = new DefaultTableModel(columnNames, 0) {

            @Override
            public Object getValueAt(int row, int col) {
                if (col == DEPENDENT_COL) {
                    return "C2:" + this.getValueAt(row, ITEM_COL);
                } else {
                    return super.getValueAt(row, col);
                }
            }
        };
        for (int i = 0; i < 16; i++) {
            model.addRow(new Object[]{"C1", "C2", "Item1"});
        }
        JTable table = new JTable(model);
        table.setPreferredScrollableViewportSize(new Dimension(320, 120));

        //Create ComboBox
        String[] items = {"Item1", "Item2", "Item3"};
        JComboBox combo = new JComboBox(items);
        TableColumn col = table.getColumnModel().getColumn(ITEM_COL);
        col.setCellEditor(new DefaultCellEditor(combo));
        combo.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    System.out.println(e.getItem() + " selected");
                }
            }
        });

        this.add(new JScrollPane(table));
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
}

【讨论】:

  • 感谢您的快速回复。但是 getTableCellEditor() 方法需要我给它一个行值,它返回 CellEditor 组件。我想从选定的组件中找出行是什么。
  • 我已经在上面详细说明了;但是,没有你的sscce,我猜。
  • 附录 +1 - 这是要走的路@JeffS - 永远不要直接听编辑,他们的目的是为一位大师(JTable fi)服务,并且会愚弄其他人:- )
  • @JeffS:我修改了您的 sscce 以说明一种方法并承认 kleopatra 的深刻观察。
猜你喜欢
  • 2020-01-02
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
相关资源
最近更新 更多