在Applet中动态地将字符串从非主线程更新为Main

时间:2014-02-17 12:51:58

标签: java applet

我有一个像下面这样的Applet代码。我在这个Applet中有一个名为String randomNumberStr的字符串,用于显示从套接字服务器检索的随机数。 显示Applet窗口后,我有一个名为“Connect”的按钮。单击此按钮将与Socket程序连接并获取随机数字符串。

我的问题是,我在这个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;
    }

}

3 个答案:

答案 0 :(得分:0)

要比较java中的对象,请使用.equals()方法而不是“==”运算符

替换以下代码

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

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

答案 1 :(得分:0)

字符串在java中是不可变的。如果更改SocketConnectionThread中的字符串,则更新将不会在主线程中明显。您可以尝试使用AtomicReference包装字符串。这样您就可以更改SocketConnectionThread中的值,主线程将始终看到正确的值。

更好的解决方案是将SocketConnectionThread代码移至SwingWorker。您将在doInBackground()方法中读取套接字并使用done()方法更新GUI。

答案 2 :(得分: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

}