-1

I have done some digging around on this, however, I still can't seem to figure it out. Please excuse me, I haven't been programming for long.

Background: When I click on my run button it should create a second JFrame and update the background colours of JPanels on the second frame, periodically, once per iteration, throughout the run that the JButton starts.

Problem: The second frame is created, but stays blank until the loop, started by the JButton is finished, and it only displays the final state.

I have tried: invalidate(), validate(), repaint(), setVisible(true). I have tried to run it in a separate thread. I have even tried sleep(), in case it doesn't have enough time to update. Is there something else that I can try?

kalibra
  • 139
  • 1
  • 5
  • You need to share your code so we can see what's going on - but please try to cut it down to a small enough sample. I would hazard a guess that you need to be using SwingUtilities.invokeLater .... – tddmonkey Jan 19 '15 at 10:50
  • 4
    1) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) 2) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Jan 19 '15 at 10:54

2 Answers2

0

I think I would have overwritten the void paint(Graphics g) method which is called by the OS when redrawing is needed and add your drawing routine there. Don't forget the super.paint(g) call. You can then manually trigger redrawing (from inside your loop) by a call to void update (Graphics g); (calling void repaint() should work too)

Byte Commander
  • 6,506
  • 6
  • 44
  • 71
  • Unless you're doing custom graphics there's no need to override `update(Graphics g)` – tddmonkey Jan 19 '15 at 11:22
  • "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[*Painting in AWT and Swing: The Paint Methods*](http://www.oracle.com/technetwork/java/painting-140037.html#callbacks). – trashgod Jan 19 '15 at 12:12
0

The second frame is created, but stays blank until the loop, started by the JButton is finished, and it only displays the final state

If your ActionListener attached to the JButton (or the Action) is implemented like

public void actionPerformed( ActionEvent e ){
  updateColor();
  ...
  updateColor();
  ...
  updateColor();
}

then the behavior you are seeing is exactly as expected.

Swing is a single threaded framework. When your ActionListener updates the background color, a repaint will be scheduled (emphasis on schedule, which is something different from performed). Since your loop in the ActionListener is still occupying the single thread (the EDT), the repaint cannot be executed.

As such, the first time the repaint can be executed is after you have released the EDT by finishing your loop. At that moment, the background color has already changed to its final color, and that is all what you will be seeing.

A possible solution to be able to see the background change is to use a javax.swing.Timer (and not the java.util version). A click on the JButton can start the timer, and each time the timer is triggered you change the background color to the next color. The moment the final color is reached, you stop the timer.

Robin
  • 36,233
  • 5
  • 47
  • 99