JLabel displaying countdown, java - java

I've got a "status" JLabel in one class (named Welcome) and the timer in another one (named Timer). Right now, the first one displays the word "status" and the second one should be doing the countdown. The way I would like it to be, but don't know how to - display 10, 9, 8, 7 ... 0 (and go to the next window then). My attempts so far:
// class Welcome
setLayout(new BorderLayout());
JPanel area = new JPanel();
JLabel status = new JLabel("status");
area.setBackground(Color.darkGray);
Font font2 = new Font("SansSerif", Font.BOLD, 25);
status.setFont(font2);
status.setForeground(Color.green);
area.add(status, BorderLayout.EAST); // can I put it in the bottom-right corner?
this.add(area);
and the timer:
public class Timer implements Runnable {
// public void runThread() {
// new Thread(this).start();
// }
public void setText(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setText(text); // link to status here I guess
}
});
}
public void run() {
for (int i = 10; i > 0; i--) {
// set the label
final String text = "(" + i + ") seconds left";
setText(text);
// // sleep for 1 second
// try {
// Thread.currentThread();
// Thread.sleep(1000);
// } catch (Exception ex) {
// }
}
// go to the next window
UsedBefore window2 = new UsedBefore();
window2.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// runThread();
}
} // end class

I agree that you should consider using a "Java" Timer as per Anh Pham, but in actuality, there are several Timer classes available, and for your purposes a Swing Timer not a java.util.Timer as suggested by Anh would suit your purposes best.
As for your problem, it's really nothing more than a simple problem of references. Give the class with the label a public method, say setCountDownLabelText(String text), and then call that method from the class that holds the timer. You'll need to have a reference of the GUI class with the timer JLabel in the other class.
For example:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Welcome extends JPanel {
private static final String INTRO = "intro";
private static final String USED_BEFORE = "used before";
private CardLayout cardLayout = new CardLayout();
private JLabel countDownLabel = new JLabel("", SwingConstants.CENTER);
public Welcome() {
JPanel introSouthPanel = new JPanel();
introSouthPanel.add(new JLabel("Status:"));
introSouthPanel.add(countDownLabel);
JPanel introPanel = new JPanel();
introPanel.setPreferredSize(new Dimension(400, 300));
introPanel.setLayout(new BorderLayout());
introPanel.add(new JLabel("WELCOME", SwingConstants.CENTER), BorderLayout.CENTER);
introPanel.add(introSouthPanel, BorderLayout.SOUTH);
JPanel usedBeforePanel = new JPanel(new BorderLayout());
usedBeforePanel.setBackground(Color.pink);
usedBeforePanel.add(new JLabel("Used Before", SwingConstants.CENTER));
setLayout(cardLayout);
add(introPanel, INTRO);
add(usedBeforePanel, USED_BEFORE);
new HurdlerTimer(this).start();
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Welcome");
frame.getContentPane().add(new Welcome());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
public void setCountDownLabelText(String text) {
countDownLabel.setText(text);
}
public void showNextPanel() {
cardLayout.next(this);
}
}
class HurdlerTimer {
private static final int TIMER_PERIOD = 1000;
protected static final int MAX_COUNT = 10;
private Welcome welcome; // holds a reference to the Welcome class
private int count;
public HurdlerTimer(Welcome welcome) {
this.welcome = welcome; // initializes the reference to the Welcome class.
String text = "(" + (MAX_COUNT - count) + ") seconds left";
welcome.setCountDownLabelText(text);
}
public void start() {
new Timer(TIMER_PERIOD, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (count < MAX_COUNT) {
count++;
String text = "(" + (MAX_COUNT - count) + ") seconds left";
welcome.setCountDownLabelText(text); // uses the reference to Welcome
} else {
((Timer) e.getSource()).stop();
welcome.showNextPanel();
}
}
}).start();
}
}

Since you're using Swing you should use the javax.swing.Timer, not the java.util.Timer. You can set the timer to fire at 1 second (1000 ms) intervals and have your listener do the updating. Since Swing updates must take place in the event dispatch thread your listener is the perfect place for status.setText.

