如何让 JButton 每次单击时显示 2 种不同的模式?

我正在尝试实现一个 JButton,根据它是否连接到服务器来显示“连接”或“断开连接”。因此,当我单击“连接”按钮时,它将连接到服务器,然后显示“断开连接”。当我单击“断开连接”时,它将与服务器断开连接,并且按钮将再次显示“连接”。但是,当我单击按钮时,什么也没有发生。


        btnConnect.addMouseListener(new MouseAdapter() {

            @Override

            public void mouseClicked(MouseEvent arg0) {


                if (btnConnect.getText().equals("Connect")){

                    btnConnect.setText("Disconnect");


                try {

                    int portNum = 5520;

                    String hostAddress = Actual_IP_Address.getText();

                    sock = new Socket(hostAddress, portNum);

                    writeSock = new PrintWriter ( sock.getOutputStream(), true);

                    readSock = new BufferedReader (new InputStreamReader(sock.getInputStream()));

                }

                catch(Exception ex) {

                    System.out.println("Error: " + ex);

                    sock = null;

                }

                }

                if (btnConnect.getText().equals("Disconnect")){

                    btnConnect.setText("Connect");


                try {

                    readSock.close();

                    writeSock.close();

                    sock.close();

                    sock = null;

                }

                catch(Exception ex) {

                    System.out.println("Error: " + ex);

                    sock = null;

                }


        }

            }}

        );

为什么当我单击按钮时它只显示“连接”?


慕码人2483693
浏览 115回答 2
2回答

呼如林

现在,您的代码的基本轮廓是if (button.getText().equals("Connect"){   button.setText("Disconnect")}if (button.getText().equals("Disconnect"){   button.setText("Connect")}看起来正在发生的事情是您正在将按钮文本值更改为“断开连接”,就像您应该做的那样。但紧接着,您再次检查按钮文本值是否等于“断开连接”并再次更改它。将两个 if 语句更改为 else-if 语句if (button.getText().equals("Connect"){   button.setText("Disconnect")} else if (button.getText().equals("Disconnect"){   button.setText("Connect")}

DIEA

这个“基本”问题是,连接时,您将按钮文本设置为Disconnect,然后立即检查文本是否为Disconnect并将其设置回Connect。更大的问题是你正在耦合你的代码,这将使得管理和保持 UI 与实际发生的事情(如果套接字意外断开会发生什么)同步变得困难。另一个问题是,您可能会阻塞 UI,从而导致它“冻结”并变得无响应,因为套接字可能需要几秒钟才能建立。更好的解决方案是尝试将 UI 与套接字解耦,并依赖某种观察者模式,这样当套接字状态发生变化时,您就可以收到通知,无论 UI 是否停止了套接字,或者由于某些其他条件而停止。就我个人而言,我会为此使用 a SwingWorker,因为它允许您将长时间运行/阻塞操作重载到另一个线程,但提供了许多有用的机制来安全地将更新传递回 UI 线程(即事件调度线程),例如例子...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放置一个“模拟”操作。我会考虑通过工作人员对套接字进行所有读/写操作,并使其保持活动状态,直到套接字关闭(无论出于何种原因)。但是,这将演示如何不根据单击的状态,而是根据工作人员本身的状态来更新按钮。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java