Swing timers basic functionality [closed] - java

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm new at java graphic design, and I would like you, if possible, to help me with an easy example to help me to get to understand the basic functionality of JFrames, Timers, SwingControllers, and all this stuff. How would you implement the following case:
We have a JFrame with a JPanel inside.
When the execution starts, the JPanel is white, but we want it to change it's colour every two seconds:
public class MiJFrame extends javax.swing.JFrame {
public MiJFrame() {
initComponents();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MiJFrame().setVisible(true);
jPanel1.setBackground(Color.yellow);
jPanel1.setBackground(Color.RED);
}
});
}
// Variables declaration - do not modify
private static javax.swing.JPanel jPanel1;
// End of variables declaration
}
At first, I used the sleep method of a thread object between the setBackgroud() methods but it doesn't work, as it only shows the last change. How would you use here a Timer object?

First of all, whenever you need to change the colour of the said thingy, always set Opaque property to true for the said thingy. Like in your case it's the JPanel so first of all you must use panelObject.setOpaque(true), for some Look And Feels calling this method is a must for background colour changes to take effect.
Do try this code example, regarding the rest :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/*
* #see
* http://stackoverflow.com/q/11036830/1057230
*/
public class ColourTimer
{
private JPanel contentPane;
private Timer timer;
private int counter;
private Color[] colours = {
Color.RED,
Color.WHITE,
Color.BLUE,
Color.DARK_GRAY,
Color.YELLOW,
Color.LIGHT_GRAY,
Color.BLACK,
Color.MAGENTA,
Color.PINK,
Color.CYAN
};
private ActionListener timerAction = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter == (colours.length - 1))
counter = 0;
contentPane.setBackground(colours[counter++]);
}
};
public ColourTimer()
{
counter = 0;
}
private void displayGUI()
{
JFrame frame = new JFrame("Colour Timer");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
final JButton button = new JButton("STOP");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (timer.isRunning())
{
button.setText("START");
timer.stop();
}
else
{
button.setText("STOP");
timer.start();
}
}
});
frame.getContentPane().add(contentPane, BorderLayout.CENTER);
frame.getContentPane().add(button, BorderLayout.PAGE_END);
frame.setSize(300, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(2000, timerAction);
timer.start();
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new ColourTimer().displayGUI();
}
});
}
}

Related

