0

我有:

  • a JTable,嵌入在 a 中JScrollPane,包含项目列表
  • a JPanel,嵌入在 aJDialog中,显示与所选项目相关的信息

代码按预期工作(信息得到更新),除了每次更改选择时JTable失去焦点和获得焦点。JDialog所以我添加了一个table.requestFocusInWindowJTable仍然失去焦点,尽管调用返回 true。

如何确保JDialog更新但JTable不会失去焦点?

ps:我的最终目标是能够使用箭头(向上/向下)浏览表格并在 JDialog 中查看信息更新 - 目前,我需要单击行来执行此操作。

EDIT
See below a SSCCE that replicates my issue (the content of the JDialog changes when selection is changed but the focus is lost).

public class TestTable extends JTable {

    public static JFrame f = new JFrame();
    public static JTextField text = new JTextField();
    public static JDialog dialog;

    public static void main(String[] args) {
        f.setSize(300, 300);
        f.setLocation(300, 300);
        f.setResizable(false);
        showPopup();
        final JScrollPane jScrollPane = new JScrollPane();
        jScrollPane.getViewport().add(new TestTable());
        f.add(jScrollPane);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public TestTable() {
        super();
        setModel(new TestTableModel());
        getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                ListSelectionModel lsm = (ListSelectionModel) e.getSource();
                int row = lsm.getAnchorSelectionIndex();

                Object item = getModel().getValueAt(row, 0);

                text.setText(item.toString());
                dialog.setVisible(true);
                TestTable.this.requestFocusInWindow(); //DOES NOT DO ANYTHING
            }
        });
        setCellSelectionEnabled(false);
    }

    public class TestTableModel extends DefaultTableModel {

        public TestTableModel() {
            super(new String[]{"DATA"}, 3);
            setValueAt(Double.valueOf(-0.1), 0, 0);
            setValueAt(Double.valueOf(+0.1), 1, 0);
            setValueAt(Double.valueOf(0), 2, 0);
        }
    }

    private static void showPopup() {
        dialog = new JDialog(f, "Title");
        dialog.setContentPane(text);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.pack();
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
    }
}
4

1 回答 1

1

您的对话框中必须有一些东西可以即时抓住焦点,因为我已经尝试过使用 JLabel 并且它不会引起任何问题。如果您需要解决这个问题,您可以随时调用toFront()您的 JTable 父框架。如果它对您的情况没有帮助,请尝试编辑此SSCCE以重现您的问题。

请参阅此代码(评论标签上的 grabFocus 以说服自己在对话框中有一些东西可以抓住焦点):

import java.awt.Component;
import java.util.Vector;

import javax.swing.FocusManager;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class Test {

    public static class MyTableModel extends DefaultTableModel {
        private int count;

        public MyTableModel() {
            addColumn("Test");
        }

        public void insertNewRow() {
            Vector<String> rowData = createNewRowData();
            insertRow(0, rowData);
        }

        private Vector<String> createNewRowData() {
            Vector<String> data = new Vector<String>(1);
            data.add("Hello-" + count++);
            return data;
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().initUI();
            }
        });
    }

    public void initUI() {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final MyTableModel model = new MyTableModel();
        final JTable table = new JTable(model);
        for (int i = 0; i < 100; i++) {
            model.insertNewRow();
        }
        final JLabel label = new JLabel();
        JDialog dialog = new JDialog(frame, false);
        dialog.add(label);
        dialog.setSize(300, 50);
        dialog.setLocation(400, 0);
        dialog.setVisible(true);
        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                final Component focused = FocusManager.getCurrentManager().getFocusOwner();
                int index = table.getSelectionModel().getLeadSelectionIndex();
                if (index > -1) {
                    Object valueAt = model.getValueAt(index, 0);
                    label.setText("Current row selected is: " + valueAt);
                } else {
                    label.setText("No selection");
                }
                label.grabFocus();
                if (focused != null) {
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            frame.toFront();
                        }
                    });
                }
            }
        });
        final JScrollPane scroll = new JScrollPane(table);
        scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        frame.add(scroll);
        frame.pack();
        frame.setVisible(true);

    }
}
于 2012-05-10T17:21:16.423 回答