Reputation: 73
I'm currently having trouble (as the title states) appending text to a JTextArea from a separate class (or thread).
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):
Chat Box 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. 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.
Upvotes: 0
Views: 403
Reputation: 324187
You have multiple instances of the ChatBoxGUI class, so you are not updating the text area that is visible on the desktop.
So first you create the ChatBoxGUI class. Then when you click on a button you create the ServerClass
. In the ServerClass you create a second instance of the ChatBoxGUI.
Don't create the second instance of the ChatBoxGUI class!!!
Instead, if you want to access variables in the ChatBoxGUI class then you need to:
Upvotes: 2
Reputation: 446
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);
}
Upvotes: 1