3

I am new to Swing so this might seem like a very naive question.

I have a JFrame which displays an initial statement and two radiobuttons. RadioButton1 is Accept and RadioButton2 is Reject. If the user chooses Accept, the program proceeds. So I have created an ActionListener for Accept so that the rest of my code is within this ActionListener. However, as soon as the user presses Accept, the GUI freezes. Pressing Reject just exists out of the program.

    public void game() throws Exception
    {
        jTextArea1.setLineWrap(true);
        jTextArea1.setWrapStyleWord(true);
        jTextArea1.setText("Please choose Accept or Reject");


        jRadioButton1.setVisible(true);
        jRadioButton2.setVisible(true);

            jRadioButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {

              jRadioButton1.setVisible(false);
              jRadioButton2.setVisible(false);
              repaint();
             //more code
           });
    }

After this I make connections to the server which works fine since when I use System.out.println(), all the outputs are fine, just the GUI is frozen.

Is there a better way to continue when the user presses Accept?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
user1773010
  • 107
  • 7
  • 4
    Your problem is in the `//more code` section. You're calling a long-running process on the Swing event thread which will tie up this thread preventing it from painting the GUI or interacting with the user effectively freezing your app. The solution is to use a SwingWorker for background threading. – Hovercraft Full Of Eels Oct 25 '12 at 03:56
  • 2
    For more on this, please read [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html). – Hovercraft Full Of Eels Oct 25 '12 at 04:04
  • 1
    There is no need for the `repaint` call BTW. Calling `setVisible(false)` will trigger a repaint automatically – Robin Oct 25 '12 at 06:02

2 Answers2

6

You can look at using the SwingWorker class.

Basically, Java Swing applications are single threaded and if there are any process intensive tasks which you perform, the control transfers to that section of code and the UI hangs, waiting for control to be handed back.

Edit: You can also look into the SwingUtilities class.

Edit: Basic info on using the SwingWorker class:

You can create a new class which extends SwingWorker and implement the public String doInBackground() { /*Do Stuff here*/ } method. And in your ActionListener event, create an instance of the SwingWorker and call the swingWorkerObject.execute() method to start the doInBackground method execution.

More details here: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

agirish
  • 473
  • 4
  • 9
2

Only put the minimum required GUI updates in the event handling, for the rest non-GUI, use Threads.
By the way, no repaint is required after setVisible.

Mordechai
  • 15,437
  • 2
  • 41
  • 82
  • The comment `no repaint is required after setVisible` is true for simple components, but is not true if components are added or removed, or if animation is needed. – Hovercraft Full Of Eels Oct 25 '12 at 04:05