2014-02-17 19 views
2

我有一個Applet代碼,如下所示。我在這個小程序中有一個名爲String randomNumberStr的字符串,用於顯示從套接字服務器檢索到的隨機數。 顯示Applet窗口後,我有一個名爲「Connect」的按鈕。點擊這個按鈕將連接到Socket程序並獲得一個隨機數字符串。從非主線程更新字符串到主動態在Applet中

我的問題是,我在這個Applet中運行套接字連接代碼在一個單獨的線程SocketConnectionThread,但是,String randomNumberStrrepaint函數在主線程中。

如何訪問並將此線程的隨機數值SocketConnectionThread傳遞給main並重新繪製Applet窗口?

public class CobrowseApplet extends Applet implements ActionListener 
{ 
    private static final long serialVersionUID = 1L; 
    String titleStr ; 
    String randomNumberStr; 
    Image sharedImage; 
    BufferedImage image; 
    private Button connectBtn; 
    Socket localSocket; 
    PrintWriter out; 
    BufferedReader in; 
    static Timer timer; 
    int delay = 1000; 
    int period = 1000; 
    DataInputStream inStream; 
    PrintStream outStream; 
    InputStream input; 

    public void init(){ 
     titleStr = "Welcome"; 
     randomNumberStr = ""; 

     connectBtn = new Button("Connect"); 

     connectBtn.addActionListener(this); 
     add(connectBtn); 
     connectBtn.setBounds(200, 50, 90, 20); 
     connectBtn.setEnabled(true); 
     setLayout(null); 

     setSize(550, 650); 
    } 
    public void paint (final Graphics g) 
    { 
     //super.paint(g); 
     int x = getSize().width; 
     int c1 = x/2; 
     g.drawString(titleStr, c1-100, 20); 
     g.drawString(randomNumberStr, c1-100, 80); 
     System.out.println("sharedImage" + sharedImage); 
     //g.drawImage(sharedImage, 100, 100, this); 
     System.out.println("drawImage"); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     Thread thr = new Thread(new SocketConnectionThread(randomNumberStr)); 
     thr.start(); 


     if (connectBtn.getLabel()=="Connect") 
     { 
      connectBtn.setLabel(""); 
      connectBtn.setLabel("Disconnect"); 
     } 
     else 
     { 
      connectBtn.setLabel(""); 
      connectBtn.setLabel("Connect"); 
     } 
     System.out.println("randomNumberStr: " + randomNumberStr); 

     repaint(); 
    } 

} 

class SocketConnectionThread implements Runnable { 

    String randomStr; 

    public SocketConnectionThread(String randomNumberStr) { 
     this.randomStr = randomNumberStr; 
    } 
    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     try { 
      System.out.println("Before Applet socket connection"); 

      Socket localSocket = new Socket(getLocalIP(), 8080); 

      BufferedReader socketReader = new BufferedReader(new InputStreamReader(localSocket.getInputStream())); 
      String msgStr = socketReader.readLine(); 
      System.out.println("Server Message on Client: " + msgStr); 

      // IT GETS THE NEW STRING HERE FROM SOCKET. HOW CAN I PUSH TO MAIN? 
      randomStr = msgStr; 

     } catch (UnknownHostException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
    String getLocalIP() { 
     InetAddress inetAddress = null; 
     String ipAddress = null; 
     try { 
      inetAddress = InetAddress.getLocalHost(); 
      ipAddress = inetAddress.getHostAddress(); 
     } catch (UnknownHostException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("ipAddress : " + ipAddress); 

     return ipAddress; 
    } 

} 
+0

您可以用[觀察者模式]嘗試(http://en.wikipedia.org/wiki/Observer_pattern)。 –

+0

1)爲什麼要編寫一個applet?如果這是由於規格。由老師,請參考[爲什麼CS老師應該停止教Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/)。 2)爲什麼選擇AWT而不是Swing?看到我對[Swing extras over AWT]的回答(http://stackoverflow.com/a/6255978/418556)有很多很好的理由放棄使用AWT組件。 –

回答

0

爲了比較在java中使用.equals()對象方法,而不是 「==」 操作者

更換以下代碼

if (connectBtn.getLabel()=="Connect") 

if ("Connect".equals.(connectBtn.getLabel())) 
0

字符串是在Java中不可變。如果更改SocketConnectionThread中的字符串,主線程中將不會顯示更新。你可以嘗試用AtomicReference來包裝你的字符串。這樣,您可以更改SocketConnectionThread中的值,並且主線程始終會看到正確的值。

更好的解決方案是將SocketConnectionThread代碼轉換爲SwingWorker。您將讀取doInBackground()方法中的套接字並更新done()方法中的GUI。

+0

我還需要從套接字獲取圖像數據並在主線程drawImage中更新。因此,請指出,在主線程(重繪窗口)中,從Socket線程訪問「String」和「Byte data」的最簡單方法是什麼?我不知道如何在我的情況下使用AtomicReference。 – Stella

+0

我會使用SwingWorker。看看這個較舊的教程:http://www.oracle.com/technetwork/articles/javase/swingworker-137249.html#ImageRetriever – Kojotak

+0

哦,我需要一個Applet來擴展,我必須使用一個Applet。 – Stella

0

您可以用觀測器模式試試吧:

public class CobrowseApplet extends Applet implements ActionListener, Observer { 

    @Override 
    public void update(Observable obs, Object obj) { 
     String randomNumberStr = String.valueOf(obj); 
     System.out.println("randomNumberStr: " + randomNumberStr); 
     repaint(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     SocketConnectionThread sct = new SocketConnectionThread(randomNumberStr); 
     Thread thr = new Thread(sct); 
     sct.addObserver(this); 
     thr.start(); 
     // ... 
    } 

    // your code here 

} 

class SocketConnectionThread extends Observable implements Runnable { 

    List<Observer> observer; 

    public SocketConnectionThread(String randomNumberStr) { 
     this.randomStr = randomNumberStr; 
     observer = new LinkedList<Observer>(); 
    } 

    public void addObserver(Observer obs) { 
     observer.add(obs); 
    } 

    @Override 
    public void run() { 
     // ... 
     randomStr = msgStr; 
     notifyObservers(randomStr); 
     // ... 
    } 

    // your code here 

} 
相關問題