【问题标题】:JTable listener to open JDialog用于打开 JDialog 的 JTable 侦听器
【发布时间】:2015-05-01 09:36:35
【问题描述】:

抱歉,如果有类似的问题,找不到任何东西。

基本上,在我的程序中,我在 JTable 中的每一行都有它们的质量、描述、价格等项目。每当从表中选择该项目时,我都想打开一个新的 JDialog,其中包含有关该项目的更多信息。但是,我不知道如何获取所选行,例如更改其颜色以知道它已被选中。以下我尝试了,它没有做任何事情。我猜事件的来源与模型无关。

public void addListener(){

    table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (e.getSource() == table.getSelectionModel()) {
                ItemDialog id = new ItemDialog(table.getSelectedRow());
            }

        }

    });
}

【问题讨论】:

  • 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、自包含、正确示例)。对表格的一些数据进行硬编码。
  • JTable#getSelectedRow 会告诉您选择的行(如果没有,则为 -1),但您可能想要的是代表您的行的数据,这取决于TableModel 您正在使用。而且,如果我是您的用户,每次更改选择时您都会弹出一个对话框,我不会很高兴。考虑改用JButton(更多信息)或JPopupMenu...

标签: java swing jtable jdialog


【解决方案1】:

可以通过在表格的选择模型中添加列表选择监听器来获取选中的行:

import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

/**
 * Adapted version of a standard Java demo project:
 * https://docs.oracle.com/javase/tutorial/displayCode.html?
 *     code=https://docs.oracle.com/javase/tutorial/uiswing/examples
 *     /components/SimpleTableDemoProject/src/components
 *     /SimpleTableDemo.java
 */
public class SimpleTableDemo extends JPanel {
    public SimpleTableDemo() {
        super(new GridLayout(1, 0));

        String[] columnNames = {"First Name", "Last Name", "Sport",
                "# of Years", "Vegetarian"};

        Object[][] data = {
                {"Kathy", "Smith", "Snowboarding", 5, false},
                {"John", "Doe", "Rowing", 3, true},
                {"Sue", "Black", "Knitting", 2, false},
                {"Jane", "White", "Speed reading", 20, true},
                {"Joe", "Brown", "Pool", 10, false}
        };

        final JTable table = new JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);
        table.getSelectionModel().addListSelectionListener(
            selectionEvent -> {
                if (!selectionEvent.getValueIsAdjusting()
                    && selectionEvent.getSource().equals(table.getSelectionModel()))
                    System.out.println("Row index: " + table.getSelectedRow());
            }
        );
        add(new JScrollPane(table));
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("SimpleTableDemo");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        SimpleTableDemo newContentPane = new SimpleTableDemo();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(SimpleTableDemo::createAndShowGUI);
    }
}

【讨论】:

  • 请注意,ListSelectionListener 在取消选择和选择值时都会通知您
  • 是的,您是对的:如果您只想处理最终事件,请使用 getValueIsAdjusting 方法(仅当它返回 false 时)。查看更新的答案。
【解决方案2】:

以下是我的一个旧项目中的几行代码。 (我故意不提供完整代码,因为其中很多都是不敬的)

将 MouseListener 添加到表中

table.addMouseListener(new MouseListener() {
            public void mouseReleased(MouseEvent arg0) {
            }

            public void mousePressed(MouseEvent arg0) {
            }

            public void mouseExited(MouseEvent arg0) {
            }

            public void mouseEntered(MouseEvent arg0) {
            }

            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isRightMouseButton(e)) { // change it to whatever key or click you want
                    if (table.getRowCount() != 0) {
                        printSelectedRowData();
                    }
                }
            }
        });

这里是 printSelectedRowData() 方法

public void printSelectedRowData() {
    new SwingWorker<Void, Void>() {
        @Override
        protected Void doInBackground() throws Exception {
            try {
                Object[] rowData = new Object[table.getColumnCount()];
                for (int i = 0; i < table.getColumnCount(); i++) {
                    rowData[i] = table
                            .getValueAt(table.getSelectedRow(), i);
                    System.out.println(table.getColumnName(i) + ":  "
                            + rowData[i] + "\n");
                }
            } catch (Exception e) {
                System.err.println("Error  ");
            }
            return null;
        }
    }.execute();
}

【讨论】:

  • ListSelectionListener 是一个更好的主意,因为 MouseListener 不考虑键盘选择(可能是好事,也可能是坏事),但您永远不应该访问 UI 元素。在事件调度线程之外,您可能会陷入线程竞争状态,从而产生错误结果
  • 当然你没问题,正如我提到的,这是一个旧项目。它只是做同样事情的另一种方式可能不太安全。
猜你喜欢
  • 2012-01-21
  • 2012-09-04
  • 2012-10-30
  • 2012-07-18
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
  • 2016-08-21
相关资源
最近更新 更多