I have a small java application with a swing gui. I have set a fixed size for the window and everything works really well. But when using the GUI on different screens, the objects seem to have moved slightly. (Labels not showing their entire text etc,...) I think the difference lies in the aspect ratio of the screen but is there any way to counter this?
The way to counter it is to not used fixed size windows.
I agree with Bryan. There are many reasons - the screen resolution, localization (if you do so), different look-and-feels and rendering depending on the platform and/or JVM version. Swing's layouts are flexible enough to do everything you want without fixing the frame size. Otherwise you are going to implement your rendering engine to calculate everything which is rendered.
Related
On previous windows systems (and till some point also in Win10) any java swing app have a 1:1 pixel matching with display.
Now when I run the app with JFrame size 1920x1080 on 1920x1080 monitor, it looks like it is about 2/3 of the screen size. It looks like all the application GUI is squized (by downscaling) to fit into 2/3 of the display reslution. This makes everything looks awful.
Now any swing app is scaled down, and the pixels aren't anymore 1:1, this makes the cleartype text look awful, as well as other parts of the GUI, in many cases this render the GUI too small to be usable.
I need to run this app on clients computers, the GUI needs to be appealing, it would be best if I could do it without the need to manually change something in their operating systems.
How could I fix it?
Is there a way to tell the javaVM|win10 to not scale a particular java application?
I have written a Java UI using the SWT UI library and the MigLayout layout library.
This page shows screenshots of the UI on Windows, Linux and OSX: http://mchr3k.github.com/org.intrace/screenshots.html
On Linux and OSX my UI has a lot more padding and spacing which I feel wastes a lot of screen space. Is this normal for these platforms? If not, what is the best way to work around this?
EDIT: the linked screenshots have now been updated and no longer show an extra gap on OSX as I have explicitly set the margins on some of my UI elements to 0. The OSX UI is still quite spaced out but I assume that this is correct for the platform.
This is Mikael Grev, the creator of MigLayout.
As someone else mentioned this is a feature of MigLayout. Instead of using x number of pixels (you can of course use that too) by default it is using gaps like related, unrelated and paragraph. These correspond to different sizes in different UI toolkits. For instance on OS X the recommended white space between components is larger than on Windows.
So, yes, this is how it's supposed to look and it will look correct for a native OS X user.
You do seem to have too much white space at the bottom of the Output pane though, in both OS X and Windows.
You can use the PlatformDefaults class in MigLayout to either force a platform or to change the default gaps. Check the source code if you want to know what's happening behind the scenes.
And remember, this is a feature so that every developer won't have to keep track of how to spacing should look like on different platforms, which is kind of hard.
Cheers,
Mikael
That's actually a feature of MigLayout, if I recall correctly. If you don't want this I am sure you could so configure MigLayout. Otherwise, you could use a different layout manager (but I still highly recommend a table-based one) which uses constant spacing for all platforms (such as my MatrixLayout).
I am currently toying with the idea of converting a small/medium sized project from AWT to SWT, although Swing is not totally out of the picture yet.
I was thinking about converting the main window to an SWT_AWT bridge object, but I have no idea how the semantics for this work. After that, I plan to update dialog for dialog, but not necessarily within one release. Is this possible?
Has someone done a conversion like this and can give me some hints? Is there maybe even a tutorial somewhere out there? Is there maybe even a tool that can automate parts of this? I have tried googling, but to no avail.
Update: One additional thing is: Currently, this is a netbeans project. Might be of help or not, I don't know.
We have done this quite a few times. But only because we are going from a Swing application to an Eclipse RCP application not because we like messing with things. This project will really let you know whether you've separated your controller/model code from your view code.
One suggestion is to not try and convert everything all at once. You will end up with a bunch of mixed code that doesn't work at all. You can start at converting portals. I would consider a portal anything within a Tab, Dialog, or Window, essentially self contained unit. If you have a window that opens up, create the Window in SWT, but make it's contents the existing AWT/Swing. This should be fairly straight forward and allow you to get used to the (I really hope they weren't drunk and had a good reason for this) way of instantiating and associating parent/child controls.
One gotcha that can occur is with transparent components. Swing, with the exception of a "window" class is all rendered in Java. This makes it very easy to render things the way you want them. In SWT, there are some restrictions:
Borders. If you use SWT.BORDER you are stuck with whatever color the native component uses. Your best bet is to use a PaintListener and render your own borders if you want them in a different style or color.
Transparent labels, progress bars. I have not been able to get Labels or Progress Bars to have a transparent background. If you want them to take on the parent color, or drawing you will need to render the text and other controls yourself.
Controls. There are composites and controls in SWT. Think of Controls as the basic native controls that do all the native API calls. These cannot be subclassed, which makes things difficult.
Tables will give you the most trouble. Make sure everything is stable before you attempt to convert a JTable to a Table or TableViewer. You will spend some time on these, especially if you have custom editors and viewers.
I have not researched why SWT was designed the way it was. I am guessing there HAD to be a good reason. It would be great if someone had a blog or defense to it's design so I don't have to search for it. Once it's posted I'll remove these lines since they have no relevance to the question.
Addition
I want to add that since you have an existing product I assume works. The best piece of advice I can give you is to never let your code get into a state that it cannot compile and run. If you work on your conversion and whatever you check in always runs and executes (despite the visual differences between SWT/AWT/Swing) you will save yourself many headaches in the long run. The worst thing you can do is try to tackle this all at once and get your code in an unstable state for weeks at a time.
I would suggest importing it into a WindowBuilder project, as WindowBuilder gives you the ability to parse existing code and create a GUI mock-up, then morph components to either SWT or Swing.
If you're thinking of using a mix of SWT and Swing in the same application, this Eclipse Corner Article will be immensely useful.
We are preparing the same step: Swing to SWT/JFace. First we try to determine the bottlenecks: reimplement special components derived from JComponent with SWT/JFace, search for a replacement of JIDE docking (we want to use SWT/JFace, not RCP to avoid too much hassle). The worst thing we already imagine is, that in Swing you could create components and adding it later to the parent. With SWT this is not possible: the parent component must be passed as a reference to the child component's constructor. This will require major refactoring in the Swing application before using SWT.
Frankly, we rate the conversion a very heavy change, because we expect the time where nothing can be compiled as quite long. We try to decrease this time by preparing everything as good as possible, but we'll see how good it will work.
Update from April 6th 2011:
We now refactored our Swing application to always create components with their parent (as in SWT). Our subclasses of JFrame and JDialog got refactored to just have a JDialog instance to make it easier to switch to SWT's Shell. In parallel, we rewrite sophisticated components in SWT.
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.
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.