I am wondering if there is a platform independent way of finding the height of caption of Desktop.
As per post Determine the size of caption windows 7 using java AWT their exists a platform dependent way for windows. Is there any generic API that can be used to fetch the caption height (which works for MAC, windows, Linux etc).
You could try using the JFame.getInsets() method.
It's not entirely accurate (as it gives the height of the entire title bar, not the caption height), requires the frame to be visible, but is probably the closest you are going to get without requiring a JNI solution.
For example, on Windows, getInsets gave me a top of 30, but win.frame.captionHeight gave me 21
You can have a look at further discussions on the top here
As a work around to this use case, I implemented the following steps:
Create a frame of size 800 x 600 and then
Use the getInsets() method to get the caption height and then re-size the frame.
Related
I have a component placement problem. First I'll try to give (possibly useful) information and then tell you about the main problem:
My System: Windows 8.1 64bit, Java 1.8.0_60 32bit
What I'm trying to do is: After I learn screen resolutions of all connected screens, I'm placing some swing components around the screen. This means that I need to know the resolutions of the screens.
I'm using multiple monitors.
3840 x 2160 (main monitor)
1920 x 1080 (secondary)
I use:
graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
devices = graphicsEnvironment.getScreenDevices();
And for the main screen device:
devices[i].getDefaultConfiguration().getBounds()
returns [0, 0, 2560, 1440]. Instead of the right values 3840 x 2160.
Interesting thing is;
devices[i].getDisplayMode().getWidth() and getHeight()
returns the right 3840 and 2160 values.
Note: This difference does not happen in any other resolution selection of the screen. For example, if I select 1920 x 1080 for the main screen, both "getDefaultConfiguration().getBounds()" and "getDisplayMode().getWidth()" returns the right values.
Now,
You can say that I'm already getting the right dimensions. So, what is the matter?
The thing is, when I try to position my SWING components, they are placed in wrong positions. For example, an element at [3750, 0, 10, 10] ends up inside the second monitor, while It should have been on the right upper corner of the first screen.
Another example: As you know, a fixed sized component would appear smaller in higher resolutions. Since its pixel percentage related to screen gets smaller, the component itself also looks smaller. For example; When I increase my screen's resolution from 1920x1080 to 2560x1440, my components gets smaller. But, when I increase the resolution from 2560x1440 to 3840x2160; they stay in the same size.
I hope I was clear about the problem.
I know of one Windows 8+ specific feature, which might manifest in that way: per-display DPI setting. The feature is supposed to keep application window at the same size physically, even when dragging them across displays with different density.
This is achieved by rendering the application's window into a intermediate buffer, which then is scaled by the DWM taking the target screen DPI into account.
This feature can be disabled, using following dialog:
It has to be done on the file containing the executable program, which displays any frames. In Java, it's somewhat convoluted, since it's a hosting application. Changing this on java(w).exe should alter the behavior globally.
Typically, this kind of flag adjustment is done by a software installer. It's possible to wrap the java jar into a exe with a thin wrapper. I like launch4j the most for this task. The wrapper exe and the jar file can be wrapped into a installer script, which sets the flag at installation time.
Hi everyone I've recently come across the problem that now days some monitors have different DPI settings, some monitors are much more dense such as, for example, Apple's Retina displays.
How would one compensate for the different DPI settings and densities on various monitors with Java? Is it possible to scale the controls to be the same size on any monitor. I know when programming for Android all measurements are in "DP" and you can specify different images for three different display densities.
Is there a way I could choose different images using Java / Swing for different display densities so my application doesn't look blurry on higher density monitors? Or is this not that important or possible? I know Chrome currently doesn't take into account DPI but Internet Explorer and other apps do.
Thank you for your help, I'm a long time Java developer I've just never thought about DPI before and was wondering how I might go about it :)
First, trust the platform's Look & Feel designers to choose sensible default sizes for text and controls. Then, avoid the temptation to frustrate those defaults. Here are some heuristics:
Use layouts; when contemplating absolute positioning, consider a custom layout.
Respect the preferred size of components.
Avoid non-resizable components.
In animation, scale graphics to the size of the enclosing Window.
Test across a range of platforms, using emulation as required.
First thanks trashgod for the useful links you provided for they were very helpful.
Below I have listed some specifics on how to deal with issues concerning DPI changes that I have run into.
Font Issues:
If the font is not fitting in the component then look at Component Sizing Issues below for often the component is not sizing to what is inside. Otherwise in a JLabel you can apply HTML tags to automatically line wrap the text (there are other solutions but this works for me).
If the component's text is naturally the default font, size, and style (Tahoma 11 plain) then everything is automatically done for you. Know that user574171 gave pictures showing different font and layout managers issues and strengths in his link to http://kynosarges.org/GuiDpiScaling.html in his answer to How to set the DPI of Java Swing apps on Windows/Linux?. This question here is asking about the "Swing" issues but his link is useful in also comparing WPF, JavaFX, and Swing layouts with a basic components and different fonts. You can see there the "Swing a" font is the best, that is Tahoma 11 Plain. However it only works if the component is naturally the default font, size, and style (Tahoma 11 Plain). This means bolding, underlining, sizing, and a different font for the text will throw off the auto sizing for different DPI.
If the text is the default font (Tahoma) but bolded, underlined, or a different size then the text does not scale for different DPI's. To fix the scaling for different DPI's then check the box labeled "Derive the font from the default font." The "Relative" option will take the default DPI scaling font and apply your relative changes such as bigger or smaller, bold, and underlined. Also know that if the component is a JLabel then DPI scaling is automatic using HTML tags despite how you format the text (line wraps too).
If the component is not naturally the default font, style, and size (Tahoma 11 plain) or you want a different font (ie not Tahoma) then you need to associate the changes in another component that is naturally the default like a JLabel. Therefore if 125 DPI increases the font by 3 then you increase your desired font by the same.
Component Sizing Issues:
All components have a preferred, minimum, and maximum size properties but I have found that they do not play well with DPI changes. The "Respect the preferred size of components" bullet in trashgod's answer tells you all about it. To summarize let the default size of the component take care of itself for it will try to size to whatever is inside.
If the component can use the default sizes then DPI handling can be done for you. Just as trashgod's said "First, trust the platform's Look & Feel designers to choose sensible default sizes for text and controls. Then, avoid the temptation to frustrate those defaults." Again, the component of the default size usually sizes to what is inside (or acts re-sizable). From my own experience when I set re-sizable components I do it via "Horizontal Resizable" or "Vertical Resizable" for I have found it works very well with DPI changes as well as window resizing.
If the default size does of the component does not work then first try looking below at some specific issues I found. Alternatively try scaling the component according to changes in a component that does get scaled right. IE, apply ratio of what you expected the scaling component to be at 100% DPI and the change to the new DPI. Examples of components that need to be scaled to other component changes would be one that it's text is filled by code or it is an image.
As a last resort use a JScrollPane to allow the user to scroll to see the whole thing. If the window/dialog is fairly large then a JScrollPane is a great idea because if the DPI is higher for the user's eyesight then the window often is bigger than the screen.
Note:
I have found that encapsulating groups of components in a JPanel helps swing handle DPI changes a lot better.
JTextField Size Issues:
Set the columns property and nothing else but the text if you wish. The columns property is the number of letters or numbers you want to show. Typically used when allowing the user to enter a number. Know that the columns property works great for multiple platforms.
JSpinner Size Issues:
Set the model to be accurate, valid, and default values. Therefore the auto-sizing of the component is done for the max value and works great for DPI changes and other platforms.
Table Row Height Issue:
Table row height does not change with higher DPI. I encountered this issue and it seems to be due to me trying to be compatible with older versions of Java. To fix multiply the change in font size ratio or change in JLabel height ratio due to the DPI change.
Use JRE 9 (or greater).
This is because the Java runtime (older versions) declared themselves to be "DPI-aware" but didn't really supported it for AWT and Swing. Java applications were sized and rendered based on pixels rather than being properly scaled, this included HiDPI displays.
Anyways, this has been recently solved.
See the issue JEP 263: HiDPI Graphics on Windows and Linux
and the upgrade.
So, increasing the font size does not work (because it does not increase the rest of the things); the jvm argument -Dsun.java2d.dpiaware=false does not work (because it is not really supported); and the manifest file + registry edit (for Windows) just does not work.
Then, You need to run it on JRE 9 because it really supports this feature.
By using
System.setProperty( "sun.java2d.uiScale", "1.0" );
in your java code, ui scaling should be deactivated.
I create Java ME application in Netbeans. I use a splashcreen and I put an image on it. I want this image to be scaled, so it has a right size on different screens - bigger ones and smaller ones. How can I do that?
If I remember correctly there is a method that you can call that will get the height and width of the screen that is currently in use. You can then use these values to re-size you image as needed. Here is an example of getting the height and width:
http://www.java-tips.org/java-me-tips/midp/how-to-get-the-size-of-mobile-screen.html
Hope this helps!
there is no image prossing api in midp 2.0 spec. so you should use 3rd library of function. you can use lwuit library. it has many image process functionality.
http://lwuit.java.net/
This is Simple One Example to show you Splash Screen in JavaME
Thanks
I was trying to create a rectangular image where will be 2 things.
A label (100% width and 20% height)
A Text Area (100% width and 80% height)
So lablel will be at top and text area will be at bottom
so I tried to create a JFrame and place both components there. Then I am creating its image with JFrame.createImage(width, height) and in last I used ImageIO.write(). but problem was, There was some extra blank space around the components in Image. When I tried to set its bound then it create an exact image but this image works perfectly on Windows but it doesn't work on Mac. Any idea why?
Is there also another easy way where I can achieve this. I've spent 2 days but couldn't found any solution.
Please advice
Thanks in adnvace
Rendering using Swing components is very versatile, but the user interface delegate for each component varies by platform. Similarly, font metrics also vary by platform and vendor. If you need very fine control over the placement of text, you can access the graphics context's font metrics as seen in this example, and you can mitigate aliasing as shown here.
I am looking for ways to zoom in a Java Swing application. That means that I would like to resize all components in a given JPanel by a given factor as if I would take an screenshot of the UI and just applied an "Image scale" operation. The font size as well as the size of checkboxes, textboxes, cursors etc. has to be adjusted.
It is possible to scale a component by applying transforms to a graphics object:
protected Graphics getComponentGraphics(Graphics g) {
Graphics2D g2d=(Graphics2D)g;
g2d.scale(2, 2);
return super.getComponentGraphics(g2d);
}
That works as long as you don't care about self-updating components. If you have a textbox in your application this approach ceases to work since the textbox updates itself every second to show the (blinking) cursor. And since it doesn't use the modified graphics object this time the component appears at the old location. Is there a possibility to change a components graphics object permanently? There is also a problem with the mouse click event handlers.
The other possibility would be to resize all child components of the JPanel (setPreferredSize) to a new size. That doesn't work for checkboxes since the displayed picture of the checkbox doesn't change its size.
I also thought of programming my own layout manager but I don't think that this will work since layout managers only change the position (and size) of objects but are not able to zoom into checkboxes (see previous paragraph). Or am I wrong with this hypothesis?
Do you have any ideas how one could achieve a zoomable Swing GUI without programming custom components? I looked for rotatable user interfaces because the problem seems familiar but I also didn't find any satisfying solution to this problem.
Thanks for your help,
Chris
You could give a try to the JXLayer library.
There are several tools in it, which could help you to make a zoom. Check the examples shown here. I would recommend you to read more about the TransformUI, from this library. From the example, it seems like it could help solving your problem.
Scaling the view is easy enough; transforming mouse coordinates is only slightly more difficult. Here's an elementary example. I'd keep JComponents out, although it might make sense to develop an analogous ScaledComponent that knows about the geometry. That's where #Gnoupi's suggestion of using a library comes in.
hey you can try this if you want to zoom a image like any other image viewer the use a JPanel draw an image using drawImage() method now create a button and when you click the button increase the size of the panel on the frame it appears as if the image is being viewed in Zoom
You might find Piccolo2D.java API useful: http://code.google.com/p/piccolo2d/
It is very simple.
It touts in particular its smooth zooming. You essentially make a "canvas" that can contain various elements, and can then zoom by just holding right-click and panning the mouse back and forth.
I worked on a team that used it to create this: http://sourceforge.net/apps/mediawiki/guitar/index.php?title=WebGuitar#EFG.2FGUI_Visualizer
The nodes you see there are clickable links themselves.
Since Java 9, there are VM arguments (actually meant to be used for high dpi scaling) that can render a application with a higher scaling factor:
java -Dsun.java2d.uiScale=2.0 -jar MyApplication.jar
Or:
java -Dsun.java2d.win.uiScaleX=2.0 -Dsun.java2d.win.uiScaleY=2.0 -jar MyApplication.jar