从侦听器中修改JFrame

可能重复:
如何在框架可见后调用setUndecorated()?

如果没有焦点并且在聚焦时装饰,我应该如何制作一个未装饰的JFrame?

这是我的代码:

import java.awt.event.*; import javax.swing.*; public class Test extends JFrame { public Test() { setSize(100, 50); addWindowFocusListener(new WindowAdapter() { public void windowGainedFocus(WindowEvent e) { setUndecorated(false); System.out.println("Hi!"); } public void windowLostFocus(WindowEvent e) { setUndecorated(true); System.out.println("Bye!"); } }); } public static void main(String[] args) { new Test().setVisible(true); } } 

这是运行时和聚焦/不聚焦时的问题:

 Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is displayable. at java.awt.Frame.setUndecorated(Frame.java:825) at Test$1.windowGainedFocus(Test.java:13) at java.awt.Window.processWindowFocusEvent(Window.java:1952) at java.awt.Window.processEvent(Window.java:1867) at java.awt.Component.dispatchEventImpl(Component.java:4750) at java.awt.Container.dispatchEventImpl(Container.java:2103) at java.awt.Window.dispatchEventImpl(Window.java:2518) at java.awt.Component.dispatchEvent(Component.java:4576) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:965) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:412) at java.awt.Component.dispatchEventImpl(Component.java:4620) at java.awt.Container.dispatchEventImpl(Container.java:2103) at java.awt.Window.dispatchEventImpl(Window.java:2518) at java.awt.Component.dispatchEvent(Component.java:4576) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:672) at java.awt.EventQueue.access$400(EventQueue.java:96) at java.awt.EventQueue$2.run(EventQueue.java:631) at java.awt.EventQueue$2.run(EventQueue.java:629) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:116) at java.awt.EventQueue$3.run(EventQueue.java:645) at java.awt.EventQueue$3.run(EventQueue.java:643) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.awt.EventQueue.dispatchEvent(EventQueue.java:642) at java.awt.SequencedEvent.dispatch(SequencedEvent.java:113) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:670) at java.awt.EventQueue.access$400(EventQueue.java:96) at java.awt.EventQueue$2.run(EventQueue.java:631) at java.awt.EventQueue$2.run(EventQueue.java:629) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:116) at java.awt.EventQueue$3.run(EventQueue.java:645) at java.awt.EventQueue$3.run(EventQueue.java:643) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.awt.EventQueue.dispatchEvent(EventQueue.java:642) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177) at java.awt.EventDispatchThread.run(EventDispatchThread.java:138) Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is displayable. at java.awt.Frame.setUndecorated(Frame.java:825) at Test$1.windowLostFocus(Test.java:18) at java.awt.Window.processWindowFocusEvent(Window.java:1955) at java.awt.Window.processEvent(Window.java:1867) at java.awt.Component.dispatchEventImpl(Component.java:4750) at java.awt.Container.dispatchEventImpl(Container.java:2103) at java.awt.Window.dispatchEventImpl(Window.java:2518) at java.awt.Component.dispatchEvent(Component.java:4576) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:965) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:712) at java.awt.Component.dispatchEventImpl(Component.java:4620) at java.awt.Container.dispatchEventImpl(Container.java:2103) at java.awt.Window.dispatchEventImpl(Window.java:2518) at java.awt.Component.dispatchEvent(Component.java:4576) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:672) at java.awt.EventQueue.access$400(EventQueue.java:96) at java.awt.EventQueue$2.run(EventQueue.java:631) at java.awt.EventQueue$2.run(EventQueue.java:629) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:116) at java.awt.EventQueue$3.run(EventQueue.java:645) at java.awt.EventQueue$3.run(EventQueue.java:643) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.awt.EventQueue.dispatchEvent(EventQueue.java:642) at java.awt.SequencedEvent.dispatch(SequencedEvent.java:113) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:670) at java.awt.EventQueue.access$400(EventQueue.java:96) at java.awt.EventQueue$2.run(EventQueue.java:631) at java.awt.EventQueue$2.run(EventQueue.java:629) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:116) at java.awt.EventQueue$3.run(EventQueue.java:645) at java.awt.EventQueue$3.run(EventQueue.java:643) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105) at java.awt.EventQueue.dispatchEvent(EventQueue.java:642) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177) at java.awt.EventDispatchThread.run(EventDispatchThread.java:138) 

原谅一个新手,我敢肯定这里有一些基本的概念,我最想知道的。

+1给@AaronKurtzhals和@trashgods评论提供以下想法的链接

这是我为帮助你而做的一个简短例子。

解:

1)在JFrame实例上调用dispose()来释放资源

2)根据需要编辑框架实例,即setUndecorated(..)

3)在JFrame上调用pack()setVisible(true)

当聚焦/鼠标hover时(如setUndecorated(true)我们无法监听焦点事件):

在此处输入图像描述

什么时候不专注:

在此处输入图像描述

 import java.awt.Dimension; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingUtilities; public class Test { private boolean firstTime2 = true; private boolean firstTime = true; private JFrame frame; private JLabel focusLabel=new JLabel(""); public Test() { initComponents(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Test(); } }); } private void initComponents() { initFrame(); frame.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseMoved(MouseEvent me) { super.mouseMoved(me); firstTime2 = false; firstTime = false; if (frame.isUndecorated()) { focusLabel.setText("Focused"); firstTime = true; firstTime2 = true; frame.dispose(); frame.setUndecorated(false); showFrame(); } } }); frame.addWindowFocusListener(new WindowAdapter() { @Override public void windowGainedFocus(WindowEvent e) { if (firstTime) { focusLabel.setText("Focused"); firstTime = false; frame.dispose(); frame.setUndecorated(false); showFrame(); } } @Override public void windowLostFocus(WindowEvent e) { if (!firstTime2) { focusLabel.setText("Not focused"); frame.dispose(); frame.setUndecorated(true); showFrame(); } firstTime2 = false; } }); showFrame(); } private void initFrame() { frame = new JFrame() { @Override public Dimension getPreferredSize() { return new Dimension(300, 300); } }; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(focusLabel); } private void showFrame() { frame.pack(); frame.setVisible(true); } } 

您可能已经注意到的一些提示:

  • 不要不必要地扩展JFrame
  • 使用Event Dispatch Thread创建和操作Swing组件