tags:

views:

49

answers:

2

Hello,

I have a simple Java Swing GUI Form with a browse button. The browse button creates a new JFileChooser when it's clicked.

However, if you click browse immediately after the window opens, the file chooser window seems to loose focus, showing the parent window behind it, but it refuses to repaint itself. I have to drag it off screen and back on again to get it to return to normal.

I've tried to reduce my code to the simplest version that still has the problem. (It just makes a very large browse button.

public class FormTest extends JFrame
{
    private final int width = 490;
    private final int height = 400;

    private JPanel outerPanel;

    private static FormTest myTest;

    public static void main(String[] args)
    {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch( Exception e )
        {
            e.printStackTrace();
        }

        myTest = new FormTest();
        myTest.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        myTest.setResizable(false);
        myTest.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                closeWindow();
            }
        });
        myTest.setVisible(true);
    }

    public FormTest()
    {
        super("Convert Ratings");

        this.setSize(width, height);

        initComponents();
    }

    private void initComponents()
    {
        outerPanel = new JPanel();
        outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
        outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.Y_AXIS));

        outerPanel.add(Box.createRigidArea(new Dimension(0, 5)));

        JButton myButton = new JButton("browse");
        myButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                JFileChooser fileChooser = new JFileChooser();

                fileChooser.showOpenDialog(myTest);
            }
        });
        outerPanel.add(myButton);

        this.add(outerPanel);
    }

    private static void closeWindow()
    {
        int result = JOptionPane.showConfirmDialog(myTest, "Are you sure you want to close the application?",
                                                   "Question", JOptionPane.YES_NO_OPTION);

        if( result == JOptionPane.YES_OPTION )
        {
            System.exit(0);
        }
    }
}

In this example, the browse button must be clicked immediately after the window opens and the bug will show itself after about 10 seconds.

Any help or suggestions would be much appreciated.

Thanks,

B.J.

+1  A: 
David Young
I don't think I am, but I could be wrong. My long running tasks don't start until a button is clicked a few screens away (and I use swing workers to perform them). It does seem like something is going on, but I'm not sure how to find it.
Benny
@Benny: You can use `SwingUtilities.isEventDispatchThread()`, http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html
trashgod
I've reviewed my application but I've been unable to find any place where I'm modifying the GUI outside of an event dispatch thread.
Benny
I believe I may have located the problem area. I've updated my initial question to reflect this discovery. My guess is that the validate function is taking too long when the Next button is clicked.
Benny
+1  A: 

Since your question has changed I'll add another answer. It looks like you're looking to use a CardLayout.

The unresponsiveness of your application is probably caused by some incorrect logic with repainting/hiding/unhiding panels.

Here is Oracle's tutorial on using it http://download.oracle.com/javase/tutorial/uiswing/layout/card.html

David Young
Thank you for the help. I've modified my code to use the CardLayout layout manager instead of switching out the panels myself, which, I'm sure, is much more efficient. However, the problem is still occurring. I'm guessing the next "card" is displayed (along with the form buttons) before it's validated, which is why, if you click browse fast enough, the window underneath gets repainted. Any ideas?
Benny
I've edited the question again, attempting to simplify the problem. The program now only shows a single component that opens a JFileChooser dialog box when clicked.
Benny
So, it seems like the problem only exists on my machine. It doesn't seem to be a problem on other machines running my application. Thank you again for the help, and giving me the info on CardLayout.
Benny