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
打印消息,注意panel1
在JScrollPane
后面,因此绿色边框之外的任何内容都是panel1
。 要使其适用于JScrollpane
/ panel2
和JPanel
/ 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); } } }
编辑:
不过,我个人不会推荐这个,
要将一个侦听器添加到将捕获所有MouseEvent
的JFrame
,请使用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
添加到JFrame
的glasspane.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,并且没有可能的火灾事件没有从父到子的重新分配坐标
-
你也可以以编程方式重新调度事件,