3

Background Information

I would like to build a tool/palette window (also called a "floating" window) in Swing with Java Version 1.6.0_26. I thought a JWindow is the best pick, and also the Swing documentation points out to use a JWindow for such purposes (floating window, which has an owner frame, has no decoration and no windows taskbar entry).

My floating tool window's content consists of several other components like JButtons and also JTextFields.

The problem

When I click into the floating tool window, the owner window (the JFrame, my "main application window") "flickers" occasionally. The "flicker" looks like the owner window is losing the focus for a few milliseconds and than gets the focus back, resulting in a very fast disabling/enabling of the window (note that no window event is fired, like focus-lost or window-deactivated).

I have tested this under Windows 7 64 Bit and Windows XP.

Video and example code

To clarify the problem (it is a bit difficult to explain), I've taken a video, there you can see the "flicker" of the owner window while I click onto the floating tool window repeatedly:

I also put together a simple example code to reproduce the problem (this code is used in the video):

import java.awt.*;
import javax.swing.*;

public class JWindowFlickerExample
{
    public JWindowFlickerExample()
    {
        // I know swing code should be executed on the EDT,
        // just wanted to keep it simple

        // Create and show the "main application window"
        JFrame frame = new JFrame( getClass().getSimpleName() );
        frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
        frame.setSize( 640, 480 );
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );

        // Create and show the "floating tool window"
        MyFloatingToolWindow testWindow = new MyFloatingToolWindow( frame );
        testWindow.setLocation( 400, 400 );
        testWindow.setVisible( true );
    }

    public static void main( String[] args )
    {
        new JWindowFlickerExample();
    }

    @SuppressWarnings( "serial" )
    private class MyFloatingToolWindow extends JWindow
    {
        public MyFloatingToolWindow( Window hostWindow )
        {
            super( hostWindow );

            // setFocusableWindowState( false );
            setSize( 300, 400 );
            setLayout( null );
            getContentPane().setBackground( Color.LIGHT_GRAY );

            JTextField textField = new JTextField();
            textField.setLocation( 50, 50 );
            textField.setSize( 70, 30 );

            add( textField );
        }
    }
}

Progress so far

I also tried to set "Window.setFocusableWindowState" to false for the floating tool window. If it is false, there is no "flicker", the problem is gone. The JavaDoc for that method points out:

Setting a Window's focusability state to false is the standard mechanism for an application to identify to the AWT a Window which will be used as a floating palette or toolbar, and thus should be a non-focusable Window."

But then I can't use a JTextField in the floating tool window of course, because I can't focus it (maybe a text field in a floating tool window is unusual, but in my case a must).

I guess the "flicker" effect has something to do with the focus management in some way... for the fraction of a second the floating tool window gets the focus, taking it away from the owner window and then back. But I'm not sure; as a side note: if the text field in the floating tool window has the focus, the owner window stays enabled (which is a correct behavior).

I hope there is an easy solution, one so that I can stay with the JWindow as my floating tool window and with text fields as it's content - because, apart from the described "flicker" problem, everything works great.

I really appreciate any help, thanks a lot!

It's Leto
  • 968
  • 4
  • 17
  • 25
  • Have you considered using a non-modal JDialog? – Guillaume Polet Feb 11 '12 at 16:31
  • I will try out using a non-modal JDialog, thanks for the hint. Is there a significant difference between a JWindow and a non-modal JDialog? – It's Leto Feb 11 '12 at 18:37
  • Ok I switched the JWindow for a non-modal JDialog. The difference is, that the JDialog gets the window-focus, making the "main application window" disabled. What I have in mind is to create a non-decorated floating tool window, to the main windows (owning window) always keeps the window focus. It looks weird when the user clicks on the non-decorated floating tool window and the main application window gets deactivated :/ – It's Leto Feb 11 '12 at 18:42
  • No solution, just an observation: I can easily - just a couple of clicks - verify the flicker with jdk6 both on vista and XP (different update versions), but not with jdk7 on vista – kleopatra Feb 12 '12 at 12:54
  • Thanks a lot for this comment; I will try jdk7 myelf and see how it looks like under Win 7. – It's Leto Feb 17 '12 at 16:53

