简体   繁体   English

无法将文本从单独的类追加到JTextArea-Java

[英]Unable to append text from a separate class to a JTextArea - Java

I'm currently having trouble (as the title states) appending text to a JTextArea from a separate class (or thread). 我目前遇到麻烦(如标题所述),将文本从单独的类(或线程)追加到JTextArea。

Here is my code, since I don't know what's causing the problem. 这是我的代码,因为我不知道是什么引起了问题。 (note that I'm using the Netbeans generated code for my GUI): (请注意,我正在使用Netbeans为我的GUI生成的代码):

Chat Box GUI: 聊天框GUI:

public class ChatBoxGUI extends javax.swing.JFrame
{
/**
 * Creates new form ChatBoxGUI
 * @return 
 */
public javax.swing.JTextArea getTextArea() 
{
    return inputOutputTextArea; 
}

public void setLabels(java.net.SocketAddress address, int port) {
    this.addressLabel.setText("IP Address: " +address);
    this.portLabel.setText("Port: " +Integer.toString(port)); 
}

public ChatBoxGUI() {
    initComponents();
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    startServerButton = new javax.swing.JButton();
    connectServerButton = new javax.swing.JButton();
    jLabel1 = new javax.swing.JLabel();
    addressLabel = new javax.swing.JLabel();
    portLabel = new javax.swing.JLabel();
    outputTextField = new javax.swing.JTextField();
    stopButton = new javax.swing.JButton();
    jScrollPane2 = new javax.swing.JScrollPane();
    inputOutputTextArea = new javax.swing.JTextArea();

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 100, Short.MAX_VALUE)
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 100, Short.MAX_VALUE)
    );

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    startServerButton.setText("Start Server");
    startServerButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            startServerButtonActionPerformed(evt);
        }
    });

    connectServerButton.setText("Connect to Server");
    connectServerButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            connectServerButtonActionPerformed(evt);
        }
    });

    jLabel1.setFont(new java.awt.Font("Lucida Grande", 1, 14)); // NOI18N
    jLabel1.setText("Isaac's Chat Box");

    addressLabel.setText("IP Address:");

    portLabel.setText("Port: ");

    stopButton.setText("Stop");
    stopButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            stopButtonActionPerformed(evt);
        }
    });

    inputOutputTextArea.setEditable(false);
    inputOutputTextArea.setColumns(20);
    inputOutputTextArea.setRows(5);
    jScrollPane2.setViewportView(inputOutputTextArea);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addComponent(jScrollPane2)
                .addComponent(outputTextField, javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(startServerButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(connectServerButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jLabel1)
                        .addComponent(addressLabel))
                    .addGap(18, 18, 18)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(stopButton)
                        .addGroup(layout.createSequentialGroup()
                            .addGap(6, 6, 6)
                            .addComponent(portLabel)))
                    .addGap(0, 18, Short.MAX_VALUE)))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(startServerButton)
                .addComponent(jLabel1)
                .addComponent(stopButton))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(connectServerButton)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addressLabel)
                    .addComponent(portLabel)))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(outputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap())
    );

    pack();
}// </editor-fold>                        

private void startServerButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                  
    CreateServerDialog createServerDialog = new CreateServerDialog(this, true);
    createServerDialog.setVisible(true);

    try {
        Runnable serverClassRunnable = new ServerClass(createServerDialog.getPort()); 
        Thread serverClassThread = new Thread(serverClassRunnable);
        serverClassThread.start();
    } catch (java.io.IOException e) {
        e.printStackTrace(); 
    }
}                                                 

private void connectServerButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                    

}                                                   

private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           

}                                          

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(ChatBoxGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(ChatBoxGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(ChatBoxGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(ChatBoxGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new ChatBoxGUI().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JLabel addressLabel;
private javax.swing.JButton connectServerButton;
private javax.swing.JTextArea inputOutputTextArea;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextField outputTextField;
private javax.swing.JLabel portLabel;
private javax.swing.JButton startServerButton;
private javax.swing.JButton stopButton;
// End of variables declaration                   
}

Create Server Dialog: 创建服务器对话框:

public class CreateServerDialog extends javax.swing.JDialog {

private int port; private boolean isValid = false; private java.awt.Frame parent; 

public int getPort() {
    return port; 
}
/**
 * Creates new form CreateServerDialog
 */
public CreateServerDialog(java.awt.Frame par, boolean modal) {
    super(par, modal);
    parent = par; 
    initComponents();
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    portInput = new javax.swing.JTextField();
    okButton = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

    jLabel1.setText("Enter Port:");

    okButton.setText("Ok");
    okButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            okButtonActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addComponent(okButton)
            .addGap(0, 0, Short.MAX_VALUE))
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(portInput)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(jLabel1)
                    .addGap(0, 0, Short.MAX_VALUE)))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jLabel1)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(portInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(okButton))
    );

    pack();
}// </editor-fold>                        

