MouseEvent在JScrollPane中丢失了

这是我用来显示我在另一个项目中遇到的问题的代码。

如果我使用JScrollPane作为panel2的包装器,我没有得到任何这样的行。 为什么? 我想点击JscrollPane并打印事件如下。

java.awt.event.MouseEvent[MOUSE_CLICKED,(800,469),absolute(808,499),button=1,modifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,934x612,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.border.LineBorder@cc0e01,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=880,height=630]] 

如果现在我改变了

 panel1.add(pane); 

 panel1.add(panel2); 

然后打印上面的消息。

 public class LostMouseEvent { public static void main(String[] args) { new LostMouseEvent(); } public LostMouseEvent() { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); JPanel panel1 = new JPanel(); JPanel panel2 = new JPanel(); JScrollPane pane = new JScrollPane(panel2); panel1.setPreferredSize(new Dimension(880, 630)); panel1.setBorder(BorderFactory.createLineBorder(Color.blue)); panel2.setPreferredSize(new Dimension(840, 610)); panel2.setBorder(BorderFactory.createLineBorder(Color.green)); panel1.add(pane); frame.add(panel1); frame.pack(); frame.setVisible(true); frame.setSize(950, 650); panel1.addMouseListener(new MyMouseListener()); } }); } private class MyMouseListener extends MouseAdapter { @Override public void mouseClicked (MouseEvent me) { System.out.println(me); } } } 

UPD:实际上在我的项目中,不仅仅有一个面板2。 最初,我有panel1和许多panel2。 然后我想用JScrollPane包装每个panel2并开始面对这个问题。

我只需要一个MouseListener来最小化对代码的更改。

  • 使用EDT创建和操作Swing组件
  • 在设置JFrame可见之前,不要调用setSize()而是调用pack()
  • 不要调用setPrefferedSize()而是覆盖getPrefferedSize()

您的代码按预期工作,它只会在单击panel1打印消息,注意panel1JScrollPane后面,因此绿色边框之外的任何内容都是panel1 。 要使其适用于JScrollpane / panel2JPanel / panel1只需将MouseListener添加到所需组件的BOTH

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; public class LostMouseEvent { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new LostMouseEvent(); } }); } public LostMouseEvent() { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); JPanel panel1 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(880, 630); } }; JPanel panel2 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(840, 610); } }; JScrollPane pane = new JScrollPane(panel2); panel1.setBorder(BorderFactory.createLineBorder(Color.blue)); panel2.setBorder(BorderFactory.createLineBorder(Color.green)); panel1.add(pane); frame.add(panel1); MouseListener ml=new MyMouseListener(); //add mouse listener to panel1 and panel2 panel1.addMouseListener(ml); panel2.addMouseListener(ml); //alternatively add to pane //pane.addMouseListener(ml); frame.pack(); frame.setVisible(true); } }); } private class MyMouseListener extends MouseAdapter { @Override public void mouseClicked(MouseEvent me) { System.out.println(me); } } } 

编辑:

不过,我个人不会推荐这个,

要将一个侦听器添加到将捕获所有MouseEventJFrame ,请使用Toolkit类并调用addAWTEventListener如下所示:

 Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { @Override public void eventDispatched(AWTEvent awte) {//all mouse events will be processed here you will have to check for the mouse events you are interested in System.out.println(awte); } }, AWTEvent.MOUSE_EVENT_MASK);//for Mouse events only 

更新1:

您还可以通过JFrame.getGlassPane().addMouseListener(ml)MouseListener添加到JFrameglasspane.addMouseListener JFrame.getGlassPane().addMouseListener(ml)在设置JFrame可见后,不要忘记设置glasspane 。 这将允许您只需添加一个Listener 。 看这里:

 ... MouseListener ml = new MyMouseListener(); //add mouse listener to panel1 and panel2 //panel1.addMouseListener(ml); //panel2.addMouseListener(ml); //alternatively add to pane //pane.addMouseListener(ml); frame.getGlassPane().addMouseListener(ml); frame.pack(); frame.setVisible(true); frame.getGlassPane().setVisible(true); ... 

UPADTE 2:

您在JScrollPane遇到MouseEvent问题的主要原因是因为它是一个错误。 看到这里 。

所示的工作是:

 public Test() { setUI(new javax.swing.plaf.metal.MetalScrollPaneUI(){ public void installListeners(JScrollPane scrollPane){} }); JPanel canvas = new JPanel(); canvas.add( new JLabel("Test") ); setViewportView( canvas ); setVisible(true); } 

MouseEvent在JScrollPane中丢失了

  • 答案非常/非常简单,确保没有关于丢失事件的事情,也没有JScrollPane,

  • 只有在添加了适当的侦听器时,Swing JComponent才能触发事件

  • 你没有将MouseListener添加到第二个JPanel,

  • 这个JPanel放在父JPanel中,这个父级添加了MouseListener,然后激活了mouseEvent,确保在你的情况下只在第二个JPanel的Bounds之外添加到这个容器

  • 然后第二个JPanel是deepestComponentAt,并且没有可能的火灾事件没有从父到子的重新分配坐标

  • 你也可以以编程方式重新调度事件,