I have created a form in Swing with 10 components (5 labels and 5 textfields), using Gridbaglayout.
When my screen resolution changes, the separation between the components is not changing. Why?
GridBagLayout uses pixels as the unit of measure. You can use java.awt.Toolkit.getScreenResolution() to get the pixel density and then scale your spacing accordingly. You also might find java.awt.GraphicsConfiguration.getNormalizingTransform() useful; it allows you to work in a coordinate system where 72 units is 1 physical inch.
Related
We are working on an android app, and we have encountered an issue where devices in the same density bucket, i.e. "xxhdpi" do not all look the same, i.e. the Pixel and Pixel 2. We have a very image heavy UI and are using a Constraint view to organize the placement of several overlaid images. The Navigation drawer at the top of some of these screens further exacerbates the issue, as the margin is thicker with different densities on the same screen size and the rest of the app in squeezed into a smaller frame.
Heres an example of how different the Pixel and Pixel 2 are rendered:
Pixel 2 vs.
Pixel
We have tried making more specific layouts to match more specific ranges of DPI but the simulator groups the same devices together no matter what we try. These are the layout categories we've tried, where sw320dp for example refers to a minimum screen width.
Is there a way to combat this issue with constraint view features such as a constraint anchor or percentage constraints? Alternatively can we more narrowly define our layout categories or do something about the dp scale not being the same for similar devices? We have already consulted this page as well as numerous stack overflow posts: Android's Guide on Supporting Multiple Screen Sizes.
Any suggestions, comments, or specific questions welcome, thanks in advance to anyone who takes the time to read this.
This is my approach for getting the image to be shown completely without cropping on the edges, hope you get some kind of idea from this to tackle your situation.
Problem here is with wrap_content and match_parent, though pixel and pixel 2 falls in same category that is "xxhdpi" for getting the image from density bucket but they have little bit change with their width, pixel: 143.8 x 69.5 x 8.5 mm (5.66 x 2.74 x 0.33 inches) and pixel2: 145.7 x 69.7 x 7.8 mm (5.7 x 2.7 x 0.31 inches)
So I am guessing you probably have match parent for width and image scale type as center crop so image is scaled accordingly zooming in, so because they have different widths they are zoomed in more on one compared to the other.
I had similar kind of situation so what I did was used webview with match parent as width and wrap content as height then I displayed image in the webview
WebSettings settings = webView.getSettings();
settings.setLoadWithOverviewMode(true);
here setLoadWithOverviewMode actually zooms out and fits the image so no matter what you always see the whole image.
I am working on a Java Swing application that needs to be run on a significant smaller screen size than what it was developed for.
Unfortunately, the layout gets heavily distorted, mainly because the fonts are displaying relatively bigger.
Most of the font sizes are set using embedded html in JLabels and JButtons.
How can I force the font sizes in Swing to be equal in Pixels across different resolutions?
Start with Toolkit(.getToolKit()).getScreenResolution() as per the javadocs: "Returns the screen resolution in dots-per-inch". Next, create a FontMetrics Object for your screen and Font (there are multiple ways to do this). Then you can use FontMetrics.getHeight() with the screen resolution to figure out how big it will display. You can use Font.deriveFont(float) until the size is the same or as similar as possible as what you want
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 want to scale my android application, basically i developed it for 800x480 display with a AbsoluteLayout. This is necessary for my Application, i can't change it.
Now the Problem:
When i start my app in the Emulator the buttons disappear and the images are extremly large. I thought android would scale applications with a fixed size down by default, but it does not work. I already tried to manipulate the manifest but this did not work.
I use a ImageView component for graphics.
Targeting Android 2.1
Cheers
Felix
It is definitely not ideal to use AbsoluteLayout. But, if you want to just push through with it, you should switch the units of all your co-ordinates and sizes away from px (pixels) to dp (density independent pixels). You will have to scale all of your existing co-ordinates by a factor of 2/3 to start, since 1 dp = 1.5px at the density that your layout targets (hdpi).
You will need to explicitly specify the sizes of all your images and layouts. If, for example, you had a button that was 30px wide and 120px tall, then it will become 20dp wide and 80dp tall.
Of course, the images won't look great on smaller (mdpi) screens, since they will be scaled to 2/3 size. Also, some devices are fixed to landscape mode, where you will definitely encounter layout problems. So it's not pretty, but it may get you over the finish line, depending on your requirements.
hello and hi everyone,
can anyone suggest me how to use device independent pixels(dip),sip and convert px to dip with a sample code..
Check this out.
Density-independent pixel (dip)
A virtual pixel unit that applications can use in defining their UI, to express layout dimensions or position in a density-independent way.
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, the baseline density assumed by the platform (as described later in this document). At run time, the platform transparently handles any scaling of the dip units needed, based on the actual density of the screen in use. The conversion of dip units to screen pixels is simple: pixels = dips * (density / 160). For example, on 240 dpi screen, 1 dip would equal 1.5 physical pixels. Using dip units to define your application's UI is highly recommended, as a way of ensuring proper display of your UI on different screens.