2 Answers2

2

Does this variant of the code show the same problem? (Note: I did not see any noticeable flicker before I started changing it.)

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class JWindowFlickerExample
{
    public JWindowFlickerExample()
    {
        // I know swing code should be executed on the EDT,
        // just wanted to keep it simple
        // SOMETIMES 'KEEPING IT SIMPLE' CAN CAUSE THE PROBLEM!

        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                // Create and show the "main application window"
                JFrame frame = new JFrame( getClass().getSimpleName() );
                frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
                frame.pack();
                frame.setSize( 640, 480 );
                frame.setLocationRelativeTo( null );
                frame.setVisible( true );

                // Create and show the "floating tool window"
                MyFloatingToolWindow testWindow = new MyFloatingToolWindow( frame );
                testWindow.setLocation( 400, 400 );
                testWindow.setVisible( true );
            }
        });
    }

    public static void main( String[] args )
    {
        new JWindowFlickerExample();
    }

    @SuppressWarnings( "serial" )
    private class MyFloatingToolWindow extends JWindow
    {
        public MyFloatingToolWindow( Window hostWindow )
        {
            super( hostWindow );

            JTextField textField = new JTextField(20);

            JPanel p = new JPanel(new GridLayout());
            p.setBackground( Color.GREEN );
            p.setBorder(new EmptyBorder(40,40,40,40));
            p.add(textField);
            add( p );

            pack();
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Yes, when I run your code I see the same flickering. Note that sometimes, you have to click a lot before you can see the flicker. In the video, I clicked ~ 3x the second to demonstrate the flicker (but I don't think that the speed is important, just the number of clicks, the flickering has a random nature). Can you please verify: please click quickly and a min of 20 times into the green window. The owner window is definitively flickering on my machine (our testers confirm that the flicker also occur on their machines). – It's Leto Feb 11 '12 at 18:21
  • Just to check: Did you see the problem in the video I recorded above? There is definitively a problem, and I slowly believe that this is some kind of Java bug – It's Leto Feb 11 '12 at 20:47
  • Interesting that you don't see it - maybe it's a OS-dependent bug, you'r on a Linux box, afair? – kleopatra Feb 12 '12 at 12:59
  • @kleopatra No, Windows 7. But then, maybe it is my tired old eyes or the fact I've not bothered to re-run the code and click 20 times. Hey, isn't that what the `Robot` is for?!? – Andrew Thompson Feb 12 '12 at 13:07
  • old eyes ... hach ... :-) Happens after two or three (on my XP netbook with an older jdk6 version) and a handful more on vista and a more recent jdk6 – kleopatra Feb 12 '12 at 13:10
  • @kleopatra OK - I've seen it now. Maybe it is time for the OP to add some code to dump telling properties of the JRE and raise a bug report. – Andrew Thompson Feb 12 '12 at 13:30
  • 1
    Thanks for your commments. Well, seems more and more like a bug. Think I will go create a bug report soon. – It's Leto Feb 17 '12 at 16:55
  • *"Think I will go create a bug report soon."* The sooner it is reported, the sooner it will be fixed. (Assuming it is a bug.) – Andrew Thompson Feb 17 '12 at 17:05
0

I think the bug at http://bugs.sun.com/view_bug.do?bug_id=4109702 may be related.

Anyway, here's a fix that seems to remove the flicker for me (Java 1.6 on Windows XP):

window = new JWindow(parentFrame);
window.setFocusableWindowState(false);
window.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentShown(ComponentEvent e) {
        window.setFocusableWindowState(true);
        // Putting the focus on the content pane means that the first
        // visible component isn't focused, but if the user tabs, they
        // will get to it.
        window.getContentPane().requestFocus();
    }
    @Override
    public void componentHidden(ComponentEvent e) {
        window.setFocusableWindowState(false);
    }
});

The trick seems to be to have the window not be focusable at the time it is shown.

MB.
  • 7,365
  • 6
  • 42
  • 42