当单元格内的 JComboBox 中有 ItemEvent 时,如何获取 CellRow

发布于 12-03 20:53 字数 3620 浏览 1 评论 0原文

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

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

但是,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;
    }
}

I have a JTable with a column containing a JComboBox.

I have an ItemListener attached to the JComboBox which acts upon any changes.

However, ItemListener does not have a method for obtaining the Row that the changed ComboBox is within.

I need to Row number in order to act upon another column in the same row when the ComboBox has a change.

Any help would be appreciated.


This is my Short and Concise code. What I am trying to accomplish, is obtaining the Table Row of the ComboBox when a the itemlistener picks up a change.

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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁拥2024-12-10 20:53:56

听起来您使用组合框作为编辑器。如果是这样,则使用 TableCellEditor 方法,getTableCellEditorComponent(),包含 row 作为参数。 此处有一个相关示例。

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

附录:根据您的示例,下面的代码将重写模型的 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);
    }
}

It sounds like you are Using a Combo Box as an Editor. If so, the TableCellEditor method, getTableCellEditorComponent(), includes the row as a parameter. There's a related example here.

Addendum: To change a value in the same row you've edited, just have the model return the correct value for the "other column" based on the related values in that row. Alternatively, update the related value in your model's setValueAt() method before firing the update, as shown in the example.

Addendum: Based on your example, the code below overrides the model's getValueAt() method to keep the dependent column synchronized with the item column.

enter image description here

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文