我有一个像下面这样的Applet代码。我在这个Applet中有一个名为String randomNumberStr
的字符串,用于显示从套接字服务器检索的随机数。
显示Applet窗口后,我有一个名为“Connect”的按钮。单击此按钮将与Socket程序连接并获取随机数字符串。
我的问题是,我在这个Applet中的一个单独的线程SocketConnectionThread
中运行套接字连接代码,但是,String randomNumberStr
和repaint
函数存在于主线程中。
如何访问并将此线程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 :(得分: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
}