A loop in action performed method Doesn't Working in java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
Question: Write JFrame that when you press the "start" button draws, and keep drawing random colored and sized filled ovals until the "stop" button is pressed.
Problem: loop inside the actionPerformed method() Doesn't Work.
The Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class p6 extends JFrame implements ActionListener
{
String str;
JButton start,stop;
int h=0,w=0;
p6()
{
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1500,1000);
start= new JButton("Start");
stop= new JButton("Stop");
setLayout(null);
start.setBounds(500, 50, 100,30);
stop.setBounds(610, 50, 100,30);
add(start);
add(stop);
start.addActionListener(this);
stop.addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
String c=ae.getActionCommand();
if(c=="Start")
{
while(c!="Stop")
{
h+=20;
w+=20;
}
repaint();
}
str=" "+h+" "+w;
}
public void paint(Graphics g)
{
super.paintComponents(g);
g.drawString(str, 100, 100);
//g.drawOval(100, 100, 100, 100);
g.drawOval((int)Math.random()*2000,(int) Math.random()*2000, w,h);
}
public static void main(String[] args)
{
new p6();
}
}
Let's start with How do I compare strings in Java?. This is pretty basic Java 101 and something you REALLY need to understand.
The move onto Concurrency in Swing. Swing is a single threaded. This means that any long running or blocking operations executed within the context of the Event Dispatching Thread will cause the app to "hang" and prevent any further possible updates or interaction.
Swing is also not thread safe, which means that you should only ever update the UI or state the UI depends on, from within the context of the Event Dispatching Thread.
This might seem like a dilemma, but Swing also provides a useful tool to help work with these constraints, see How to user Swing Timer for more details.
Swing also has a well defined and documented painting process, see Painting in AWT and Swing and Performing Custom Painting to get a better understand of how painting works in Swing and how you're suppose to work with it
It is generally recommended not to override the paint method of top level containers (like JFrame). These tend to be composite components and trying to paint on them tends to end up not working very well.
Image from How to Use Root Panes
And you really should make the time to learn how to use layout managers, see Laying Out Components Within a Container. They will save many hours of frustration. The following examples makes use of both a BorderLayout and CardLayout.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private CardLayout cardLayout;
private JPanel showPane;
private DrawingPane drawingPane;
public TestPane() {
setLayout(new BorderLayout());
cardLayout = new CardLayout();
showPane = new JPanel(cardLayout);
showPane.add(new EmptyPane(), "Empty");
drawingPane = new DrawingPane();
showPane.add(drawingPane, "Drawing");
cardLayout.show(showPane, "Empty");
add(showPane);
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
stopButton.setEnabled(false);
JPanel actionsPane = new JPanel();
actionsPane.add(startButton);
actionsPane.add(stopButton);
add(actionsPane, BorderLayout.SOUTH);
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(false);
stopButton.setEnabled(true);
drawingPane.start();
cardLayout.show(showPane, "Drawing");
}
});
stopButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(true);
stopButton.setEnabled(false);
drawingPane.stop();
cardLayout.show(showPane, "Empty");
}
});
}
}
public class EmptyPane extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public class DrawingPane extends JPanel {
private int h = 0, w = 0;
private Timer timer;
private Random rnd = new Random();
public DrawingPane() {
}
public void start() {
if (timer == null) {
timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
h += 20;
w += 20;
repaint();
}
});
}
timer.start();
}
public void stop() {
if (timer != null) {
timer.stop();
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
int x = 0;
int y = 0;
if (w < getWidth() && h < getHeight()) {
x = rnd.nextInt(0, getWidth() - w);
y = rnd.nextInt(0, getHeight() - w);
}
g2d.drawOval(x, y, w, h);
g2d.dispose();
}
}
}
Why make use of CardLayout?
Based on the original code, when not painting, nothing is shown. So I made use of a CardLayout to switch to an "empty" state. Now, it wouldn't be very hard to derive a model to hold the state information and share that between the "empty" and "running" states and show something different on the "empty" state. Equally, we could make use of the glassPane, but I think we're drifting of course.
The purpose is to demonstrate ONE possible solution for showing different states.
Why use two different panes?
First, we don't "need" EmptyPane, we could get away with just an instance of JPanel, but, if you wanted to display something else when not drawing, this is one approach you could take.
The original code had a if statement which means that when not drawing, nothing is painted, so why waste the time and instead just show a "empty" pane instead.
Again, this is just a demonstration of one possible solution.
You have to add these lines before actionPerformed method,
start.setActionCommand("start");
stop.setActionCommand("stop");