there's already a Timer class in java: http://www.exampledepot.com/egs/java.util/ScheduleRepeat.html

Why not put the setText method in the welcome class and just do 'status.setText(text)'?
And you might try BorderLayout.SOUTH or .PAGE END or .LINE END to get the timer in the lower right corner

Related

Java second variable dismisses first one

What I have to do is make a little GUI that when a button is clicked it starts to progress bars with threads; however, we have to do it with an inner class that implements the Runnable interface, and within the constructor for that class, it takes a String and a JProgressBar object. Then within the main constructor, we are supposed to instantiate 2 JProgressBar objects and then create 2 of the Inner class objects using those JProgressBars.
Only my second JProgressBar is updating with the thread. I know that my second JProgressBar is basically overriding my first one, but I don't know how I would go to fix that, because if I try to change the inner class's constructor to setting 2 JProgressBar attributes equal to the parameter of the constructor, then the first JProgessBar just completely disappears from the GUI. Here is my code, thank you to anyone that can help.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Lab4Part2 {
//Attributes
private JFrame frame;
private String progress;
private JProgressBar jpb;
//Constructor
public Lab4Part2() {
//Create frame with specified grid layout
frame = new JFrame();
GridLayout grid = new GridLayout(0,1);
frame.setLayout(grid);
JButton jbClick = new JButton("Let's start this show");
frame.add(jbClick);
//Add in JProgressBars and create Inner Class objects with them
JProgressBar jpb1 = new JProgressBar();
JProgressBar jpb2 = new JProgressBar();
InnerProgress bar1 = new InnerProgress("Progress 1: ", jpb1);
InnerProgress bar2 = new InnerProgress("Progress 2: ", jpb2);
//Anonymous class for the button's action listener
jbClick.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Thread t1 = new Thread(bar1);
Thread t2 = new Thread(bar2);
t1.start();
t2.start();
}
});
//Adds inner object to frame
frame.add(bar1);
frame.add(bar2);
//Packing and stuff
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
//Inner class
class InnerProgress extends JPanel implements Runnable {
//Constructor
public InnerProgress(String pbar, JProgressBar jpBar) {
jpBar.setMinimum(0);
jpBar.setMaximum(80);
jpBar.setStringPainted(true);
progress = pbar;
jpb = jpBar;
JLabel label = new JLabel(pbar);
add(label);
add(jpBar);
}
//Thread action
public void run() {
System.out.println("We are running " + Thread.currentThread().getName());
for(int i = 1; i<= 80; i++) {
try {
Thread.currentThread().sleep((long)Math.random()*100);
jpb.setValue(i);
}
catch(InterruptedException ie) {
System.out.println(ie);
}
}
System.out.println("Thread name: " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
}
}
//Main
public static void main(String[] args) {
new Lab4Part2();
}
}
Your inner class should maintain it's own reference to the JProgressBar that it is passed.
Simply take...
private JProgressBar jpb;
and move it inside your inner class
class InnerProgress extends JPanel implements Runnable {
private JProgressBar jpb;
//...
So, two other issues
One, (long)Math.random()*100 is causing the result of Math.random() to be case to an int, which will result in it becoming 0.
You need to cast the result of the operation, for example...
Thread.currentThread().sleep((int)(Math.random() * 500));
(nb: I made it 500 for my testing)
Two, Swing is not thread safe. This means you should not be updating the UI from outside of the context of the Event Dispatching Thread.
So, instead of...
jpb.setValue(i);
I wrote a new method which will update the UI accordingly
protected void updateProgress(int value) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
InnerProgress.this.jpb.setValue(value);
}
});
}
(Long and short, this over comes issues with referencing variables from inside an anonymous context)
Then simply called it using updateProgress(i);
Runnable example...
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
public class Lab4Part2 {
//Attributes
private JFrame frame;
private String progress;
//Constructor
public Lab4Part2() {
//Create frame with specified grid layout
frame = new JFrame();
GridLayout grid = new GridLayout(0, 1);
frame.setLayout(grid);
JButton jbClick = new JButton("Let's start this show");
frame.add(jbClick);
//Add in JProgressBars and create Inner Class objects with them
JProgressBar jpb1 = new JProgressBar();
JProgressBar jpb2 = new JProgressBar();
InnerProgress bar1 = new InnerProgress("Progress 1: ", jpb1);
InnerProgress bar2 = new InnerProgress("Progress 2: ", jpb2);
//Anonymous class for the button's action listener
jbClick.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Thread t1 = new Thread(bar1);
Thread t2 = new Thread(bar2);
t1.start();
t2.start();
}
});
//Adds inner object to frame
frame.add(bar1);
frame.add(bar2);
//Packing and stuff
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
//Inner class
class InnerProgress extends JPanel implements Runnable {
private JProgressBar jpb;
//Constructor
public InnerProgress(String pbar, JProgressBar jpBar) {
jpBar.setMinimum(0);
jpBar.setMaximum(80);
jpBar.setStringPainted(true);
progress = pbar;
jpb = jpBar;
JLabel label = new JLabel(pbar);
add(label);
add(jpBar);
}
//Thread action
public void run() {
System.out.println("We are running " + Thread.currentThread().getName());
for (int i = 1; i <= 80; i++) {
try {
Thread.currentThread().sleep((int)(Math.random() * 500));
updateProgress(i);
} catch (InterruptedException ie) {
System.out.println(ie);
}
}
System.out.println("Thread name: " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
}
protected void updateProgress(int value) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
InnerProgress.this.jpb.setValue(value);
}
});
}
}
//Main
public static void main(String[] args) {
new Lab4Part2();
}
}

