Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying a JFrame from within a Listener [duplicate]

Possible Duplicate:
How to call setUndecorated() after a frame is made visible?

How should I make a JFrame be undecorated when unfocused and decorated when focused?

Here's my code:

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);
    }
}

And here's the problem when run and whenever focused/unfocused:

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)

Forgive a newb, I'm sure there's some fundamental concept I'm missing here, and I'd like to know that the most.

like image 883
werdnanoslen Avatar asked Dec 20 '12 19:12

werdnanoslen


1 Answers

+1 to @AaronKurtzhals and @trashgods comments for the link that gave the ideas below

Here is a short example I made to help you out.

Solution:

1) call dispose() on JFrame instance to release resources

2) edit frame instance as needed i.e setUndecorated(..)

3) Call pack() and setVisible(true) on JFrame.

when focused/Mouse over (as when setUndecorated(true) is called we cannot listen for focus events):

enter image description here

when not focused:

enter image description here

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);
    }
}

Some tips you might have noticed:

  • Dont extend JFrame unnecessarily
  • Use Event Dispatch Thread to create and manipulate Swing components
like image 99
David Kroukamp Avatar answered Oct 23 '22 00:10

David Kroukamp