1

我有两个基本问题。

  • 我有一个带有 Java Swing 的 GUI 项目。当我将按钮放在框架上并双击它们时,我有 的代码actionPerformed,但它被阻止了。

    我怎样才能放一个按钮,然后在一个按钮上使用它actionListener

  • 我的项目是关于服务器客户端(多线程和套接字)

    我调用一种方法来接收一个我们可以在 JtextField 上写入的字符串,它会在 PrintWriter 和 getOutputStream 上停留一段时间。

    就像是:


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

所以..当我写东西并按下按钮发送它时,它会停留在 cicle 和按钮块上。如何解锁按钮以编写其他内容?
编辑:
我了解 EDT 问题,但我无法解决。

我尝试使用 Timer 但没有成功,如下所示:

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

当我按下按钮时,如何处理这个来做计时器?

每当一个用户在文本字段中输入内容时,我如何才能留在那个 cicle(阅读评论行)以通过 OutputStream 发送信息?我知道,例如对于控制台应用程序,我使用 BufferedReader,然后使用 ReadLine() 等待从控制台发送的任何内容,但使用 GUI 界面时,它会一直冻结。

4

2 回答 2

3

Java GUI 开发中有一个基本概念,即开发人员在哪个线程中实现用户交互处理,例如按钮单击。

简而言之,您需要在调用您的操作处理方法的线程之外执行您的处理。这个单线程称为事件调度线程 (EDT),如果您的逻辑运行时间超过几毫秒,它将阻止 UI 继续绘制按钮释放等内容。

您需要将长时间运行的套接字代码移出 EDT。这样做将允许按钮释放并让用户与其他控件(甚至同一个按钮)进行交互。

为避免重复有关该主题的其他讨论,我将您引向这个相当不错的讨论。此外,本文简要概述了 Swing 中的线程概念。

问候,

斯科特

于 2012-12-15T20:18:21.223 回答
3

根据您的评论,您在那里有一些命名问题。你需要一个ActionListener像这样实现 -interface 的类:class YourListenerClass implements ActionListener,但你也可以通过一个匿名类来做到这一点,比如 new ActionListener { public void actionPerformed(ActionEvent e) { //your code for your button here } }); 当你设置你的ActionListener.
关键是您需要以正确的方式命名您的方法。它必须是 public void actionPerformed(ActionEvent e)并且你肯定必须实现ActionListener-interface。接下来是您必须在按钮中注册您的侦听器,例如:

yourButton.addActionListener(new YourListenerClass);

或者像我之前向你展示的那样插入一个匿名类。

第二件事听起来像是我在评论中提到的多线程问题。我没有关注 scott 的链接,但根据他的描述,这可能是您想要阅读以解决任何进一步的阻塞问题的来源。
编辑: 嗯,起初我不想解释它,因为它是一大块代码,但由于问题仍然存在,我想SwingWorker在我的答案中添加一些关于 s 的内容。
如果您有长时间运行的代码,则使用 a 将无济于事,Timer因为它调用的代码也将在 EDT 上,因为它是由事件触发的。
取而代之的是,您可以使用 aSwingWorker来解决此问题。不过,这需要一些额外的代码。这是您可以遵循的简单方法:

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

}

如果您想了解更多关于这些工人的信息......有几个线程处理它,例如这个

于 2012-12-15T20:42:53.653 回答