JFrame freezing when I call a class using JButton - java

Im not really an expert in programming and Im just starting to learn. Here is my problem.
I tried to call this class to start the server using a JButton but after the button was pressed the application freezes.
Here is my mouseClicked event
private void startbtnActionPerformed(java.awt.event.ActionEvent evt) {
new DisplayServer(80);
}

I suppose you block the Event Dispatcher Thread. Try to run it in a new Thread.
private void startbtnActionPerformed(java.awt.event.ActionEvent evt) {
new Thread(new Runnable() {
public void run() {
new DisplayServer(80);
}
}).start();
}
For more info read the article about Concurrency in Swing

Related

I am a beginner and I am trying to make a card flip game in netbeans

On clicking an image I want another image to be displayed pause for one second and the original image to be restored and displayed againdisplayed again When I try to do it it action handler such as code given below it sets the image after sleep .I want the image to be displayed pause and the original to be displayed again how can I achieve that
private void jButton16ActionPerformed(java.awt.event.ActionEvent evt) {
jButton16.setIcon(new javax.swing.ImageIcon("C:\\Users\\x\\Documents\\O.png"));
try { //sleep 1 seconds
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
jButton16.setIcon(new javax.swing.ImageIcon("C:\\Users\\x\\Documents\\118px-AMIGO.jpg")); }
Swing is single threaded, you should never perform long running or blocking operations within the context of the Event Dispatching Thread
Swing is NOT thread safe, this means you should never update the UI (and anything the UI needs) outside of the context of the EDT
The simplest solution to your problem is to use a Swing Timer
private void jButton16ActionPerformed(java.awt.event.ActionEvent evt) {
jButton16.setIcon(new javax.swing.ImageIcon("C:\\Users\\x\\Documents\\O.png"));
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jButton16.setIcon(new javax.swing.ImageIcon("C:\\Users\\x\\Documents\\118px-AMIGO.jpg"));
}
});
timer.setRepeats(false);
timer.start();
}
See Concurrency in Swing and How to use Swing Timers for more details
You should never invoke Thread.sleep() inside Event Dispatch Thread
because Thread.sleep() will block Event Dispatch Thread and your UI will be Freeze , instead you could use a Timer to achieve your goal
Refer below code,
jButton16.setIcon(new javax.swing.ImageIcon("C:\\Users\\x\\Documents\\O.png"));
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jButton16.setIcon(new javax.swing.ImageIcon("C:\\Users\\x\\Documents\\118px-AMIGO.jpg"));
}
});
timer.setRepeats(false);
timer.start();

Why isn't my timer working?

public class TimerProgram extends JFrame {
public TimerProgram(){
int DELAY=1000;
Timer t = new Timer(DELAY,new TimerListener());
t.start();
}
class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("Hello");
}
}
public static void main(String[]args){
new TimerProgram();
}
}
I am trying to make a timer that outputs every second the word hello, but it seems that when I type as the DELAY value 1000 , it outputs hello once and then it terminates. What am I doing wrong ? All help appreciated!
The JVM exited before the Timer fired.
Try:
t.setInitialDelay(0);
t.start();
to see the difference.
Or a better approach is to execute the code on the Event Dispatch Thread (EDT). All GUI code should execute on the EDT. By using SwingUtitities.invokeLater() you ensure the EDT has been created when your code executes:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new TimerProgram();
}
});
Read the section from the Swing tutorial on Concurrency for more information about the EDT.

Trouble with SwingUtilities.invokeLater() updating GUI