paintComponent not Running [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Basically, I'm trying to do a test on my GUI to make sure it will paint.
Here are my classes:
Game
public class Game {
private static GUI gui = new GUI();
private static int[][] pixels = new int[10][10];
public static void main(String[] args) {
}
public void startGame() {
System.out.print("start");
gui.setGameFrame();
}
public static GUI getGUI() {
return gui;
}
public static int[][] getGraphics() {
return pixels;
}
}
GUI
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class GUI extends JPanel {
private static Game game = new Game();
private static JPanel panel = new JPanel();
private static JFrame frame = new JFrame();
final private static int FRAME_HEIGHT = 500;
final private static int FRAME_WIDTH = 500;
//Board size 25x25px
final private static int PIXEL_SIZE = 20;
public GUI () {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setAttributes();
makeMenu();
}
});
}
public static void setAttributes() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("");
frame.setBackground(Color.black);
frame.setVisible(true);
}
private static void makeMenu() {
JButton start = new JButton("Start");
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
game.startGame();
}
});
panel.add(start);
frame.add(panel);
frame.pack();
}
public void setGameFrame() {
panel.removeAll();
frame.getContentPane().add(Game.getGUI());
frame.setTitle("Snake v0.1");
frame.setSize(getPreferredSize());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(5, 5, 10, 10);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(FRAME_WIDTH, FRAME_HEIGHT);
}
public void paintGraphics() {
int[][] pixels = Game.getGraphics();
}
}
I've attempted to debug it, but cannot trace why it isn't functioning.
I believe it's something to do with:
frame.getContentPane().add(Game.getGUI());
But I'm not certain.
Me: "What's the purpose of the Game class? Why not just run everything from the Gui class? "
You: "because further code will involve logic and event handling, and sending these events to the GUI class for updating."
Think of the Game as your data model. Use the Game class for only data and data manipulation and keep all the GUI procedures in your GUI class. Just create an instance of the Game class in your GUI class. Run the program from your GUI class, i.e. have the main method in your GUI class. and run the invokeLater from the main method.
I copied and pasted your code directly into Netbeans, and it seems to be working.
On mine there seems to be some graphical object covering the top left of the white rectangle, which is why it didn't show up initially.
Try changing your fillRect() function to fill a larger area.
This worked for me:
g.fillRect(5, 5, 100, 100);

Firing delay between JFrame components

I want to show how merge sort perform visually using JFrame. What I want to do is to make visible subsequent JLabel with some time delay. I tried many way but all of them appears at same moment with no intermediate delay.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
// jLabel1.setVisible(false);
jLabel2.setVisible(false);
jLabel3.setVisible(false);
jLabel4.setVisible(false);
jLabel5.setVisible(false);
jLabel6.setVisible(false);
jLabel7.setVisible(false);
final Timer t=new Timer((4000), null);
final int delay=2000;
final ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jLabel1.setVisible(true);
t.getDelay();
jLabel2.setVisible(true);
t.setDelay(3000);
jLabel3.setVisible(true);
t.setDelay(2000);
jLabel4.setVisible(true);
t.setDelay(2000);
jLabel5.setVisible(true);
t.setDelay(2000);
jLabel6.setVisible(true);
t.setDelay(2000);
}
};
new Timer(delay, taskPerformer).start();
But when I click button all the lables appear at same momenet though I have kept delay.
You need to update the icons in the timer's action listener, as shown here. You can implement the Icon interface to render icons having a size proportional to an element's comparative value, as shown here.
Addendum: Can you please be little bit specific?
You want to animate the intermediate steps of sorting a List<Number> of size N in some initially random order. Number subclasses implement Comparable<T>, so compareTo() is already done. A GridLayout(1, 0) of JLabel each having an Icon can be used to display the values. DecRenderer shows how to create icons with a proportional size; you'll want to vary the height over the interval [0, N). GrayIcons & Mad's example show how to animate the display of the icons in some order.
There are a number of reasons why this won't work. Firstly, javax.swing.Timer doesn't work this way. It waits in the background until the given delay has past and then calls the registered ActionListeners actionPerformed method.
Secondly, if it did work this way, it would block the Event Dispatching Thread, preventing it from processing repaint requests.
I think you will find How to use Swing Timers of use.
public class BlinkOut {
public static void main(String[] args) {
new BlinkOut();
}
public BlinkOut() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel[] labels;
private int[] delays;
private Timer timer;
private int index;
public TestPane() {
setLayout(new GridLayout(0, 1));
labels = new JLabel[7];
for (int index = 0; index < 7; index++) {
labels[index] = new JLabel("Label " + (index + 1));
add(labels[index]);
}
delays = new int[] {2000, 3000, 2000, 2000, 2000, 2000, 2000};
JButton hide = new JButton("Hide");
add(hide);
hide.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Click");
index = 0;
labels[index].setVisible(false);
timer.setDelay(delays[index]);
timer.start();
}
});
timer = new Timer(delays[0], new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Tick");
timer.stop();
index++;
if (index < 7) {
labels[index].setVisible(false);
timer.setDelay(delays[index]);
timer.start();
}
}
});
timer.setRepeats(false);
timer.setCoalesce(true);
}
}
}

