为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕码人2483693 2023-08-04 15:48:23
我正在尝试实现一个 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;                }        }            }}        );为什么当我单击按钮时它只显示“连接”?
查看完整描述

2 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

现在,您的代码的基本轮廓是


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")

}


查看完整回答
反对 回复 2023-08-04
?
DIEA

TA贡献1820条经验 获得超2个赞

这个“基本”问题是,连接时,您将按钮文本设置为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放置一个“模拟”操作。我会考虑通过工作人员对套接字进行所有读/写操作,并使其保持活动状态,直到套接字关闭(无论出于何种原因)。但是,这将演示如何不根据单击的状态,而是根据工作人员本身的状态来更新按钮。



查看完整回答
反对 回复 2023-08-04
  • 2 回答
  • 0 关注
  • 114 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信