Display not Changing [duplicate]

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I am working on this program that calculates the Beats per Minute (BPM) when you click the button. When you click two times, it is supposed to display the current BPM, and display the new one with every click after that. What the problem is, though, is that the display isn't changing. What do I need to do?
Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class BPM extends JPanel implements ActionListener {
JLabel label;
public String display;
public int bpm;
public int buttonPressed;
public int time1;
public int time2;
public int time3;
public int counter[];
public void addComponents(Container pane) {
JPanel buttons = new JPanel();
JButton bpmButton = new JButton("Click");
bpmButton.setSize(new Dimension(100, 50));
bpmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPressed++;
counter = new int[2];
if (buttonPressed == 1) {
counter[0] = (int)(System.currentTimeMillis());
} else if (buttonPressed == 2) {
counter[1] = (int)(System.currentTimeMillis());
calculateTimeBetweenClicks();
setTime();
} else {
counter[0] = counter[1];
counter[1] = (int)(System.currentTimeMillis());
calculateTimeBetweenClicks();
setTime();
}
}
});
display = "0";
label = new JLabel(display, SwingConstants.CENTER);
label.setFont(label.getFont().deriveFont(100.0f)); // original 45
pane.add(label, BorderLayout.PAGE_START);
pane.add(bpmButton, BorderLayout.CENTER);
}
// Calculates the difference between the two saved clicks
public void calculateTimeBetweenClicks() {
if (buttonPressed == 1) {
time1 = counter[0];
} else {
time1 = counter[0];
time2 = counter[1];
}
time3 = time2 - time1;
}
// Calculates the BPM and changes the display accordingly
public void setTime() {
bpm = 60000 / time3;
display = "" + bpm + "";
label.setText(display);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
public static void createAndShowGUI() {
// Creates the window
JFrame frame = new JFrame("BPM Calculator");
frame.setPreferredSize(new Dimension(300, 200)); // original (250, 130)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Adds the components to the content pane
BPM window = new BPM();
window.addComponents(frame.getContentPane());
//Displays the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Turns off bold text
UIManager.put("swing.boldMetal", Boolean.FALSE);
// Allows the components to be used and interacted with
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
The problem is in your addComponents method, you are creating a new array on each and every button click (so you end up with a new and empty array). This is throwing off your calculation. Simply move the instantiation of your array to somewhere outside of the ActionListener like this...
public void addComponents(Container pane) {
JPanel buttons = new JPanel();
counter = new int[2]; //Move this line to here...
JButton bpmButton = new JButton("Click");
bpmButton.setSize(new Dimension(100, 50));
bpmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPressed++;
if (buttonPressed == 1) {
counter[0] = (int)(System.currentTimeMillis());
} else if (buttonPressed == 2) {
counter[1] = (int)(System.currentTimeMillis());
calculateTimeBetweenClicks();
setTime();
} //Removed the else - see edit below :-)
}
});
Additional
Your code as-is seems to get a litle confused after the 2nd click (the first BPM calculation) as it seems to take that 2nd click as the first click of the next set of 2 clicks if you get what I mean. I'm not sure if this is intended behaviour, but if not, I would reset everything in the calculateTimeBetweenClicks method after you've calculated the correct bpm ready for a new set of 2 clicks...
// Calculates the difference between the two saved clicks
public void calculateTimeBetweenClicks() {
if (buttonPressed == 1) {
time1 = counter[0];
} else {
time1 = counter[0];
time2 = counter[1];
//Reset here ready for next 2 clicks...
counter[0]=0;
counter[1]=0;
buttonPressed = 0;
}
time3 = time2 - time1;
}

Program not overwriting variable

I have a program which uses 3 radiobuttons to switch between 3 incrementing values for a counter, here time.
I want to change status when a radiobutton is pressed, and it does so, but only for a fraction. When launching the program will keep printing
0
Normal
2
Normal
4
Normal
6
etc. When I press the button slow it prints CHANGE Slow once but keeps incrementing with 2 and still prints Normal every time.
How can I have this permenently switch to a different value for status, and a different increment, until I choose another radiobutton again?
package daynightcycle;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
/**
* Day/night cycle with visuals. Adjustable speed and time inserts.
* Optional date or daycounter later
* #author rogie
*/
public class DayNightCycle extends JFrame implements Runnable{
//JFrame entities
private JPanel animationPanel;
public JRadioButton button;
public JRadioButton button2;
public JRadioButton button3;
public int time = 0;
public String status = "Normal";
public static void main(String[] args) {
DayNightCycle frame = new DayNightCycle();
frame.setSize(2000, 1300);
frame.setLocation(1000,350);
frame.createGUI();
frame.setVisible(true);
frame.setTitle("Day/Night Cycle, Rogier");
(new Thread(new DayNightCycle())).start();
}
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new FlowLayout() );
animationPanel = new JPanel();
animationPanel.setPreferredSize(new Dimension(2000, 900));
animationPanel.setBackground(Color.black);
window.add(animationPanel);
JRadioButton option1 = new JRadioButton("Slow");
JRadioButton option2 = new JRadioButton("Normal", true);
JRadioButton option3 = new JRadioButton("Fast");
option1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("CHANGE");
status = "Slow";
System.out.println(status);
}
});
option2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
status = "Normal";
}
});
option2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
status = "Fast";
}
});
//option2.setFont(new java.awt.Font("Tahoma", Font.BOLD, 30));
//option2.putClientProperty("JComponent.sizeVariant", "huge"); //doesn't work
ButtonGroup group = new ButtonGroup();
group.add(option1);
group.add(option2);
group.add(option3);
add(option1);
add(option2);
add(option3);
pack();
}
public void run() {
while(true){
System.out.println(time);
System.out.println(status);
try
{
Thread.sleep(500);
if (status.equals("Slow")) {
time += 1;
}
else if (status.equals("Normal")){
time += 2;
}
else {
time += 3;
}
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
}
}
You are creating to DayNightCycle-Objects, the first shows the GUI and the second prints on the console.
Change the line
(new Thread(new DayNightCycle())).start();
to
(new Thread(frame)).start();
public static void main(String[] args) {
final DayNightCycle frame = new DayNightCycle();
frame.setSize(2000, 1300);
frame.setLocation(1000,350);
frame.createGUI();
frame.setTitle("Day/Night Cycle, Rogier");
And then
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
Or in java 8:
EventQueue.invokeLater(() -> frame.setVisible(true));
}
You in effect created a second DayNightCycle.

Build JFrame from another JFrame with long process

I'm quite new on JAVA, and i have a question (i hope my english is not too bad).
Here is my process :
Open a first JFrame in the Main, with a JButton (to open the second
JFrame).
On click, with ActionLister, i call the process to open my second
window, with a black background (this works very well).
BUT, if i add a long process (in my code, just a sleep(5000)) just after setVisible() my second JFrame, this one will appear in white, and waits for the sleep(5000) to end before being black.
Questions :
Can someone tell me why the second JFrames appears white until the
end of process ? Maybe i make something wrong when i build my JFrame
?
Can someone tell me how to show my second JFrame black BEFORE the process ends ?
I searched for a long time, and saw that if my second window is built direct in the main thread it's ok even with the sleep before end of process.
But when i am in another thread (like when i click on the button), that doesn't work good !
SECOND PART :
On click on the button from the first window :
The second window shows up (empty with black background). then, the result's calcul is launched.
Calculate the result cant take 20sec, and will find 1 element each 5 seconds.
Each times an element is found, i want it to be shown in the second window.
For that, i added an observer on this result from the JFrame, which will add an element each time one element is found. I hope you understand.
Here picture of what i want to make :
Process
Here my project .JAR : http://dl.free.fr/b5IUSStBJ
Here my result's calcul :
public void launchCalculateResult(){
String[] tabelements = {"test1","test2", "test3", "test4", "test5"};
for (int i=0; i < 5; i++){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
_elementslist.add(tabelements[i]);
notifyObservers();
}
}
you can see that it adds an element in a list each 2 seconds, and then notify the observers (my second window), then the observer adds an element :
public void refresh(Observable o) {
_otherwindow.addResultElement(_result.getLastElement());
}
The behaviour I got :
The Result calculates good, and in the end the second window looks good, with its 5 elements. But during the result's search, my second windows remains empty and white . . .
I repeat the aim :
Each time an element is added in the Result, i want to show it in my second window.
You're calling the long process on the Swing event thread, and this will tie up the thread preventing it from doing its important jobs, including painting your new JFrame.
The canonical solution is to use a background thread for your long processes, and for Swing GUI's, you'd want to use a SwingWorker -- if the background process needs to communicate with the GUI (which is usually the case).
For the details on this problem and solution, please check out: Concurrency in Swing
Side issue: you'll usually not want to show multiple JFrames in your application. For why this is important and for how you can improve this design, please check out Multiple JFrames
For example
import java.awt.Color;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class SwingExample extends JPanel {
private JButton openDialogBtn = new JButton(new OpenDialogAction("Open Dialog"));
private JDialog dialog;
private DialogPanel dialogPanel = new DialogPanel();
public SwingExample() {
setPreferredSize(new Dimension(400, 400));
add(openDialogBtn);
}
private class OpenDialogAction extends AbstractAction {
public OpenDialogAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
dialogPanel.setText("");
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(SwingExample.this);
dialog = new JDialog(win, "Dialog", ModalityType.MODELESS);
dialog.add(dialogPanel);
dialog.pack();
dialog.setLocationRelativeTo(win);
}
new SwingWorker<Void, Integer> () {
private final int maxI = 5;
#Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < maxI; i++) {
publish(i);
Thread.sleep(1000);
}
return null;
}
protected void process(java.util.List<Integer> chunks) {
for (Integer chunk : chunks) {
dialogPanel.setText("Time: " + chunk);
}
};
protected void done() {
dialogPanel.setText("Done!");
};
}.execute();
dialog.setVisible(true);
}
}
private class DialogPanel extends JPanel {
private JTextField textField = new JTextField(10);
public DialogPanel() {
setBackground(Color.BLACK);
setPreferredSize(new Dimension(200, 200));
add(textField);
}
public void setText(String text) {
textField.setText(text);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
SwingExample mainPanel = new SwingExample();
JFrame frame = new JFrame("SwingExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
Example 2: handles Strings being passed into a JList<String> using a SwingWorker<Void, String>
import java.awt.Color;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwingExample extends JPanel {
private JButton openDialogBtn = new JButton(new OpenDialogAction("Open Dialog"));
private JDialog dialog;
private DialogPanel dialogPanel = new DialogPanel();
public SwingExample() {
setPreferredSize(new Dimension(400, 400));
add(openDialogBtn);
}
private class OpenDialogAction extends AbstractAction {
public OpenDialogAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
dialogPanel.clearList();
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(SwingExample.this);
dialog = new JDialog(win, "Dialog", ModalityType.MODELESS);
dialog.add(dialogPanel);
dialog.pack();
dialog.setLocationRelativeTo(win);
}
new SwingWorker<Void, String>() {
#Override
protected Void doInBackground() throws Exception {
String[] tabelements = { "test1", "test2", "test3", "test4", "test5" };
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publish(tabelements[i]);
}
return null;
}
protected void process(java.util.List<String> chunks) {
for (String chunk : chunks) {
dialogPanel.addText(chunk);
}
};
protected void done() {
dialogPanel.addText("Done!");
};
}.execute();
dialog.setVisible(true);
}
}
private class DialogPanel extends JPanel {
private DefaultListModel<String> listModel = new DefaultListModel<>();
private JList<String> jList = new JList<>(listModel);
public DialogPanel() {
jList.setPrototypeCellValue("ABCDEFG HIJKLMNOP");
jList.setVisibleRowCount(6);
JScrollPane scrollPane = new JScrollPane(jList);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setBackground(Color.BLACK);
setPreferredSize(new Dimension(200, 200));
add(scrollPane);
}
public void clearList() {
listModel.clear();
}
public void addText(String text) {
listModel.addElement(text);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
SwingExample mainPanel = new SwingExample();
JFrame frame = new JFrame("SwingExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
//Make constructor class for both JFrame then
//write this code into your JFrame where your button is accesing another JFrame
//Note:- jb=button var name,
// jf=JFrame vatr name,
// addnew()=JFrame Class to be open.
jb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
new addnew();
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
});
It might work as well.

Thread interruption and ActionListener Java

I have a function graphics() that creates my JFrame and two JRadioButtons and adds ActionListeners to them. This graphics is called from main() and graphics itself calls game().
public void game() throws Exception
{
jTextArea1.setLineWrap(true);
jTextArea1.setWrapStyleWord(true);
jTextArea1.setText("This is private information.");
jRadioButton1.setVisible(true);
jRadioButton2.setVisible(true);
try {
t.sleep(40000);
repaint();
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
After displaying "This is private information." in the text Area, I want the program execution to pause for 40 seconds, or until the user presses the JRadioButton, whichever is earlier. So I added an ActionListener and called t.interrupt() inside it.
private void jRadioButton1ActionPerformed(java.awt.event.ActionEvent evt) {
t.interrupt();
jRadioButton1.setVisible(false);
jRadioButton2.setVisible(false);
//System.out.println(t.interrupted());
jTextArea1.setText("Please wait...");
}
However, even after choosing the JRadioButton which should trigger the interrupt, that does not happen and t.interrupted returns false.
Any help would be appreciated.
Never, ever call Thread.sleep(...) on the Swing event thread as you will freeze the thread and effectively freeze your program. The solution is to consider use of a Swing Timer for the time-dependent portion of your requirement and using a SelectionListener for the JCheckBox or JRadioButton requirement.
For example:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class PausingExecution extends JPanel {
private static final String SELECTED_TEXT = "Snafus are Better!!!";
private static final String UNSELECTED_TEXT = "Fubars Rule!!";
private static final String TIMES_UP = "Time's Up!!!!";
private static final int TIMER_DELAY = 10 * 1000;
private JTextField messageField = new JTextField(UNSELECTED_TEXT, 10);
private JCheckBox checkBox = new JCheckBox("Click Me");
public PausingExecution() {
add(messageField);
add(checkBox);
checkBox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent iEvt) {
if (iEvt.getStateChange() == ItemEvent.SELECTED) {
messageField.setText(SELECTED_TEXT);
} else {
messageField.setText(UNSELECTED_TEXT);
}
}
});
Timer mySwingTimer = new Timer(TIMER_DELAY, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
messageField.setText(TIMES_UP);
checkBox.setEnabled(false);
}
});
mySwingTimer.setRepeats(false);
mySwingTimer.start();
}
private static void createAndShowGui() {
PausingExecution mainPanel = new PausingExecution();
JFrame frame = new JFrame("PausingExecution");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Categories