Progress bar to run simultaneously with a function(in another class)

I have created a form on which two components are present, button and progressbar (Netbeans drag and drop).Form contains the main method from where my application starts.I have created another class as well in which i have written a function.What i want is that when i press a button the application goes into the function and the progressbar runs simultaneously with it and when that function is complete with its functionality the the progress bar shows 100% complete.Now this function can take anytime for its completion so i cannot set the max value for the progressbar.So, what to do in this case?Can anyone please provide me with a good example .
JProgressBar.setIndeterminate(true)
Since what sort of a work you are doing inside that so called "Called Function", so it's tough to say, what you want in the scenario, though you can put your lines like progressBar.setValue(someProgress); at regular intervals with it's Indeterminate State to true, and at the end of the function you can simply say that progressBar.setValue(100); and the Indeterminate State will turn to false here, so that it can show that to the end user.
Have a look at this sample program :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ProgressExample
{
public static JProgressBar progressBar;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Progress Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
JButton button = new JButton("START");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
progressBar.setIndeterminate(true);
WorkingDialog wd = new WorkingDialog();
wd.createAndDisplayDialog();
}
});
contentPane.add(progressBar, BorderLayout.PAGE_START);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ProgressExample().createAndDisplayGUI();
}
});
}
}
class WorkingDialog extends JDialog
{
private String message = "HelloWorld";
private int count = 0;
private JTextField tfield;
private Timer timer;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (count == 10)
{
timer.stop();
ProgressExample.progressBar.setIndeterminate(false);
ProgressExample.progressBar.setValue(100);
ProgressExample.progressBar.setStringPainted(true);
dispose();
return;
}
tfield.setText(tfield.getText() + message.charAt(count));
count++;
}
};
public void createAndDisplayDialog()
{
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setLocationByPlatform(true);
JPanel panel = new JPanel();
tfield = new JTextField(10);
panel.add(tfield);
add(panel);
pack();
setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
}
So , it seems like you are write
ProgressExample.progressBar.setIndeterminate(false);
ProgressExample.progressBar.setValue(100);
ProgressExample.progressBar.setStringPainted(true);
after your while loop.
You can take a look at my answer in a previous SO question, which contains a sample using a JProgressBar which gets updates from another Thread by using a SwingWorker. Whether or not to use a SwingWorker depends a bit on your use case. If the function take some time to run you better use the SwingWorker to avoid blocking the UI.

How to update/paint JProgressBar while Swing is loaded building the GUI