private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {                                         
    ErrorDialog errorDialog = new ErrorDialog(parent, true);

    try {
        port = Integer.parseInt(this.portInput.getText()); 
        isValid = true; 
    } catch (NumberFormatException n) {
        errorDialog.errorOccured(0); 
        isValid = false; 
    }

    if (port <= 1024 || port > 65535) {
        errorDialog.errorOccured(0);
        isValid = false; 
    }

    if (isValid == true) {
       this.dispose();
    }
}                                        

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(CreateServerDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(CreateServerDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(CreateServerDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(CreateServerDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the dialog */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            CreateServerDialog dialog = new CreateServerDialog(new javax.swing.JFrame(), true);
            dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    System.exit(0);
                }
            });
            dialog.setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JLabel jLabel1;
private javax.swing.JButton okButton;
private javax.swing.JTextField portInput;
// End of variables declaration                   
}

Server Class: 服务器类别:

import java.io.*;
import java.net.*;

public class ServerClass implements Runnable
{
private final ServerSocket serverSocket; 

public ServerClass(int port) throws IOException
{
    serverSocket = new ServerSocket(port); 
}

public void run() 
{
    ChatBoxGUI chatBoxGUI = new ChatBoxGUI();  
    try {
        chatBoxGUI.getTextArea().append("\nSearching for client connection. \nPort: " +serverSocket.getLocalPort()); //this is the code that isn't working

        Socket server = serverSocket.accept(); 

        System.out.println();

        chatBoxGUI.setLabels(server.getLocalSocketAddress(), serverSocket.getLocalPort()); //this also isn't working - but that's not the focus of this question

        DataOutputStream out = new DataOutputStream(server.getOutputStream());
        DataInputStream in = new DataInputStream(server.getInputStream());

        chatBoxGUI.getTextArea().append("\nClient found! Connected with: " +server.getRemoteSocketAddress()); 

        //note: this part isn't finished - but it doesn't need to be for that code to work
    } catch (IOException e) {
        e.printStackTrace(); 
    }
}

}

I've tried to do research on the problem, and what I've found tells me that I have to use either invokeLater or invokeAndWait when running the code so that it runs in the EDT. 我已经尝试对这个问题进行研究,发现的发现告诉我,在运行代码时必须使用invokeLater或invokeAndWait才能使其在EDT中运行。 And I have tried to implement this but it still doesn't seem to work: 而且我已经尝试实现了这一点,但它似乎仍然不起作用:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                chatBoxGUI.getTextArea().append("\nSearching for client connection. \nPort: " +serverSocket.getLocalPort());
            }
});

Similar output to the terminal works completely fine, so it's definitely an issue with appending the text. 与终端的类似输出完全可以正常工作,因此添加文本绝对是一个问题。

Any help would be appreciated, and thanks in advance. 任何帮助将不胜感激,并在此先感谢。

You have multiple instances of the ChatBoxGUI class, so you are not updating the text area that is visible on the desktop. 您具有ChatBoxGUI类的多个实例,因此您不会更新在桌面上可见的文本区域。

So first you create the ChatBoxGUI class. 因此,首先创建ChatBoxGUI类。 Then when you click on a button you create the ServerClass . 然后,当您单击按钮时,将创建ServerClass In the ServerClass you create a second instance of the ChatBoxGUI. 在ServerClass中,创建ChatBoxGUI的第二个实例。

Don't create the second instance of the ChatBoxGUI class!!! 不要创建ChatBoxGUI类的第二个实例!!!

Instead, if you want to access variables in the ChatBoxGUI class then you need to: 相反,如果要访问ChatBoxGUI类中的变量,则需要:

  1. pass a reference of the ChatBoxGUI class to the ServerClass 将ChatBoxGUI类的引用传递给ServerClass
  2. save this reference as an instance variable in the ServerClass 将此引用另存为ServerClass中的实例变量
  3. access this variable when you want to add text to the text area. 要将文本添加到文本区域时,请访问此变量。

Without a more complete example, all I can do is link you to this question that has an answer for a similar issue. 如果没有更完整的示例,我所能做的就是将您链接到这个问题该问题可以为类似的问题提供答案。

Or you could try changing your approach from: 或者,您可以尝试从以下方法更改方法:

public javax.swing.JTextArea getTextArea() 
{
     return inputOutputTextArea; 
}

To: 至:

public void setTextArea(String textToAppend) 
{
    inputOutputTextArea.append(textToAppend); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM