1

I have two basic questions.

  • I have a GUI project with Java Swing. When I put buttons on the frame and I double clicked them, I had the code of the actionPerformed, but it is blocked.

    How can I put there a button and then use it on a actionListener?

  • My Project is about Server-client (multithread and sockets)

    I call one method to reiceve one string that we can write on a JtextField and it stays on a while cicle with PrintWriter and a getOutputStream.

    Something like:


do{
...
}while(thisstring!=null || thisstring!="exit")

So.. when I write something and press the button to send it, it stays on the cicle and the button blocks. How can I unblock the button to write something else?
Edit:
I understood the EDT problem, but I can't solve it.

I tried use the Timer but without success, something like that:

  int delay = 1000; //milliseconds
  ActionListener listener = new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  //My action calling the Thread class with the while cicle that has the PrintWriter
       }

  };
new Timer(delay, listener).start();

How can I handle this to do the timer when I press the button?

How can I stay on the that cicle (read the comment line) to send the information by OutputStream every time that one user enter something on the text field? I know that for example for a console application I use a BufferedReader and then I use the ReadLine() to wait for anything sent from the console, but with GUI interface it freezes all time..

Zhedar
  • 3,480
  • 1
  • 21
  • 44
Fabio Cardoso
  • 1,181
  • 1
  • 14
  • 37
  • what do you mean with "is blocked" and "blocks"? Theres no optical feedback, that you pressed it and it "hangs"? This may have several issues, e.g. by processing large data in the EDT(Event-Dispatcher-Thread). We may need to see some code. – Zhedar Dec 15 '12 at 20:10
  • private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { } So.. if I want change it to public for example, I can't edit it... After this code has been generated how can I use the button with an actionlister? In the 2nd question, the interface is locked because it is waiting to jump out of the cicle. – Fabio Cardoso Dec 15 '12 at 20:21
  • 1
    1) That do/while appears to be blocking the EDT. Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead implement a Swing `Timer` for repeating tasks or a `SwingWorker` for long running tasks. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details. 2) For better help sooner, post an [SSCCE](http://sscce.org/). 3) And please stop putting code in comments. It is unreadable. Instead edit it into the question. – Andrew Thompson Dec 16 '12 at 00:42
  • did that last addition solve your problem or is sth. left? – Zhedar Dec 29 '12 at 13:34

2 Answers2

3

There is a fundamental concept in Java GUI development surrounding which thread in which the developer implements user-interaction processing such as button clicks.

In short, you need to perform your processing outside of the thread that calls your action handling method. This single thread is known as the Event Dispatch Thread (EDT), and if you have logic that runs much more than a few milliseconds, it will prevent the UI from continuing to draw things like the button releasing, etc.

You'll want to move your long-running, socket code off the EDT. Doing so will allow the button to release and let the user interact with other controls (or even the same button).

To avoid duplicating other discussions on the topic, I direct you to this pretty good one. Additionally, this article gives a short overview of threading concepts in Swing.

Regards,

ScottH

Community
  • 1
  • 1
Scott Heaberlin
  • 3,364
  • 1
  • 23
  • 22
3

According to your comment you have some naming issues there. You need a class that implements the ActionListener-interface like so: class YourListenerClass implements ActionListener, but you could also do that via an anonymous class like new ActionListener { public void actionPerformed(ActionEvent e) { //your code for your button here } }); when you set your ActionListener.
The crucial thing is that you need to name your method the correct way. It MUST be public void actionPerformed(ActionEvent e) and you definitely have to implement the ActionListener-interface. The next thing is that you have to register your listener in your button like:

yourButton.addActionListener(new YourListenerClass);

or insert an anonymous class like I showed to you before.

The 2nd thing sounds like an multithreading issue like I mentioned in my comment. I didnt follow scotth's link, but according to his description this might be a source you want to read to solve any further blocking issues.
EDIT: Well, at first I didn't want to explain it, because it's quite a chunk of code, but as the problem persists I want to add something about SwingWorkers in my answer.
If you have long running code, it wont help to use a Timer as the code invoked by it will also be on the EDT as it's triggered by an event.
Instead of that you could use a SwingWorker to solve this. This needs some extra code, though. Here's a simple approach you could follow:

public class WorkingHard{
  SwingWorker<String, String> worker;
  JButton yourButton = ...;
  ...
  //do some cool stuff, as register those listeners!
  ...

  public void actionPerformed(ActionEvent evt){
      if(evt.getSource().equals(yourButton);
      // Construct a new SwingWorker
      worker = new SwingWorker<String, Void>(){


    @Override
    protected String doInBackground(){
      //do your reading in this method, it will be executed in an own thread
      String readText = "i will be read".
      /*your reading algorithm, you could also call publish(...) to post your results,
      e.g. likewise), then you also have to override process(...). this process will be
      thread save, too*/
      readText += ... ;

      ...
      return readText;
    }

    @Override
    protected void done(){
      try {
        //do sth. with your result, now thread safe.
        someGuiElement.setText(get());
      } catch (InterruptedException e) {
        e.printStackTrace();
      } catch (ExecutionException e) {
        e.printStackTrace();
      }
    }
  };
  // Execute the SwingWorker; the GUI will not freeze
  worker.execute();
}

}

If you want to know more about those workers... there several threads dealing about it, e.g. this one.

Community
  • 1
  • 1
Zhedar
  • 3,480
  • 1
  • 21
  • 44