Java UIManager SetLookAndFeel 的鼠标侦听器错误
Java Mouse Listener error with UIManager SetLookAndFeel
下面的代码显示 JFrame
和 JMenu
以及 [自定义] JPanel
。
我通过调用方法 UIManager.setLookAndFeel
将外观 (LAF) 设置为 Windows LAF
我用鼠标单击 JMenu
,然后将鼠标移到 [自定义] JPanel
- 同时菜单仍然可见。然后我再次单击鼠标,我的 [custom] JPanel
上的 MouseListener
的 mousePressed
方法没有被调用,即使 mouseReleased
方法调用了。
如果我没有明确设置 LAF,即如果我使用默认的 LAF,它工作正常。
我该如何解决这个问题?
下面有两个 class:MListen
和 Panel
。 Class MListen
声明了一个 main
方法,因此您可以启动那个 class。然后您可以执行上述操作来重现该行为。 Class Panel
是我的习惯 JPanel
.
我希望在 class Panel
中 MouseListener
的 mousePressed
方法在每次按下鼠标时调用 [=] 24=].
- MListen.java
package drawer.Main;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
public class MListen extends JFrame{
public MListen(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
//setExtendedState(MAXIMIZED_BOTH);
setLayout(new BorderLayout());
getContentPane().setBackground(Color.WHITE);
Panel panel = new Panel();
JMenuBar bar = new JMenuBar();
JMenu file = new JMenu("file");
JMenuItem open = new JMenuItem("open");
JButton b = new JButton("AB");
file.add(b);
bar.add(file);
file.add(open);
setJMenuBar(bar);
add(panel, BorderLayout.CENTER);
setVisible(true);
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
new MListen();
}
});
}
}
- Panel.java
package drawer.Main;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
public class Panel extends JPanel implements MouseListener, MouseMotionListener{
public float size;
public Color color;
public boolean DoDraw;
public Panel(){
addMouseListener(this);
setFocusable(true);
addMouseMotionListener(this);
setBackground(Color.RED);
}
@Override
public void mouseDragged(MouseEvent arg0) {
//System.out.println("Drag");
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
System.out.println("Press");
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("relese");
// TODO Auto-generated method stub
}
}
尝试 运行 点击红色 JPanel
上面的代码。控制台将显示“按下”。现在点击 JMenu
然后点击 JPanel
和“按下”将 而不是 显示在控制台中。
谢谢!
- 编辑
我需要 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
我可以在不删除它的情况下修复它吗?
另外我第一次需要 MousePressed
这是一个错误的答案,但它应该有效。您可以在委托之前捕获所有事件。
这可以添加到您的 JPanel 构造函数中。
long eventMask = AWTEvent.MOUSE_EVENT_MASK;
Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener() {
public void eventDispatched(AWTEvent e){
MouseEvent evt = (MouseEvent)e;
if( evt.getSource() == this && evt.getId()==MouseEvent.MOUSE_PRESSED ){
this.mousePressed(evt);
evt.consume();
}
}
}, eventMask );
这会捕获所有鼠标事件,检查它们是否来自正确的面板,检查它是否是 mousePressed 事件并调用该方法。
这是用于调试的好代码,但在您的项目中不好找到。
下面的代码显示 JFrame
和 JMenu
以及 [自定义] JPanel
。
我通过调用方法 UIManager.setLookAndFeel
我用鼠标单击 JMenu
,然后将鼠标移到 [自定义] JPanel
- 同时菜单仍然可见。然后我再次单击鼠标,我的 [custom] JPanel
上的 MouseListener
的 mousePressed
方法没有被调用,即使 mouseReleased
方法调用了。
如果我没有明确设置 LAF,即如果我使用默认的 LAF,它工作正常。
我该如何解决这个问题?
下面有两个 class:MListen
和 Panel
。 Class MListen
声明了一个 main
方法,因此您可以启动那个 class。然后您可以执行上述操作来重现该行为。 Class Panel
是我的习惯 JPanel
.
我希望在 class Panel
中 MouseListener
的 mousePressed
方法在每次按下鼠标时调用 [=] 24=].
- MListen.java
package drawer.Main;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
public class MListen extends JFrame{
public MListen(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
//setExtendedState(MAXIMIZED_BOTH);
setLayout(new BorderLayout());
getContentPane().setBackground(Color.WHITE);
Panel panel = new Panel();
JMenuBar bar = new JMenuBar();
JMenu file = new JMenu("file");
JMenuItem open = new JMenuItem("open");
JButton b = new JButton("AB");
file.add(b);
bar.add(file);
file.add(open);
setJMenuBar(bar);
add(panel, BorderLayout.CENTER);
setVisible(true);
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
new MListen();
}
});
}
}
- Panel.java
package drawer.Main;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
public class Panel extends JPanel implements MouseListener, MouseMotionListener{
public float size;
public Color color;
public boolean DoDraw;
public Panel(){
addMouseListener(this);
setFocusable(true);
addMouseMotionListener(this);
setBackground(Color.RED);
}
@Override
public void mouseDragged(MouseEvent arg0) {
//System.out.println("Drag");
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
System.out.println("Press");
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("relese");
// TODO Auto-generated method stub
}
}
尝试 运行 点击红色 JPanel
上面的代码。控制台将显示“按下”。现在点击 JMenu
然后点击 JPanel
和“按下”将 而不是 显示在控制台中。
谢谢!
- 编辑 我需要 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); 我可以在不删除它的情况下修复它吗? 另外我第一次需要 MousePressed
这是一个错误的答案,但它应该有效。您可以在委托之前捕获所有事件。
这可以添加到您的 JPanel 构造函数中。
long eventMask = AWTEvent.MOUSE_EVENT_MASK;
Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener() {
public void eventDispatched(AWTEvent e){
MouseEvent evt = (MouseEvent)e;
if( evt.getSource() == this && evt.getId()==MouseEvent.MOUSE_PRESSED ){
this.mousePressed(evt);
evt.consume();
}
}
}, eventMask );
这会捕获所有鼠标事件,检查它们是否来自正确的面板,检查它是否是 mousePressed 事件并调用该方法。
这是用于调试的好代码,但在您的项目中不好找到。