I have a GUI which is quite heavy to build/initialize on the platform on which it runs.. Therefore I want to update progress while it initializes..
I have a small undecorated JDialog containing a JLabel and a JProgressBar which I want to update at specific places during initialization, however, because the event dispatch thead (as per Swing rules) is used to build/initialize the GUI, the progress is of course not updated until the EDT is idle again (i.e. initialization is finished)..
The JProgressBar I have gotten to redraw using "paintImmediately", but I can't seem to make it work properly for the JLabel and the dialog itself.. Is there any simple recommended/proven method to accomplish this?
cheers...
EDIT: Adding an example of what it is I'm trying to do; greatly simplified, of course.
private JLabel progressLabel;
private JProgressBar progressBar;
public static int main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showProgressDialog();
progressLabel.setText("construct 1");
constructSomeHeavyGUI();
progressLabel.setText("construct 2");
progressBar.setValue(33);
constructSomeMoreHeavyGUI();
progressLabel.setText("construct 3");
progressBar.setValue(67);
constructEvenMoreHeavyGUI();
progressLabel.setText("done");
progressBar.setValue(100);
hideProgressDialog();
showHeavyGUI();
}
});
}
the repaints caused by the calls to progressBar.setValue()/progressLabel.setText() above will of course get queued as long as the EDT is busy and result in a repaint after we are all done instead of updating along the way..
I would suggest that by using SwingWorker , then you can update the JProgressBar correctly on EDT and without any freeze or isuees with Concurency in Swing,
there is another option by using Runnable#thread, but then you have to wrapp all output to the GUI into invokeLater();
for example:
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
public class TestProgressBar {
private static void createAndShowUI() {
JFrame frame = new JFrame("TestProgressBar");
frame.getContentPane().add(new TestPBGui().getMainPanel());
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() {
#Override
public void run() {
createAndShowUI();
}
});
}
private TestProgressBar() {
}
}
class TestPBGui {
private JPanel mainPanel = new JPanel();
public TestPBGui() {
JButton yourAttempt = new JButton("WRONG attempt to show Progress Bar");
JButton myAttempt = new JButton("BETTER attempt to show Progress Bar");
yourAttempt.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
yourAttemptActionPerformed();
}
});
myAttempt.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myAttemptActionPerformed();
}
});
mainPanel.add(yourAttempt);
mainPanel.add(myAttempt);
}
private void yourAttemptActionPerformed() {
Window thisWin = SwingUtilities.getWindowAncestor(mainPanel);
JDialog progressDialog = new JDialog(thisWin, "Uploading...");
JPanel contentPane = new JPanel();
contentPane.setPreferredSize(new Dimension(300, 100));
JProgressBar bar = new JProgressBar(0, 100);
bar.setIndeterminate(true);
contentPane.add(bar);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(null);
Task task = new Task("Your attempt");
task.execute();
progressDialog.setVisible(true);
while (!task.isDone()) {
}
progressDialog.dispose();
}
private void myAttemptActionPerformed() {
Window thisWin = SwingUtilities.getWindowAncestor(mainPanel);
final JDialog progressDialog = new JDialog(thisWin, "Uploading...");
JPanel contentPane = new JPanel();
contentPane.setPreferredSize(new Dimension(300, 100));
final JProgressBar bar = new JProgressBar(0, 100);
bar.setIndeterminate(true);
contentPane.add(bar);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(null);
final Task task = new Task("My attempt");
task.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equalsIgnoreCase("progress")) {
int progress = task.getProgress();
if (progress == 0) {
bar.setIndeterminate(true);
} else {
bar.setIndeterminate(false);
bar.setValue(progress);
progressDialog.dispose();
}
}
}
});
task.execute();
progressDialog.setVisible(true);
}
public JPanel getMainPanel() {
return mainPanel;
}
}
class Task extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 4000;
private String text;
public Task(String text) {
this.text = text;
}
#Override
public Void doInBackground() {
setProgress(0);
try {
Thread.sleep(SLEEP_TIME);// imitate a long-running task
} catch (InterruptedException e) {
}
setProgress(100);
return null;
}
#Override
public void done() {
System.out.println(text + " is done");
Toolkit.getDefaultToolkit().beep();
}
}
EDIT:
1) you showed another issues, why do you create lots of Top-Level Containers on Fly/Runtime, create only required numbers of Containers and re-use that by removeAll()
2) here is probably what you needed, all those JProgressBars in the JTable are pretty accesible and configurable
3) this is your paintImmediately(), that really reason why not painting any of Progress to the JLabel but using JProgressBar#setValue(int);
instead,
It's possible that constructSome*HeavyGUI() really takes long enough to matter, but it's more likely that filling in the data model(s) is the problem. Instead, construct and show the empty GUI elements and launch one or more SwingWorker instances to marshal each element's data. There are related examples here and here.
Addendum: If the problem is instantiating components, and not loading data models, you can chain the calls to invokeLater(), as suggested in a comment below. If you're instantiating that many components, consider the flyweight pattern. JTable is a familiar example.
Move the long running code in a separate thread and use SwingUtilities.invokeAndWait or invokeLater to update GUI.
Either use SwingUtilities.invokeLater(...) as suggested by #StanislavL, or use SwingWorker.
See also:
Worker Threads and SwingWorker

Categories

Resources