当我通过按下OS X上的最大化按钮或全屏按钮放大窗口时,不再捕获鼠标移动事件(尽管拖动是).
我在下面添加了一个演示程序,突出了该问题.可以使用Java Tutorials网站上的MouseEventDemo Web start示例复制最大化问题.
经过一些故障排除后,我注意到如果鼠标离开窗口(例如,移动到窗口顶部以访问菜单栏)然后返回,则重新捕获鼠标移动.似乎问题可能与调整动画大小期间鼠标位置和窗口之间的关系有关,因为鼠标在调整大小之前不在帧中,但即使它不一定在此过程中移动也是如此.
import java.awt.Window;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.lang.reflect.Method;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Main implements MouseMotionListener {
JLabel label = new JLabel("label");
public static void main(String[] args) {
Main main = new Main();
main.init();
}
public void init() {
JFrame frame = new JFrame();
frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(label);
frame.addMouseMotionListener(this);
frame.setVisible(true);
if (isMacOSX()) {
enableFullScreenMode(frame);
}
}
public void mouseDragged(MouseEvent e) {
label.setText(e.toString());
}
public void mouseMoved(MouseEvent e) {
label.setText(e.toString());
}
private static boolean isMacOSX() {
return System.getProperty("os.name").indexOf("Mac OS X") >= 0;
}
public static void enableFullScreenMode(Window window) {
try {
Class<?> clazz = Class.forName("com.apple.eawt.FullScreenUtilities");
Method method = clazz.getMethod("setWindowCanFullScreen", new Class<?>[] { Window.class, boolean.class });
method.invoke(null, window, true);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行上面的代码应该显示标签何时更新和不更新.
我正在使用Java SE 7 [1.7.0_45]运行OS X版本10.9 Build 13A3017.
根据经验,如果在最大化时切换远离应用程序并且返回应用程序,问题就会消失.添加一个ComponentListener强制框架toFront()似乎工作.另外,应该仅在事件派发线程上构造和操作Swing GUI对象.
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
frame.toFront();
}
});
Run Code Online (Sandbox Code Playgroud)
经测试:
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.lang.reflect.Method;
import javax.swing.JFrame;
import javax.swing.JLabel;
/** @see http://stackoverflow.com/a/20054242/230513 */
public class Main implements MouseMotionListener {
JLabel label = new JLabel("label");
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Main main = new Main();
main.init();
}
});
}
public void init() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.pack();
frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
if (isMacOSX()) {
enableFullScreenMode(frame);
}
frame.addMouseMotionListener(this);
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
frame.toFront();
}
});
}
@Override
public void mouseDragged(MouseEvent e) {
label.setText(e.toString());
}
@Override
public void mouseMoved(MouseEvent e) {
label.setText(e.toString());
}
private static boolean isMacOSX() {
return System.getProperty("os.name").indexOf("Mac OS X") >= 0;
}
public static void enableFullScreenMode(Window window) {
try {
Class<?> clazz = Class.forName("com.apple.eawt.FullScreenUtilities");
Method method = clazz.getMethod("setWindowCanFullScreen",
new Class<?>[]{Window.class, boolean.class});
method.invoke(null, window, true);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)