I have been trying this all day in different variations with little success. Could someone please help explain what I am doing wrong? I am just a beginner with regards to threads.
private JTextArea text = new JTextArea();
private JButton button = new JButton("Cancel");
public StatusFrame() {
text.setEditable(false);
this.add(text);
this.add(button, BorderLayout.EAST);
this.setSize(new Dimension(150, 100));
this.setVisible(true);
}
public void updateStatus(String textIn) {
text.setText(textIn);
}
public JButton getButton() {
return button;
}
In another class, I am calling methods which may take a while to complete. I want to be able to call the StatusFrame.updateStatus() method to keep the user informed on the progress.
This is what I have:
someMethod() {
// prevent GUI from freezing using threads
final Runnable r = new Runnable() {
public void run() {
status = new StatusFrame();
}
};
SwingUtilities.invokeLater(r);
//do something
status.update("process 1 completed");
//do something else
status.updateStatus("Process 2 completed");
}
The frame appears but none of the code after the runnable appears to be run/processed. It just stops/blocks/something. But the GUI remains active
Thanks for any advice.
P.S.: I have tried using invokeAndWait() method but again not sure if I am doing it the right way. For now a quick fix would be preferred as I have not learned much about threads yet. Any instructions are welcome.
You have the concepts backwards.
Here's your code
someMethod() {
// prevent GUI from freezing using threads
final Runnable r = new Runnable() {
public void run() {
status = new StatusFrame();
}
};
SwingUtilities.invokeLater(r);
//do something
status.update("process 1 completed");
//do something else
status.updateStatus("Process 2 completed");
You should execute the long running code in a thread, and use the SwingUtilities invokeLater method to update the GUI.
someMethod() {
// prevent GUI from freezing using threads
final Runnable r = new Runnable() {
public void run() {
status = new StatusFrame();
}
};
new Thread(r).start();
// inside the StatusFrame
//do something
SwingUtilities.invokeLater(new Runnable() {
public void run() {
update("process 1 completed");
}
);
//do something else sometime later
SwingUtilities.invokeLater(new Runnable() {
public void run() {
update("Process 2 completed");
}
);
I don't know if I was clear in my answer.
Execute SwingUtilities.invokeLater when you start your Java application to make sure Swing components are on the Event Dispatch thread (EDT).
From the EDT, invoke long running processes as a runnable thread.
In the runnable thread, since you're not on the EDT, execute SwingUtilities.invokeLater whenever you're updating Swing components. This ensures that Swing components are updated on the EDT.
Every Swing application should start with a class like this:
import javax.swing.SwingUtilities;
import com.ggl.text.entry.model.TextEntryModel;
import com.ggl.text.entry.view.TextEntryFrame;
public class TextEntry implements Runnable {
#Override
public void run() {
new TextEntryFrame(new TextEntryModel());
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new TextEntry());
}
}
This class does 3 things.
Constructs the GUI data model.
Constructs the GUI JFrame.
Ensures that the Swing components are on the EDT.
You'll need to call the updates on EDT too. I would suggest to sleep on the main thread, to give GUI a chance to show up before any other work:
someMethod() {
// prevent GUI from freezing using threads
Runnable r = new Runnable() {
public void run() {
status = new StatusFrame();
}
};
SwingUtilities.invokeLater(r);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
//do something
r = new Runnable() {
public void run() {
status.update("process 1 completed");
}
};
SwingUtilities.invokeLater(r);
//do something else
r = new Runnable() {
public void run() {
status.update("Process 2 completed");
}
};
SwingUtilities.invokeLater(r);
}
See Concurrency in Swing.
You may find using a Swing Worker easier to work with since it uses a Thread and has methods that will allow you to update the GUI properly.

Initiating GUI as thread

I have a GUI class that works fine, however I have a button in that GUI class that is the supposed to open a new GUI from another class..
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
GUI2 newGui = new GUI2();
newGui.setVisible(true);
}
However, when the new GUI class (newGui) is called, it just appears as a see-through window. Is this becuase both GUI's can't run at the same time?
I'm now trying to open the new GUI as a thread, but I don't know how to do this!
Thread thread = new Thread();
thread.sleep(5000);
thread.newGui.setVisible();
public void run();
This was my attempt, but unsurprisingly this didn't work.
Any help?
Thanks!
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
GUI2 newGui = new GUI2();
newGui.setVisible(true);
}
});
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
Thread thread = new Thread(){
public void run(){
GUI2 newGui = new GUI2();
newGui.setVisible(true);
}
};
thread.start();
}

update jtextpane with java swing

I'm making an application with java swing. In a button of the application I need to every x minutes to make something.
I think that I must do it with a new thread, but I have two problems. The first is that I must to pass a parameter to these thread. I solved it with a class that extends of a Thread and a constructor. I think these way is correct no?
The second thing I cannot resolve it is that I need to update a jtextpane while the thread is running but if I try to update the JTextPane propierties Eclipse says me that cannot be resolved. I think that the problem is that these thread is not the main thread. But... there is some way to fix it?
Many thanks and sorry for my english!
The code is:
btnIniciar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//String file = "D:\\prueba.torrent";
// while (true) {
Hilo ejecutar = new Hilo(listaBuscar);
ejecutar.run();
public class Hilo extends Thread {
public Hilo(List<String> aBuscar){
}
public void run(){
System.out.println("Trabajo por hacer dentro de MiHilo");
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
lblNewLabel.setText("hola");
}
});
}
}
It says me lblNewLabel cannot be resolved.
Any help?
Thanks
I'm trying with these code now and doesnt works:
public class Hilo implements Runnable {
private JLabel etiqueta;
public Hilo (List <String> aBuscar, JLabel label){
System.out.println("Hemos entrado en el puto hilo");
etiqueta = label;
}
#Override
public void run() {
etiqueta.setText("hola");
System.out.println("vamos a coneseguirlo");
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
etiqueta.setText("hola");
System.out.println("vamos a coneseguirlo");
}
});
}
}
Use Swing timer. It is very much like invisible button that is pressed periodically in the given intervals. It will call your actionPerformed already in a Swing thread from where you can manipulate components (same as from the JButton ActionListener). Hence most likely you do not need to run your own threads for this task.
You mention JTextPane in your question title but only refer to JLabel?
The main problem though you are having I see is that you have not declared the JLabel within the scope of your Thread, you could pass your JLabel instance which has a method to get a reference to the JLabel to your Thread via a constructor thus it has a reference to the JLabel, right now it doesnt.
Also I'd recommend using SwingUtilities and not EventQueue
And do not extend Thread class (unless adding custom functionality) rather implement a Runnable
Something like:
GUI.java:
public class GUI {
private JFrame frame;
private JLabel label;
private JButton btnIniciar;
public void getJLabel() {
return label;
}
public void initComponents() {
//create UI and components here
btnIniciar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//String file = "D:\\prueba.torrent";
Hilo ejecutar = new Hilo(listaBuscar,Gui.this);//pass reference of to our class
}
}
}
Hilo.java:
public class Hilo implements Runnable {
private Thread t;
private final GUI gui;
public Hilo(List<String> aBuscar, GUI ui){
this.gui=ui;
t=new Thread(this);
startThread();
}
#Override
public void run(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui.getJLabel().setText("hola");
}
});
}
//so we can start thread from other class
public void startThread() {
if(!t.isAlive()) //if the thread is not started alreade
t.start();
}
}
Though depending on what you are doing a Swing Timer might be what you need, it will allow you to run code, at intervals/delays and all this is done on the EDT already.

Categories