I want to display an image from the web to a panel in another JFrame at the click of a button. Whenever I click the button, first the image loads; and during this time, the current form potentially freezes. Once the image has loaded, the form is displayed with the image. How can I avoid the situation where my form freezes since it is very irritating. Among my codes:
My current class:
private void btn_TrackbusActionPerformed(java.awt.event.ActionEvent evt) {
try {
sendMessage("Query,map,$,start,211,Arsenal,!");
System.out.println(receiveMessage());
} catch (UnknownHostException ex) {
Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
}
catch (Exception ex) {
Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
}
client_trackedbus nextform=new client_trackedbus(planform,connection,packet_receive,packet_send);
this.setVisible(false);
this.dispose();
nextform.setVisible(true);
// TODO add your handling code here:
}
My next class that displays the image:
public class client_trackedbus extends javax.swing.JFrame {
client_planform planform=null;
DatagramSocket connection=null;
DatagramPacket packet_receive=null;
DatagramPacket packet_send=null;
JLabel label=null;
/** Creates new form client_trackedbus */
public client_trackedbus(client_planform planform,DatagramSocket connection,DatagramPacket packet_receive,DatagramPacket packet_send) {
initComponents();
this.planform=planform;
this.connection=connection;
this.packet_receive=packet_receive;
this.packet_send=packet_send;
try {
displayMap("http://www.huddletogether.com/projects/lightbox2/images/image-2.jpg", jPanel1, new JLabel());
} catch (MalformedURLException ex) {
Logger.getLogger(client_trackedbus.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void displayMap(String url,JPanel panel,JLabel label) throws MalformedURLException{
URL imageurl=new URL(url);
Image image=(Toolkit.getDefaultToolkit().createImage(imageurl));
ImageIcon icon = new ImageIcon(image);
label.setIcon(icon);
panel.add(label);
// System.out.println(panel.getSize().width);
this.getContentPane().add(panel);
}
/** 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();
jLabel1 = new javax.swing.JLabel();
btn_Exit = new javax.swing.JButton();
btn_Plan = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Public Transport Journey Planner");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 368, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 172, Short.MAX_VALUE)
);
jLabel1.setFont(new java.awt.Font("Arial", 1, 18));
jLabel1.setText("Your tracked bus");
btn_Exit.setText("Exit");
btn_Exit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btn_ExitActionPerformed(evt);
}
});
btn_Plan.setText("Plan journey");
btn_Plan.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btn_PlanActionPerformed(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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(104, 104, 104)
.addComponent(jLabel1))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGap(65, 65, 65)
.addComponent(btn_Plan)
.addGap(65, 65, 65)
.addComponent(btn_Exit, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(20, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addComponent(jLabel1)
.addGap(18, 18, 18)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btn_Exit)
.addComponent(btn_Plan))
.addContainerGap(12, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void btn_ExitActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Exitform();
}
private void btn_PlanActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
this.setVisible(false);
this.dispose();
this.planform.setVisible(true);
}
private void Exitform(){
this.setVisible(false);
this.dispose();
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// new client_trackedbus().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton btn_Exit;
private javax.swing.JButton btn_Plan;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
As suggested in the article Concurrency in Swing, your button handler's query may be blocking the event dispatch thread. Using javax.swing.SwingWorker is one approach to loading images in the background, while displaying progress and keeping the GUI thread alive.
Addendum: Here's a sscce that loads the SO logo; it's been updated to handle exceptions and resize the enclosing container to fit the loaded image:
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
/**
* #see http://stackoverflow.com/questions/4530659
*/
public final class WorkerTest extends JFrame {
private final JLabel label = new JLabel("Loading...");
public WorkerTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.BOTTOM);
this.add(label);
this.pack();
this.setLocationRelativeTo(null);
}
private void start() {
new ImageWorker().execute();
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
WorkerTest wt = new WorkerTest();
wt.setVisible(true);
wt.start();
}
});
}
class ImageWorker extends SwingWorker<Image, Void> {
private static final String TEST
= "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png";
#Override
protected Image doInBackground() throws IOException {
Image image = ImageIO.read(new URL(TEST));
return image.getScaledInstance(640, -1, Image.SCALE_SMOOTH);
}
#Override
protected void done() {
try {
ImageIcon icon = new ImageIcon(get());
label.setIcon(icon);
label.setText("Done");
WorkerTest.this.pack();
WorkerTest.this.setLocationRelativeTo(null);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
public class SSBTest extends javax.swing.JFrame {
/** Creates new form worker1 */
public SSBTest() {
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();
jPanel1 = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setText("jLabel1");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 348, Short.MAX_VALUE));
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 210, Short.MAX_VALUE));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap(196, Short.MAX_VALUE).addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE).addGap(178, 178, 178)).addGroup(layout.createSequentialGroup().addGap(86, 86, 86).addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(122, Short.MAX_VALUE)));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 40, Short.MAX_VALUE).addComponent(jLabel1).addGap(36, 36, 36)));
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
final SSBTest ssbTest = new SSBTest();
ssbTest.setVisible(true);
ssbTest.execute();
}
});
}
private void execute() {
(new MeaningOfLifeFinder(jLabel1, jPanel1)).execute();
}
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
class MeaningOfLifeFinder extends SwingWorker<Icon, Object> {
JLabel label = null;
JPanel panel;
MeaningOfLifeFinder(JLabel label, JPanel jpanel) {
this.label = label;
this.panel = jpanel;
}
protected Icon doInBackground() throws IOException {
URL imageurl;
Image image = null;
System.out.println("image loading");
imageurl = new URL("http://maps.google.com/maps/api/staticmap"
+ "?zoom=14&size=512x512&maptype=roadmap"
+ "&markers=color:green|label:21|-15.0,-150.0&sensor=false");
//image = (Toolkit.getDefaultToolkit().createImage(imageurl));
image = ImageIO.read(imageurl);
ImageIcon icon = new ImageIcon(image);
System.out.println("image loaded...");
return icon;
}
#Override
protected void done() {
try {
System.out.println("image adding to label...");
label.setIcon(get());
//panel.add(label);
System.out.println("image loaded to label...");
} catch (Exception ignore) {
}
}
// System.out.println(panel.getSize().width);
}
Related
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.
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:
pass a reference of the ChatBoxGUI class to the ServerClass
save this reference as an instance variable in the ServerClass
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);
}
I am creating new Splash screen in Java (using Netbeans as my IDE).
But the problem is that after reaching 100% by progress bar it is automatically move to 2nd frame and exit the 1st frame which is showing the splash screen. But here 1st screen of splash screen is not exiting.
This is my code
public NewJFrame() {
initComponents();
try {
for (int i=0;i<=100;i++){
Thread.sleep(40);
jLabel1.setText(Integer.toString(i)+"%");
jProgressBar2.setValue(i);
if (i==100)
{
this.setVisible(false);
new NewJFrame1().setVisible(true);
}
}
} catch (Exception e) {
}
}
I once created a simple splash, not to fancy but for me it did the trick.
This is a copy paste from the entire class from netbeans, so you will need to change somethings.
This example you will get a splash with a image and a progress bar bellow.
import javax.swing.SwingUtilities;
public class Splash extends javax.swing.JWindow {
private static final long serialVersionUID = -6711792976773608816L;
/**
* Creates new form Splash
*/
public Splash() {
initComponents();
}
public void splashScreenInit() {
setLocationRelativeTo(null);
setProgressMax(100);
setVisible(true);
}
/**
* 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("all")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
imageLabel = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
imageLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/help/splash.png"))); // NOI18N
getContentPane().add(imageLabel, java.awt.BorderLayout.CENTER);
progressBar.setForeground(new java.awt.Color(51, 85, 112));
progressBar.setStringPainted(true);
getContentPane().add(progressBar, java.awt.BorderLayout.PAGE_END);
pack();
}// </editor-fold>
/**
* Sets the max value for the progressbar
* #param maxProgress
*/
public void setProgressMax(int maxProgress) {
progressBar.setMaximum(maxProgress);
}
public void setProgress(int progress) {
final int theProgress = progress;
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
progressBar.setValue(theProgress);
}
});
}
/**
* Changes the string message and set a new value fro the progressbar
* #param message String the message
* #param progress int the new value of the progressbar. This cant be higher than the value defined in the setProgressMax
*/
public void setProgress(String message, int progress) {
final int theProgress = progress;
final String theMessage = message;
setProgress(progress);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
progressBar.setValue(theProgress);
setMessage(theMessage);
}
});
}
private void setMessage(String message) {
if (message == null) {
message = "";
progressBar.setStringPainted(false);
} else {
progressBar.setStringPainted(true);
}
progressBar.setString(message);
}
// Variables declaration - do not modify
private javax.swing.JLabel imageLabel;
private javax.swing.JProgressBar progressBar;
// End of variables declaration
}
To call
final Splash s = new Splash();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
s.splashScreenInit();
}
});
and in the end
s.setVisible(false);
the following is my code it is working properly in my system.. u can try add import the following in your codes
//import com.sun.awt.AWTUtilities;
//import java.awt.event.ActionEvent;
//import javax.swing.Timer;
//import javax.swing.UIManager;
//import java.awt.event.ActionListener;
//import javax.swing.JProgressBar;
private Timer t;
private ActionListener al;
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
ActionListener a1 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
if(jProgressBar1.getValue()<100)
{
jProgressBar1.setValue(jProgressBar1.getValue()+5);
}
else
{
t.stop();
abcd();
}
}
};
t=new Timer(80, a1);
initComponents();
AWTUtilities.setWindowOpaque(this, false);
t.start();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jProgressBar1 = new javax.swing.JProgressBar();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setUndecorated(true);
jLabel1.setText("jLabel1");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(123, 123, 123)
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 136, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(92, 92, 92)
.addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(141, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(66, 66, 66)
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(41, 41, 41)
.addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(133, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
private void abcd()
{
NewJFrame1 f1= new NewJFrame1();
f1.setLocationRelativeTo(null);
f1.setVisible(true);
this.dispose();
}
How do I wire output to paneWithList?
PaneWithList has a listener on its JList so that the selected row is output to the console. How can I direct that output to the JTextPane on output?
Could PaneWithList fire an event which Main picks up? Would PropertyChangeSupport suffice?
Main.java:
package dur.bounceme.net;
import javax.swing.JTabbedPane;
public class Main {
private static JTabbedPane tabs;
private static PaneWithList paneWithList;
private static PaneWithTable paneWithTable;
private static Output output;
public static void main(String[] args) {
tabs = new javax.swing.JTabbedPane();
paneWithList = new PaneWithList();
paneWithTable = new PaneWithTable();
tabs.addTab("list", paneWithList);
tabs.addTab("table", paneWithTable);
tabs.addTab("output", output);
}
}
Here's an example using the observer pattern, also seen here, here and here. Note that it would also be possible to listen to the combo's model.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
/**
* #see http://en.wikipedia.org/wiki/Observer_pattern
* #see https://stackoverflow.com/a/10523401/230513
*/
public class PropertyChangeDemo {
public PropertyChangeDemo() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.add(new ObserverPanel());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PropertyChangeDemo example = new PropertyChangeDemo();
}
});
}
}
class ObserverPanel extends JPanel {
private JLabel title = new JLabel("Value received: ");
private JLabel label = new JLabel("null", JLabel.CENTER);
public ObserverPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObserverPanel"));
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(title);
panel.add(label);
this.add(panel);
ObservedPanel observed = new ObservedPanel();
observed.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals(ObservedPanel.PHYSICIST)) {
String value = e.getNewValue().toString();
label.setText(value);
}
}
});
this.add(observed);
}
}
class ObservedPanel extends JPanel {
public static final String PHYSICIST = "Physicist";
private static final String[] items = new String[]{
"Alpher", "Bethe", "Gamow", "Dirac", "Einstein"
};
private JComboBox combo = new JComboBox(items);
private String oldValue;
public ObservedPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObservedPanel"));
combo.addActionListener(new ComboBoxListener());
this.add(combo);
}
private class ComboBoxListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
String newValue = (String) combo.getSelectedItem();
firePropertyChange(PHYSICIST, oldValue, newValue);
oldValue = newValue;
}
}
}
I'd be use JMenu with JMenuItems with contents layed by using CardLayout rather than very complicated JTabbedPane(s)
For my own reference, and for anyone using the Netbeans GUI builder, this works so far as it goes:
The PanelWithList class:
package dur.bounceme.net;
public class PanelWithList extends javax.swing.JPanel {
public PanelWithList() {
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() {
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jList1.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jList1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jList1MouseClicked(evt);
}
});
jList1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jList1KeyReleased(evt);
}
});
jScrollPane1.setViewportView(jList1);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane2.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(54, 54, 54)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 308, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(167, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane2)
.addComponent(jScrollPane1))
.addContainerGap(166, Short.MAX_VALUE))
);
}// </editor-fold>
private void jList1MouseClicked(java.awt.event.MouseEvent evt) {
row();
}
private void jList1KeyReleased(java.awt.event.KeyEvent evt) {
row();
}
// Variables declaration - do not modify
private javax.swing.JList jList1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
private void row() {
Object o = jList1.getSelectedValue();
String s = (String)o;
jTextArea1.setText(s);
this.firePropertyChange("list", -1, 1);
}
}
and Frame.java as a driver:
package dur.bounceme.net;
public class Frame extends javax.swing.JFrame {
public Frame() {
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() {
jTabbedPane1 = new javax.swing.JTabbedPane();
panelWithList1 = new dur.bounceme.net.PanelWithList();
panelWithTable1 = new dur.bounceme.net.PanelWithTable();
newJPanel1 = new dur.bounceme.net.PanelWithCombo();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
panelWithList1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
panelWithList1PropertyChange(evt);
}
});
jTabbedPane1.addTab("tab1", panelWithList1);
jTabbedPane1.addTab("tab2", panelWithTable1);
jTabbedPane1.addTab("tab3", newJPanel1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 937, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 913, Short.MAX_VALUE)
.addContainerGap()))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 555, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 521, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(22, Short.MAX_VALUE)))
);
pack();
}// </editor-fold>
private void panelWithList1PropertyChange(java.beans.PropertyChangeEvent evt) {
System.out.println("panelWithList1PropertyChange ");
}
/**
* #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(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Frame.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 Frame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JTabbedPane jTabbedPane1;
private dur.bounceme.net.PanelWithCombo newJPanel1;
private dur.bounceme.net.PanelWithList panelWithList1;
private dur.bounceme.net.PanelWithTable panelWithTable1;
// End of variables declaration
}
The key being that panelWithList1PropertyChange is the listener on 'panelWithList' itself.
Because PanelWithList.firePropertyChange("list", -1, 1); cannot send Object nor String that I see, I'm not exactly sure how to get the value selected all the way from the JList up to the JFrame.
Hmm, well the API says yes it can send Objects. Have to check that out.
I think it's necessary to get some info about the model which the JList is using up to the JFrame. However, doesn't that break MVC? Or maybe that's the wrong approach.
How do I wire output to paneWithList?
PaneWithList has a listener on its JList so that the selected row is output to the console. How can I direct that output to the JTextPane on output?
Could PaneWithList fire an event which Main picks up? Would PropertyChangeSupport suffice?
Main.java:
package dur.bounceme.net;
import javax.swing.JTabbedPane;
public class Main {
private static JTabbedPane tabs;
private static PaneWithList paneWithList;
private static PaneWithTable paneWithTable;
private static Output output;
public static void main(String[] args) {
tabs = new javax.swing.JTabbedPane();
paneWithList = new PaneWithList();
paneWithTable = new PaneWithTable();
tabs.addTab("list", paneWithList);
tabs.addTab("table", paneWithTable);
tabs.addTab("output", output);
}
}
Here's an example using the observer pattern, also seen here, here and here. Note that it would also be possible to listen to the combo's model.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
/**
* #see http://en.wikipedia.org/wiki/Observer_pattern
* #see https://stackoverflow.com/a/10523401/230513
*/
public class PropertyChangeDemo {
public PropertyChangeDemo() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.add(new ObserverPanel());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PropertyChangeDemo example = new PropertyChangeDemo();
}
});
}
}
class ObserverPanel extends JPanel {
private JLabel title = new JLabel("Value received: ");
private JLabel label = new JLabel("null", JLabel.CENTER);
public ObserverPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObserverPanel"));
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(title);
panel.add(label);
this.add(panel);
ObservedPanel observed = new ObservedPanel();
observed.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals(ObservedPanel.PHYSICIST)) {
String value = e.getNewValue().toString();
label.setText(value);
}
}
});
this.add(observed);
}
}
class ObservedPanel extends JPanel {
public static final String PHYSICIST = "Physicist";
private static final String[] items = new String[]{
"Alpher", "Bethe", "Gamow", "Dirac", "Einstein"
};
private JComboBox combo = new JComboBox(items);
private String oldValue;
public ObservedPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObservedPanel"));
combo.addActionListener(new ComboBoxListener());
this.add(combo);
}
private class ComboBoxListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
String newValue = (String) combo.getSelectedItem();
firePropertyChange(PHYSICIST, oldValue, newValue);
oldValue = newValue;
}
}
}
I'd be use JMenu with JMenuItems with contents layed by using CardLayout rather than very complicated JTabbedPane(s)
For my own reference, and for anyone using the Netbeans GUI builder, this works so far as it goes:
The PanelWithList class:
package dur.bounceme.net;
public class PanelWithList extends javax.swing.JPanel {
public PanelWithList() {
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() {
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jList1.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jList1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jList1MouseClicked(evt);
}
});
jList1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jList1KeyReleased(evt);
}
});
jScrollPane1.setViewportView(jList1);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane2.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(54, 54, 54)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 308, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(167, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane2)
.addComponent(jScrollPane1))
.addContainerGap(166, Short.MAX_VALUE))
);
}// </editor-fold>
private void jList1MouseClicked(java.awt.event.MouseEvent evt) {
row();
}
private void jList1KeyReleased(java.awt.event.KeyEvent evt) {
row();
}
// Variables declaration - do not modify
private javax.swing.JList jList1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
private void row() {
Object o = jList1.getSelectedValue();
String s = (String)o;
jTextArea1.setText(s);
this.firePropertyChange("list", -1, 1);
}
}
and Frame.java as a driver:
package dur.bounceme.net;
public class Frame extends javax.swing.JFrame {
public Frame() {
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() {
jTabbedPane1 = new javax.swing.JTabbedPane();
panelWithList1 = new dur.bounceme.net.PanelWithList();
panelWithTable1 = new dur.bounceme.net.PanelWithTable();
newJPanel1 = new dur.bounceme.net.PanelWithCombo();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
panelWithList1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
panelWithList1PropertyChange(evt);
}
});
jTabbedPane1.addTab("tab1", panelWithList1);
jTabbedPane1.addTab("tab2", panelWithTable1);
jTabbedPane1.addTab("tab3", newJPanel1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 937, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 913, Short.MAX_VALUE)
.addContainerGap()))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 555, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 521, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(22, Short.MAX_VALUE)))
);
pack();
}// </editor-fold>
private void panelWithList1PropertyChange(java.beans.PropertyChangeEvent evt) {
System.out.println("panelWithList1PropertyChange ");
}
/**
* #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(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Frame.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 Frame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JTabbedPane jTabbedPane1;
private dur.bounceme.net.PanelWithCombo newJPanel1;
private dur.bounceme.net.PanelWithList panelWithList1;
private dur.bounceme.net.PanelWithTable panelWithTable1;
// End of variables declaration
}
The key being that panelWithList1PropertyChange is the listener on 'panelWithList' itself.
Because PanelWithList.firePropertyChange("list", -1, 1); cannot send Object nor String that I see, I'm not exactly sure how to get the value selected all the way from the JList up to the JFrame.
Hmm, well the API says yes it can send Objects. Have to check that out.
I think it's necessary to get some info about the model which the JList is using up to the JFrame. However, doesn't that break MVC? Or maybe that's the wrong approach.
I want to display an image from the web to a panel in another JFrame at the click of a button. Whenever I click the button, first the image loads; and during this time, the current form potentially freezes. Once the image has loaded, the form is displayed with the image. How can I avoid the situation where my form freezes since it is very irritating. Among my codes:
My current class:
private void btn_TrackbusActionPerformed(java.awt.event.ActionEvent evt) {
try {
sendMessage("Query,map,$,start,211,Arsenal,!");
System.out.println(receiveMessage());
} catch (UnknownHostException ex) {
Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
}
catch (Exception ex) {
Logger.getLogger(client_Trackbus.class.getName()).log(Level.SEVERE, null, ex);
}
client_trackedbus nextform=new client_trackedbus(planform,connection,packet_receive,packet_send);
this.setVisible(false);
this.dispose();
nextform.setVisible(true);
// TODO add your handling code here:
}
My next class that displays the image:
public class client_trackedbus extends javax.swing.JFrame {
client_planform planform=null;
DatagramSocket connection=null;
DatagramPacket packet_receive=null;
DatagramPacket packet_send=null;
JLabel label=null;
/** Creates new form client_trackedbus */
public client_trackedbus(client_planform planform,DatagramSocket connection,DatagramPacket packet_receive,DatagramPacket packet_send) {
initComponents();
this.planform=planform;
this.connection=connection;
this.packet_receive=packet_receive;
this.packet_send=packet_send;
try {
displayMap("http://www.huddletogether.com/projects/lightbox2/images/image-2.jpg", jPanel1, new JLabel());
} catch (MalformedURLException ex) {
Logger.getLogger(client_trackedbus.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void displayMap(String url,JPanel panel,JLabel label) throws MalformedURLException{
URL imageurl=new URL(url);
Image image=(Toolkit.getDefaultToolkit().createImage(imageurl));
ImageIcon icon = new ImageIcon(image);
label.setIcon(icon);
panel.add(label);
// System.out.println(panel.getSize().width);
this.getContentPane().add(panel);
}
/** 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();
jLabel1 = new javax.swing.JLabel();
btn_Exit = new javax.swing.JButton();
btn_Plan = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Public Transport Journey Planner");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 368, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 172, Short.MAX_VALUE)
);
jLabel1.setFont(new java.awt.Font("Arial", 1, 18));
jLabel1.setText("Your tracked bus");
btn_Exit.setText("Exit");
btn_Exit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btn_ExitActionPerformed(evt);
}
});
btn_Plan.setText("Plan journey");
btn_Plan.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btn_PlanActionPerformed(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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(104, 104, 104)
.addComponent(jLabel1))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGap(65, 65, 65)
.addComponent(btn_Plan)
.addGap(65, 65, 65)
.addComponent(btn_Exit, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(20, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addComponent(jLabel1)
.addGap(18, 18, 18)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btn_Exit)
.addComponent(btn_Plan))
.addContainerGap(12, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void btn_ExitActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Exitform();
}
private void btn_PlanActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
this.setVisible(false);
this.dispose();
this.planform.setVisible(true);
}
private void Exitform(){
this.setVisible(false);
this.dispose();
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// new client_trackedbus().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton btn_Exit;
private javax.swing.JButton btn_Plan;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
As suggested in the article Concurrency in Swing, your button handler's query may be blocking the event dispatch thread. Using javax.swing.SwingWorker is one approach to loading images in the background, while displaying progress and keeping the GUI thread alive.
Addendum: Here's a sscce that loads the SO logo; it's been updated to handle exceptions and resize the enclosing container to fit the loaded image:
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
/**
* #see http://stackoverflow.com/questions/4530659
*/
public final class WorkerTest extends JFrame {
private final JLabel label = new JLabel("Loading...");
public WorkerTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.BOTTOM);
this.add(label);
this.pack();
this.setLocationRelativeTo(null);
}
private void start() {
new ImageWorker().execute();
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
WorkerTest wt = new WorkerTest();
wt.setVisible(true);
wt.start();
}
});
}
class ImageWorker extends SwingWorker<Image, Void> {
private static final String TEST
= "http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png";
#Override
protected Image doInBackground() throws IOException {
Image image = ImageIO.read(new URL(TEST));
return image.getScaledInstance(640, -1, Image.SCALE_SMOOTH);
}
#Override
protected void done() {
try {
ImageIcon icon = new ImageIcon(get());
label.setIcon(icon);
label.setText("Done");
WorkerTest.this.pack();
WorkerTest.this.setLocationRelativeTo(null);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
public class SSBTest extends javax.swing.JFrame {
/** Creates new form worker1 */
public SSBTest() {
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();
jPanel1 = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setText("jLabel1");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 348, Short.MAX_VALUE));
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 210, Short.MAX_VALUE));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap(196, Short.MAX_VALUE).addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE).addGap(178, 178, 178)).addGroup(layout.createSequentialGroup().addGap(86, 86, 86).addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(122, Short.MAX_VALUE)));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 40, Short.MAX_VALUE).addComponent(jLabel1).addGap(36, 36, 36)));
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
final SSBTest ssbTest = new SSBTest();
ssbTest.setVisible(true);
ssbTest.execute();
}
});
}
private void execute() {
(new MeaningOfLifeFinder(jLabel1, jPanel1)).execute();
}
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
class MeaningOfLifeFinder extends SwingWorker<Icon, Object> {
JLabel label = null;
JPanel panel;
MeaningOfLifeFinder(JLabel label, JPanel jpanel) {
this.label = label;
this.panel = jpanel;
}
protected Icon doInBackground() throws IOException {
URL imageurl;
Image image = null;
System.out.println("image loading");
imageurl = new URL("http://maps.google.com/maps/api/staticmap"
+ "?zoom=14&size=512x512&maptype=roadmap"
+ "&markers=color:green|label:21|-15.0,-150.0&sensor=false");
//image = (Toolkit.getDefaultToolkit().createImage(imageurl));
image = ImageIO.read(imageurl);
ImageIcon icon = new ImageIcon(image);
System.out.println("image loaded...");
return icon;
}
#Override
protected void done() {
try {
System.out.println("image adding to label...");
label.setIcon(get());
//panel.add(label);
System.out.println("image loaded to label...");
} catch (Exception ignore) {
}
}
// System.out.println(panel.getSize().width);
}