在GUI类之外附加到JTextArea的麻烦

时间:2014-09-17 13:54:18

标签: java append client chat jtextfield

我试图从GUI类外部更改我的JTextArea文本。我想我知道我应该怎么做,它只是没有用。

我声明并初始化JTextArea,如下所示:

JTextArea typeField = new JTextArea();

然后我在我的GUI类中有这个方法(当然在构造函数之外):

public void setText(String text){
    typeField.append(text);
}

我在这里读到另一个帖子,这就是你应该怎么做的。但是编译器并不赞同这一点,并且说" typeField无法解析"在我使用append方法的行上。我认为我想要完成的事情非常简单,我真的不明白为什么这样做不起作用。也许我做了一些愚蠢的错误?如果是这样,我找不到它。

提前致谢。

编辑:无论如何我都会在这里发布我的代码,希望有人能够帮助我! 所以我想要做的就是实现聊天程序的客户端部分。我有两个部分。聊天客户端部分和GUI部分。

聊天部分:

package chat;

import java.io.\*;
import java.net.\*;
import javax.swing.\*;
import java.awt.\*;
import java.awt.event.\*;

public class ChatClient{
  public static void main(String [] args) throws IOException {

    //ChatWindow chatWindow = new ChatWindow();

    //Default values.
    String host = "127.0.0.1";
    int port = 2000;

    //If the user starts the program with "java ChatClient <host>"
    if (args.length == 1) {
        host = args[0]; //Catches the first parameter.                
    }

    //If the user starts the program with "java ChatClient <host> <port>"
    else if (args.length == 2) {
        host = args[0]; //Catches the first parameter.
        port = Integer.parseInt(args[1]); //Catches the second parameter.
    }

    //If the user sends too many parameters.
    else if (args.length > 2) {
        System.out.println("You have sent too many parameters.");
        System.exit(1);
    }

    //Sets the host and port as the titel of the window.
    //chatWindow.setWindowTitle(host + " " + port);

    try (   
        Socket socket = new Socket(host, port);

        PrintWriter out = 
            new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = 
            new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
        BufferedReader stdIn =
            new BufferedReader(
                new InputStreamReader(System.in))
    ) {
        String userInput;
        while ((userInput = stdIn.readLine()) != null) {
            out.println(userInput);
            System.out.println("Server: " + in.readLine());
        }
    } catch (UnknownHostException e) {
        System.err.println("Couldn't not find host " + host);
        System.exit(1);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to " + host);
        System.exit(1);
    }
}
}

GUI部分(这两个类在同一个文件中定义,所以我不需要重复导入的库):

class ChatWindow extends JFrame {
public ChatWindow () {
    setLayout(new BorderLayout());

    //A JPanel containing the "message board";
    JPanel messageBoard = new JPanel(new FlowLayout());

    //A JTextArea showing all the messages.
    JTextArea messageField =  new JTextArea();
    messageField.setPreferredSize(new Dimension(470, 300));
    messageField.setMargin(new Insets(10, 10, 10, 10));
    messageBoard.add(messageField);
    add(messageBoard, BorderLayout.NORTH);

    //A JPanel containing the TextField where the user writes his messages as well as the button to send these messages
    JPanel typeBoard = new JPanel(new FlowLayout());

    //A JTextArea where the user writes his messages.
    JTextArea typeField = new JTextArea();
    typeField.setPreferredSize(new Dimension(350, 100));
    typeField.setMargin(new Insets(10, 10, 10, 10));
    typeBoard.add(typeField);

    //A button used to send a message.
    JButton sendButton = new JButton("Send");
    sendButton.setPreferredSize(new Dimension(100, 100));
    typeBoard.add(sendButton);

    add(typeBoard, BorderLayout.SOUTH);

    setSize(500, 470);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);        
}

public void setText (String text) {
    messageField.append("\n" + text);
}

public void setWindowTitle (String title) {
    setTitle(title);
}
}

class SendButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent e){
        //Not implemented yet
    }
}

2 个答案:

答案 0 :(得分:0)

我不确定,但你可以试试这个:

public synchronized void setText(String text){
    typeField.append(text);
}

synchronized将同步两个线程。 您可以在此处阅读更多内容:Docs Oracle

答案 1 :(得分:0)

好的,这个问题的答案结果非常简单。它就是这样的:

由于我在构造函数中声明并初始化变量messageField,因此它不存在于构造函数之外。因此,当我尝试在构造函数之外使用该变量的值时 - 在我的setText(String text) - 方法中,它显然无法正常工作。

我需要做的是在构造函数之外声明该变量,如下所示:

class ChatWindow extends JFrame {
JTextArea messageField; //This line does the trick!

public ChatWindow () {
    setLayout(new BorderLayout());

    //A JPanel containing the "message board";
    JPanel messageBoard = new JPanel(new FlowLayout());

    //A JTextArea showing all the messages.
    messageField =  new JTextArea();
    messageField.setPreferredSize(new Dimension(470, 300));
    messageField.setMargin(new Insets(10, 10, 10, 10));
    messageBoard.add(messageField);
    add(messageBoard, BorderLayout.NORTH);

    //A JPanel containing the TextField where the user writes his messages as well as the button to send these messages
    JPanel typeBoard = new JPanel(new FlowLayout());

    //A JTextArea where the user writes his messages.
    JTextArea typeField = new JTextArea();
    typeField.setPreferredSize(new Dimension(350, 100));
    typeField.setMargin(new Insets(10, 10, 10, 10));
    typeBoard.add(typeField);

    //A button used to send a message.
    JButton sendButton = new JButton("Send");
    sendButton.setPreferredSize(new Dimension(100, 100));
    typeBoard.add(sendButton);

    add(typeBoard, BorderLayout.SOUTH);

    setSize(500, 470);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);        
 }