使用另一个类的 JFrame

2022-01-24 00:00:00 java swing jframe

您好,我在尝试将一些文本从同一个包中的另一个类附加到 JTextArea 时遇到了一个小问题.下面是属于 JFrame 的主要类:

Hi I'm small a little issue trying to append some text to a JTextArea from another class within the same package. Below is the main class that pertains to the JFrame:

  public class Client extends JFrame{

        //Static variables
        private static final String host = "localhost";
        private static final int portNumber = 4444;

        //Variables
        private String userName;

        //JFrame Variables
        private JPanel contentPanel;
        private JTabbedPane panel_Social;
        private JPanel jpanel_Social;
        private JPanel jpanel_Chat;
        private JTextArea textArea_Receive;
        private JTextField textField_Send;
        private JTextArea textArea_ClientList;
        private JButton btn_Enter;


        public JTextArea getTextArea_Receive(){
            return this.textArea_Receive;
        }

        //Constructor
        private Client(String userName, String host, int portNumber){
            this.userName = userName;
            this.serverHost = host;
            this.serverPort = portNumber;
        }

        public void main(String args[]){
            //Requests user to enter name
            String readName = null;
            Scanner scan = new Scanner(System.in);
            System.out.println("Please enter username");
            readName = scan.nextLine();

            //Start client
            Client client = new Client(readName, host, portNumber);
            client.startClient(scan);
        }

        private void startClient(Scanner scan){
            try{
                //Create new socket and wait for network communication
                Socket socket = new Socket(serverHost, serverPort);
                Thread.sleep(1000);

                //Create thread and start it
                serverThread = new ServerThread(socket, userName);
                Thread serverAccessThread = new Thread(serverThread);
                serverAccessThread.start();
            }
        }
    }


Below is the serverThread class

    public class ServerThread implements Runnable{

        private Socket socket;
        private String userName;
        private boolean isAlived;
        private final LinkedList<String> messagesToSend;
        private boolean hasMessages = false;

        //Constructor
        ServerThread(Socket socket,  String userName){
            this.socket = socket;
            this.userName = userName;
            messagesToSend = new LinkedList<String>();
        }

        public void run(){   
            try{
                Client test1 = new Client();
                JTextArea test2 = test1.getTextArea_Receive();
                String test3 = "Hello World";
                test2.append(test3);
            } catch (IOException e){
}
    }

我包含测试变量只是为了轻松地重新创建问题,但是每当运行 append 函数时,jFrame 的文本区域中不会出现任何内容.在我的场景中,我让客户端从服务器接收文本,然后将其附加到文本框中.

I included test variables just to easily recreate the issue but whenever the append function is run nothing appears in the text area of the jFrame. In my scenario I'm having the client receive text from a server then append it to the text box.

顺便说一句,我正在为 JFrame 使用 IntelliJ GUI 设计器.我只包含了重新创建问题所需的代码.我仍在尝试创建 MCVE 问题,因此请随时告诉我我犯的错误.

BTW I'm using the IntelliJ GUI designer for the JFrame. I've only included code needed to recreate the problem. I'm still trying to create MCVE questions so feel free to let me know mistakes I made.

推荐答案

您应该通过构造函数将 Client 传递给 ServerThread.您在 run() 中实例化的 Client 与您在 main() 中创建的 Client 引用不同>.所以你的 ServerThread 类将类似于

You should pass Client into ServerThread via the constructor. The Client you are instantiating within run() is not the same reference to the Client you created in main(). So your ServerThread class would be something like

ServerThread(Client client, Socket socket,  String userName) {
    this.client = client;
    this.socket = socket;
    this.userName = userName;
    messagesToSend = new LinkedList<String>();
}

public void run() {
    try
    {
        JTextArea test2 = this.client.getTextArea_Receive();
        String test3 = "Hello World";
        test2.append(test3);
    } 
    catch (IOException e)
    {}
}

您的 startClient() 方法将更新为类似的内容

Your startClient() method would be updated to something like this

private void startClient(Client client, Scanner scan)
{
    try
    {
        //Create new socket and wait for network communication
        Socket socket = new Socket(serverHost, serverPort);
        Thread.sleep(1000);

        //Create thread and start it
        ServerThread serverThread = new ServerThread(client, socket, userName);
        serverAccessThread.run();
    }
}

<小时>

说了这么多,


All that being said,

我建议将您的 main() 移出 Client 并移到与 Swing UI 代码不那么耦合的类中.像这样的:

I would recommend moving your main() out of Client and into a class that isn't so coupled to the Swing UI code. Something like this:

public class MySwingApplication {

    private static final String host = "localhost";
    private static final int portNumber = 4444;

    public static void main(String[] args) {
        // Requests user to enter name
        // Start client
    }
}

您的 Client 然后构建得更像一个实例对象

Your Client is then built more like an instance object

public class Client extends JFrame {
    public JTextArea getTextArea_Receive(){
        // Return the text area
    }

    // Constructor -- public to allow instantiation from main()
    public Client(String userName, String host, int portNumber) {
        // Do stuff
    }

    private void startClient(Scanner scan) {
        // Show the JFrame on screen
        // Spawn Server
    }
}

相关文章