如何从helper类向JTextField发送String?

时间:2012-05-27 13:30:23

标签: java swing concurrency jtextfield

例如在下面的代码中,我想更改JTextField以显示端口im扫描是否打开,但我不知道该怎么做。也许我需要一些辅助方法?

public void actionPerformed(ActionEvent arg0) {
  console.setText("Starting check\n" +
    "Start = "+stopServTf.getText()+
    "\nStop ="+stopServTf.getText()+
    "\nPort Start ="+startPortTf.getText()+
    "\nPort Stop ="+stopPortTf.getText());
  PortScanner p= new PortScanner(Integer.parseInt(startPortTf.getText()),
    Integer.parseInt(stopPortTf.getText()),startServTf.getText());
}

和另一个方法/构造函数

public   PortScanner(int portStart, int portStop ,String ip) {
  for (int i = portStart; i <= portStop; i++) {
    try {
      Socket ServerSok = new Socket(ip, i);
      setString(i);
      //System.out.println("Port in use: " + i);
      ServerSok.close();
    } catch (Exception e) {
    }
    setStrinN(i);
    System.out.println("Port not in use: " + i);
  }
}

public static String setString(int i) {
  return "Port in use: " +i;
}

public static String setStrinN(int i){
  return "Port not in use: "+i;
} 

所以我想发送到console.setText();

3 个答案:

答案 0 :(得分:4)

建议:

  • 确保在Swing GUI的后台线程中进行端口扫描,例如SwingWorker提供的端口。
  • 更新任何Swing组件时,请务必在Swing事件线程EDT上执行此操作。同样,SwingWorker将提供帮助,因为它具有自动执行此功能的设施(发布/处理)。
  • 为您的GUI类提供一个公共方法,允许外部类更新其文本字段,例如public void consoleSetText(String text)
  • 将对GUI类的引用传递给helper类,以便helper类可以调用上述方法。它当然会使用SwingWorker process(...)方法在Swing事件线程上调用该方法。

编辑1
这是我的建议的一个例子:

class PortScannerGui {
   private JTextField startPortTf;
   private JTextField stopPortTf;
   private JTextField console;
   private JTextField stopServTf;
   private JTextField startServTf;

   // ... lots of code mising

   public void actionPerformed(ActionEvent arg0) {
      console.setText("Starting check\n" + "Start = " + stopServTf.getText()
            + "\nStop =" + stopServTf.getText() + "\nPort Start ="
            + startPortTf.getText() + "\nPort Stop =" + stopPortTf.getText());

      new SwingWorkerPortScannerWrapper(this, 
            Integer.parseInt(startPortTf.getText()), 
            Integer.parseInt(stopPortTf.getText()),
            startServTf.getText()).execute();
   }

   public void setConsoleText(String text) {
      console.setText(text);
   }
}

class SwingWorkerPortScannerWrapper extends SwingWorker<Void, Integer> {
   private PortScannerGui gui;
   private PortScanner portScanner;

   public SwingWorkerPortScannerWrapper(PortScannerGui gui, int portStart,
         int portStop, String ip) {
      this.gui = gui;
      portScanner = new PortScanner(portStart, portStop, ip);
   }

   @Override
   protected Void doInBackground() throws Exception {
      portScanner.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent evt) {
            if (PortScanner.PORT_IN_USE_NUMBER.equals(evt.getPropertyName())) {
               publish((Integer) evt.getNewValue());
            }
         }
      });

      portScanner.scan();
      return null;
   }

   @Override
   protected void process(List<Integer> chunks) {
      for (Integer chunk : chunks) {
         gui.setConsoleText("Port in use: " + chunk);
      }
   }
}

class PortScanner {
   public static final String PORT_IN_USE_NUMBER = "port in use number";
   public static final String STRIN_N = "strinN";
   private int portStart;
   private int portStop;
   private String ip;
   private int string;
   private PropertyChangeSupport propChangeSupport = new SwingPropertyChangeSupport(
         this);
   private int portInUseNumber;

   public PortScanner(int portStart, int portStop, String ip) {
      this.portStart = portStart;
      this.portStop = portStop;
      this.ip = ip;

   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      propChangeSupport.addPropertyChangeListener(listener);
   }

   public void scan() {
      for (int i = portStart; i <= portStop; i++) {
         try {
            Socket ServerSok = new Socket(ip, i);

            setPortInUseNumber(i);
            // System.out.println("Port in use: " + i);

            ServerSok.close();
         } catch (UnknownHostException e) {
            e.printStackTrace();
         } catch (IOException e) {
            e.printStackTrace();
         }
         setStrinN(i);
         System.out.println("Port not in use: " + i);
      }
   }

   public void setStrinN(int i) {
      // TODO do something with this?
   }

   public void setPortInUseNumber(int i) {
      int oldValue = portInUseNumber;
      int newValue = i;
      portInUseNumber = i;
      propChangeSupport.firePropertyChange(PORT_IN_USE_NUMBER, oldValue,
            newValue);
   }

}

答案 1 :(得分:2)

您需要能够访问JTextField实例,有两种方法:

  • 将变量作为局部变量传递给PortScanner
  • 对包含文本字段(或文本字段本身)的框架进行静态引用,以便您可以从任何地方访问它

第一种方式更正确,因为它保持封装,第二种方式更容易和简单,但是当不需要如此严重时,也将字段暴露给外部,这在OOP环境中是一个糟糕的设计选择。

答案 2 :(得分:1)

当您调用setString(i);时,该函数返回您丢弃的字符串(即不存储在任何地方)。你需要存储字符串并在以后检索它,如果你想用返回的字符串调用console.setText(),你需要将console传递给PortScanner构造函数:

public PortScanner(int portStart, int portStop, String ip, JTextArea console)

并将呼叫更改为setString(i);

console.setText(setString(i));

此外(由于PortScanner构造函数已更改),请调用

 PortScanner p= new PortScanner(Integer.parseInt(startPortTf.getText()),
   Integer.parseInt(stopPortTf.getText()),startServTf.getText()); 
actionPerformed()

中的