2 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超3個贊
現(xiàn)在,您的代碼的基本輪廓是
if (button.getText().equals("Connect"){
button.setText("Disconnect")
}
if (button.getText().equals("Disconnect"){
button.setText("Connect")
}
看起來正在發(fā)生的事情是您正在將按鈕文本值更改為“斷開連接”,就像您應(yīng)該做的那樣。但緊接著,您再次檢查按鈕文本值是否等于“斷開連接”并再次更改它。將兩個 if 語句更改為 else-if 語句
if (button.getText().equals("Connect"){
button.setText("Disconnect")
} else if (button.getText().equals("Disconnect"){
button.setText("Connect")
}

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超2個贊
這個“基本”問題是,連接時,您將按鈕文本設(shè)置為Disconnect,然后立即檢查文本是否為Disconnect并將其設(shè)置回Connect。
更大的問題是你正在耦合你的代碼,這將使得管理和保持 UI 與實(shí)際發(fā)生的事情(如果套接字意外斷開會發(fā)生什么)同步變得困難。
另一個問題是,您可能會阻塞 UI,從而導(dǎo)致它“凍結(jié)”并變得無響應(yīng),因?yàn)樘捉幼挚赡苄枰獛酌腌姴拍芙ⅰ?/p>
更好的解決方案是嘗試將 UI 與套接字解耦,并依賴某種觀察者模式,這樣當(dāng)套接字狀態(tài)發(fā)生變化時,您就可以收到通知,無論 UI 是否停止了套接字,或者由于某些其他條件而停止。
就我個人而言,我會為此使用 a SwingWorker,因?yàn)樗试S您將長時間運(yùn)行/阻塞操作重載到另一個線程,但提供了許多有用的機(jī)制來安全地將更新傳遞回 UI 線程(即事件調(diào)度線程),例如例子...
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Test {
? ? public static void main(String[] args) {
? ? ? ? new Test();
? ? }
? ? public Test() {
? ? ? ? SwingUtilities.invokeLater(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? JFrame frame = new JFrame();
? ? ? ? ? ? ? ? frame.add(new TestPane());
? ? ? ? ? ? ? ? frame.pack();
? ? ? ? ? ? ? ? frame.setLocationRelativeTo(null);
? ? ? ? ? ? ? ? frame.setVisible(true);
? ? ? ? ? ? }
? ? ? ? });
? ? }
? ? public class TestPane extends JPanel {
? ? ? ? private JButton doStuff;
? ? ? ? private SocketWorker worker;
? ? ? ? public TestPane() {
? ? ? ? ? ? setLayout(new GridBagLayout());
? ? ? ? ? ? doStuff = new JButton("Connect");
? ? ? ? ? ? doStuff.addActionListener(new ActionListener() {
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void actionPerformed(ActionEvent event) {
? ? ? ? ? ? ? ? ? ? if (worker == null) {
? ? ? ? ? ? ? ? ? ? ? ? doStuff.setText("...");
? ? ? ? ? ? ? ? ? ? ? ? worker = new SocketWorker("hostname");
? ? ? ? ? ? ? ? ? ? ? ? worker.addPropertyChangeListener(new PropertyChangeListener() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? ? public void propertyChange(PropertyChangeEvent evt) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ("state".equals(evt.getPropertyName())) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(worker.getState());
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? switch (worker.getState()) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case STARTED:?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? doStuff.setText("Disconnect");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case DONE:?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? worker = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? doStuff.setText("Connect");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? worker.execute();
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? System.out.println("...");
? ? ? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? ? ? worker.stop();
? ? ? ? ? ? ? ? ? ? ? ? } catch (IOException ex) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ex.printStackTrace();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? doStuff.setText("Connect");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? ? ? add(doStuff);
? ? ? ? }
? ? }
? ? public class SocketWorker extends SwingWorker<Void, Void> {
? ? ? ? private Socket socket;
? ? ? ? private String hostName;
? ? ? ? private PrintWriter writeSock;
? ? ? ? private BufferedReader readSock;
? ? ? ? public SocketWorker(String hostName) {
? ? ? ? ? ? this.hostName = hostName;
? ? ? ? }
? ? ? ? @Override
? ? ? ? protected Void doInBackground() throws Exception {
? ? ? ? ? ? // This is just here to demonstrate the point
? ? ? ? ? ? Thread.sleep(5000);
? ? ? ? ? ? //int portNum = 5520;
? ? ? ? ? ? //socket = new Socket(hostName, portNum);
? ? ? ? ? ? //writeSock = new PrintWriter(socket.getOutputStream(), true);
? ? ? ? ? ? //readSock = new BufferedReader(new InputStreamReader(socket.getInputStream()));? ? ? ??
? ? ? ? ? ? // Do your socket handling here...
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? public void stop() throws IOException {
? ? ? ? ? ? if (socket == null) { return; }
? ? ? ? ? ? socket.close();
? ? ? ? }
? ? }
}
在這個例子中,我只是用來Thread.sleep放置一個“模擬”操作。我會考慮通過工作人員對套接字進(jìn)行所有讀/寫操作,并使其保持活動狀態(tài),直到套接字關(guān)閉(無論出于何種原因)。但是,這將演示如何不根據(jù)單擊的狀態(tài),而是根據(jù)工作人員本身的狀態(tài)來更新按鈕。
添加回答
舉報