My application does not paint itself on startup. When resizing it or minimizing/maximizing it, the window of the application is painted.
This problem only appears on Windows machines (I tested XP, Vista and Windows 7). On Mac OS X and Linux, the application works fine.
The machines have installed java 6. My application uses the AWT, so not Swing. I tried using Swing (so JFrame in stead of Frame), but this does not solve the problem.
I checked the calls on repaint(), update() and paint() of the frame. They all appear, and the image to draw is available. I also checked if these calls are done on the EDT thread. This is the case. When the window is resized (or min/max-ed) a call on paint() is done by the system, and the image is drawn.
My fear is that I'm missing something really obvious. I'm making the frame visible, validate it (also tested with invalidate) and repaint it. This is sufficient in Mac OS X and Linux.
Does somebody have any suggestions to what I should do, or what else to try?
Thanx in advance
Maurice
My guess is that you are overriding Frame.paint. You will probably get better results from painting to a JPanel (or Canvas, if you insist on the obsolete AWT), and when you do that, make sure you're overriding JPanel's paintComponent, rather than paint. In some cases, a JLabel with an ImageIcon can be simpler still.
As others have suggested, though, try to post a test case.
You might want to check out this debugging trick using a custom RepaintManager. It helped me track down some tricky intermittent swing glitches.
http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html
It is difficult to diagnose the problem without seeing any source code, but is the image fully loaded?
AWT loads images in the background after, so even though a call to Toolkit.getImage() may return a valid Image instance, this does not mean that the image is loaded by that time. You can use a MediaTracker to track this.
Related
I need to do a loading window in java like this:
I tried with the jframe but I can't figure it out, I can't remove the close button, my jframe should look like a jpanel before that program begin, somebody know how to do this.
You Could...
Use Java's inbuild splash screen support. This is good as it gets loaded relatively earlier in the process by the JVM itself, so it comes up reasonably quick.
The major drawback (in my opinion) is it can be troublesome to get right as it doesn't follow the standard painting process that most developers are use to and you are going to have to paint it all yourself, there's no component support
How do I use SplashScreen without throwing a NullPointerException?
How to Undo the splash screen painting in java
Splash Screen Progress bar not drawing
You Could...
Create a JWindow. This is a frameless window, which won't appear on the taskbar (at least for some OSs).
You gain complete control over what and how things get displayed, as it's like dealing with any other window.
The only problem is that it won't become available for you to load until the JVM has completed loading your application. If the JVM needs to download resources over the network, for example, this could produce an undesirable delay
For example
Splashscreen in Java
SplashScreen java change alpha
Why won't this draw the image?
You Could...
Use an undecorated frame. This is pretty much the same as the JWindow option, except that a taskbar icon will be displayed, but on some OSs, this can't be completely helped.
See Frame#setUndecorated for more details
Final thoughts
Swing is not thread safe. So if you're displaying a splash screen, this means you should be ensuring that whatever actions you are taking are done off the Event Dispatching Thread, possibly through the use of SwingWorker
Is it possible to simply paint() (or use some other function) to the screen in Java? As in draw over everything else on some coordinates of the screen itself, not inside some window.
If not, is it possible to make an invisible window that takes up the entire screen and use its glass pane to do it? Would complications arise from doing this? (Such as not being able to click on other applications)
Are there any other ways?
Thanks.
Edit: I'm not trying to do full screen with this, by the way.
When you paint() in Java, you're painting only within the confines of the size and location of what is being paint()ed.
If you're looking to do full screen stuff, there are tutorials for that:
http://download.oracle.com/javase/tutorial/extra/fullscreen/index.html
In theory, you can create an transparent undecorated maximized JFrame. This will allow you to "paint" over the desktop. Problems are obvious: if an application stays behind this window, it will not receive any mouse events.
Months ago, I made an evil cheat to draw directly on Windows Explorer's Desktop: mixing some .NET coding with JNI and Sun's internal classes - that's surreal, but works.
We have a problem in our swing based application since we've upgraded our java version from 6u5 to 6u18 (The application runs over WinXP).
Our application contains a Canvas object which resides in a JFrame. The application draws things on the canvas.
Every time we drag a lightweight swing object (popup or another frame) over the canvas, it has a refresh problem.
It blinks - becomes black. The problem only resolves after we move the swing component away from the canvas and click on it again.
We think this problem is related to the fact the the canvas is a heavyweight object.
And we know there were changes done in the new versions of java on the mixing of heavyweight and lightweight objects issue.
Some more details:
1) Our problem reproduces in java 6u14 and 6u16.
2) Everything works fine in java 6u5.
Another strange thing:
We have 2 types of stations running our application.
The first type has a ATI FireGL7100 PCI-E graphics card. The second type has a Matrox G450 PCI graphic card.
The problem does not reproduce on the Matrox based station in any java version.
One more thing:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6829858 - looks similar to our problem.
Is our problem familiar?
Do you have any suggestions (workarounds, ideas how the difference in graphics cards is connected to this problem)
Hope I was clear enough,
Yoav
The article Mixing heavy and light components describes how support for this changed in JDK 6 update 12. The two video cards may handle Z-order differently. Any chance your code has a workaround that's no longer needed?
We had problems w/ HW/LW mixing from 6u14+ (the fixes that breaks everything is in 14). Our problem was in a thirdy part library (JIDE) and they ended up fixing the problem on their end.
My suggestion is avoid HW where ever you can. You can get very decent performance out of LW if done correclty. What are you drawing that needs to be HW?
I don't know if this is relevant to anyone else, but we've found a workaround/fix for our problem.
We've set the system properties sun.awt.noerasebackground and sun.java2d.noddraw both to true. That eliminated our issue.
The only problem is that I'm not sure what other problems might rise from setting those system properties.
We have a Java Applet built using AWT. This applet lets you select pictures from your hard drive and upload them to a server. The applet includes a scrollable list of pictures, which works fine in Windows, Linux and Mac OS X 10.5. We launch this applet via Java Web Start or within a web page.
Our applet does not behave properly in Mac OS X 10.4, regardless of the version of Java (1.4 or 1.5). You can find a screenshot of the incorrect behaviour, when scrolling, here:
http://www.lavablast.com/tmp/ui_error.png
Simply put, sometimes when scrolling the pictures end up overlapping the header or footer of the application. This behaviour does not occur on other platforms. On Mac OS X 10.4, it shows the pictures in the incorrect location when scrolling, which would not be so bad if it refreshed the screen after painting the image at that location. However, it does not appear that the application knows it painted it incorrectly and thus does not refresh.
If the window is minimized, resized or even moved, the application is refreshed and the incorrectly positioned elements vanish and the application resumes normally. I spent quite some time trying to force a refresh of the background image unsuccessfully. (the repaint the image directly, repaint all children of a few panels, etc. ) Thus, I am looking for any tips that would help me resolve this problem under Mac OS X 10.4 or, in the worst case, simply simulate a full applet refresh.
Until recently, everything was compatible with Java 1.1 but this has changed in a few locations which now require 1.4. I don't feel these changes created the issue, I am just providing this as extra information. If you are interested in implementation details of the scroll panel, I will investigate, but I am assuming this is a common platform bug for which workarounds must be known.
To replicate the problem, open the following Java Web Start application:
http://www.lavablast.com/tmp/opal-webstart.php.jnlp
Select a folder containing lots of images and play with the scrollbar. At some point (fairly quickly), you should get the refresh problem.
Edit: I followed the first suggestion here and replaced all my controls that feature background images with a Swing equivalent and the issue is still there. (Plus, there are numerous other fixes I would need to do to do a complete change). Any other ideas? A simple one line of code that forces a full refresh would be great :)
Edit2: The main thread creates the panels and launches X threads. Using an observer/notifier pattern, the threads complete and notify the main control, which adds a panel to the page. This is done via an EventQueue.invokeLater which, unless I am mistaken, should run on the right thread. The issue is at its most severe when scrolling even if no extra threads are running (as during the loading).
It does look like mixing lightweight (usually Swing) and heavyweight (AWT) components together. Moving to Swing you need to replace every last AWT component Swing equivalents (hint: avoid import java.awt.*).
Threading is often a potential problem for odd bugs. Swing components must always be used on the EDT (use java.awt.EventQueue.invokeLater). AWT is thread-safe is theory, but not in practice - also restrict usage to the EDT.
As you already require Java 1.4 you should consider some small changes to take into use SWING GUI instead, it solved our Applet refresh issues with AWT. (Mac, Linux etc)
If you have e.g. Panel, you need to replace it with JPanel etc.
You need this:
import javax.swing.*;
I made a Java Applet with some Standard GUI Components on it. I used the MigLayout Manager.
If I move the mouse slowly over the various GUI Components everything appears to be fine, but if I move the mouse fast, it flickers.
What could make that nasty ugly redraw?
(Core 2 Duo 6300, 2GB Ram, Windows XP)
One thought would be to check your code (and/or the MigLayout code) for unnecessary repaint() operations.
Custom UIs and layouts can cause weird problems sometimes...
you could use double buffering in java applet to improve screen refreshing speed. ask more if details needed..
I found the bugger:
I used a custom ClosableTabbedPaint Class.