In my app I'm using swing and awt. I am setting the size (and position) of the window I'm creating based on toolkit.getScreenSize() and this works fine. But I would like to deal with the size of the windows 7 task bar at the bottom (or wherever) of the screen. I can not seem to find out how to do this. Anyone know how I can get the size if the task bar?
You'll want to look at java.awt.GraphicsEnvironment#getMaximumWindowBounds(), which returns the bounds of the screen area excluding the area covered by "objects in the native windowing system such as task bars and menu bars".
Per Matthew's post I got going down the right path. I was able to determine the windows bounds of the task bar with:
Insets scnMax = getToolkit().getScreenInsets(getGraphicsConfiguration());
taskBarSize = scnMax.bottom;
and then subtracting that value from a getScreenSize() height value to help me position the app window correctly.
Don't have a multi monitor system so I'm not sure how this works there but I will have to test that out.
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.
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.
I created a program that deals with combo boxes, and I ran across a problem a Mac user showed me. Mac apparrently resizes JComboBox's and JButton's even if I set the width. The width of all the combo boxes on Windows are different since they are supposed to, but on OSX it's all the same width and size making it impossible to read half the entries of in the combo-box because it's all cut off when you try to select a selection. How can I fix or prevent this?
So my question is, how do you stop an operating system from auto-resizing the swing tools, or how do I make the selections in the JCombBox's readable and not cut off to like "Boxes" instead of "Bo...?"
As shown here, don't set the width; that is the purview of the UI delegate, com.apple.laf.AquaComboBoxUI. Instead, let the JComboBox calculate it's own preferred size based on the font metrics that inevitably vary from one platform to another.
If you still have problems, this example may form the basis for your sscce.
I have a Java application, and in order to find the size of the screen to use, I do the following, for example:
Toolkit.getDefaultToolkit().getScreenSize().width;
Toolkit.getDefaultToolkit().getScreenSize().height;
In my application, I am painting some items on the screen. And to determine the position, I use these values for width and height (because I want a particular item at the very bottom).
But, I'm finding that it is going off the screen, even though it's position doesn't exceed what the value for the height of my screen is.
Then, I realized I'm on a Mac, and the window that pops up for the Java application starts below the little toolbar menu thing at the top of my Mac (you know, the thing that has the time, the battery, etc). Do I need to take the height of that bar into consideration in my application? If so, is there an easy way to say "if I'm on a mac, then subtract something from the height." Also, what is that value of the height of that Menu Bar?
To get the maximum usable area, minus taskbars and menu bars, use the following:
Rectangle rect = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
From the docs:
Returns the maximum bounds for centered Windows. These bounds account
for objects in the native windowing system such as task bars and menu
bars.
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