Forums Register Login

Updating JFrame is too slow (Fullscreen)

+Pie Number of slices to send: Send
I'm trying to simulate an LED display for a device. Right now I'm drawing one image to a fullscreen JFrame, updating the image depending on which LEDs should be turned on. Right now it seems to update far too slowly, for example everything turns on at the end of the "Exposure" loop. I had a sample running alright before drawing to a JPanel canvas, but now I'm running into issues when full screen. There are comments spaced through the code showing how the JPanel was set up in this newer version. Any suggestions to get headed in the right direction?

Also, this is set up fairly poorly in two classes because I'll need a while loop running at one point (single LED blinking on/off until keypress), and I need to set up the KeyListener in another thread I think.
_____________

Some sample functions:

Start:

Ask for "Exposure Time"
User will input 6, 7, 8, 9, or 10
"Exposure Time" divided by 4 = sequence time (in seconds)

When user pushes the "p" key (power):
turn on LED 1

Exposure:
When the user push the "s" key (start):
Delay .2 seconds
Turn on LED 3
Wait "sequence time"
Turn on LEDs 4 and 5
Wait "sequence time"
Turn on LEDs 6 and 7
Wait "sequence time"
Turn on LEDs 8 and 9
Wait "sequence time"
Turn on LEDs A and B

_____________







+Pie Number of slices to send: Send
A few things I quickly saw:

1) You are updating the user interface from a thread that is not the Event Dispatcher Thread. You shouldn't; read Concurrency in Swing for more information.

2) You are starting the thread before the object has completed its initialization. This could potentially lead to problems, like NullPointerExceptions etc. If you really need to start the thread (which you don't with the current code), that should be done at the end of the constructor. Even better is to use either a Swing timer (if you need to do something on regular intervals), or a SwingWorker. The latter has methods publish / process with which you can perform updates to the user interface.

3) You override paint of the JFrame itself. You should instead create a new JPanel sub class which overrides paintComponent, and set an instance of that JPanel sub class as the JFrame's content pane.

4) You are calling paintComponent directly. You should instead call repaint().

5) Your JPanel should not call super.paint(g) from paintComponent, but instead super.paintComponent(g). This should also be the first statement of the method.


This last one is actually the main reason for your slowness. When your panel is painted, it calls paintComponent. This will call paint. This in turn will lead to paintComponent to be called. This will again call paint. This will continue forever; your CPU is being hogged by constant repainting.
+Pie Number of slices to send: Send
Thanks for the quick reply!

For those changes:

1) TODO

2) Starting the thread at the end of the constructor now.

3) JPanel subclass added to the content pane.

4) Changed to repaint(), but see below.

5) Got it! Changing super.paint(g) to super.paintComponent(g) got images to draw to the JPanel while fullscreen. Thanks.

However, there's still a delay with repaint(). Specifically, the screen now goes white until the "Exposure" sequence has run through. But if I run the sequence a second time while the same instance of the program is still up, it runs smoothly. Would using BufferedImage solve this problem, and do you have any advice on its use here?
+Pie Number of slices to send: Send
 

Matt Metzger wrote:However, there's still a delay with repaint(). Specifically, the screen now goes white until the "Exposure" sequence has run through.



Rob Spoor wrote:5) Your JPanel should not call super.paint(g) from paintComponent, but instead super.paintComponent(g). This should also be the first statement of the method.



Did you make that change?

And since this is related to GUIs, I'm moving this thread to the section where we usually discuss such things.
+Pie Number of slices to send: Send
 

Rob Spoor wrote:5) Your JPanel should not call super.paint(g) from paintComponent, but instead super.paintComponent(g). This should also be the first statement of the method.



I had made this change, but with the same results. And strange, but after removing any sort of super calls within paintComponet() the flickering has stopped. Every call to drawImage() is redrawing over the entire JPanel; maybe that's got something to do with it. Not quite sure what's up, looking into it still, but it's working well. Thanks.
+Pie Number of slices to send: Send
You're calling exposure() on the EDT. This will block the entire EDT until the method is done. During this time the EDT will do nothing, including (re)painting. I suggest you read the Concurrency in Swing article now, because it will explain what's going wrong and how to solve it.
Arch enemy? I mean, I don't like you, but I don't think you qualify as "arch enemy". Here, try this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 4138 times.
Similar Threads
Repainting within a applet
How to set the bitmap height at runtime
Need help extending a file to read an image from a path
Scrolling BufferedImage
placing an image into a panel
More...

All times above are in ranch (not your local) time.
The current ranch time is
Apr 16, 2024 01:02:14.