繁体   English   中英

单击Swing JTable中的行时发生意外的事件顺序

[英]Unexpected event order when clicking on row in Swing JTable

单击JTable中的一行时的默认行为似乎是...

1 event=javax.swing.event.ListSelectionEvent[ source=javax.swing.DefaultListSelectionModel 673443626 ~{0} firstIndex= 0 lastIndex= 0 isAdjusting= true ]
2 mousePressed
3 event=javax.swing.event.ListSelectionEvent[ source=javax.swing.DefaultListSelectionModel 673443626 ={0} firstIndex= 0 lastIndex= 0 isAdjusting= false ]
4 mouseReleased
5 mouseClicked

即使单击鼠标会启动操作,JTable事件也会在mousePressed之前潜入。 为什么不...

1 mousePressed
2 event=javax.swing.event.ListSelectionEvent[ source=javax.swing.DefaultListSelectionModel 673443626 ~{0} firstIndex= 0 lastIndex= 0 isAdjusting= true ]
3 event=javax.swing.event.ListSelectionEvent[ source=javax.swing.DefaultListSelectionModel 673443626 ={0} firstIndex= 0 lastIndex= 0 isAdjusting= false ]
4 mouseReleased
5 mouseClicked

我所追求的行为是

  1. 点击一行
  2. 在mousePressed中,检查是否选择了行?
  3. 否-仅选择行。
  4. 是的-执行一些操作。

当前发生的是,单击未选择的行时,步骤3和步骤4同时发生。 没有鼠标事件可用于检测是否选择了该行-它将始终处于选中状态。

或者换句话说...当您在JTable中的行上单击鼠标时,如何在单击事件期间测试是否仅在单击事件之前未选中该行?

这是一个SSCCE ...

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JTableRowSelectTest {

    public static void main(String args[]) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Object rowData[][] = {{"Row1-Column1"}, {"Row2-Column1"}};
        Object columnNames[] = {"Column One"};
        final JTable table = new JTable(rowData, columnNames);

        table.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                final int row = table.rowAtPoint(e.getPoint());
                if (row >= 0 && table.isRowSelected(row)) {
                    System.out.println("mouseClicked on selected row");
                } else {
                    // never reached.
                    System.out.println("mouseClicked on un-selected row");
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
                final int row = table.rowAtPoint(e.getPoint());
                if (row >= 0 && table.isRowSelected(row)) {
                    System.out.println("mousePressed on selected row");
                } else {
                    // never reached.
                    System.out.println("mousePressed on un-selected row");
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("mouseReleased");
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                System.out.println(e);
            }
        });

        frame.add(table, BorderLayout.CENTER);
        frame.setSize(300, 150);
        frame.setVisible(true);

    }
}

我已经遇到了这个问题:确定哪个事件触发了选择更改。 解决方案是:

if (EventQueue.getCurrentEvent() instanceof MouseEvent) {
  // handler for mouse
} else if (EventQueue.getCurrentEvent() instanceof KeyEvent) {
  // handler for key
}

只需在您的ListSelectionListener中使用它即可。 我不确定这种方法是否绝对正确,但是对我有用。

感谢@mKorbel。 还有另一种可能性可以检查是否通过鼠标或键盘进行了选择更改。 详细信息在这里

这是我的解决方案,尽管您感觉有点像是骇人听闻的,因为您必须使用来自另一个事件的信息-getValueIsAdjusting()。 它也只能在mousePressed()中工作。

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JTableRowSelectTest {

    private static boolean isValueAdjusting = false;

    public static void main(String args[]) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Object rowData[][] = {{"Row1-Column1"}, {"Row2-Column1"}};
        Object columnNames[] = {"Column One"};
        final JTable table = new JTable(rowData, columnNames);

        table.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouseClicked");
            }

            @Override
            public void mousePressed(MouseEvent e) {
                final int row = table.rowAtPoint(e.getPoint());
                if (row >= 0 && table.isRowSelected(row) && !isValueAdjusting) {
                    System.out.println("mousePressed on selected row " + row);
                } else {
                    System.out.println("mousePressed on un-selected row " + row);
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("mouseReleased");
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                isValueAdjusting = e.getValueIsAdjusting();
                System.out.println(e);
            }
        });

        frame.add(table, BorderLayout.CENTER);
        frame.setSize(300, 150);
        frame.setVisible(true);

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM