Win a copy of Secure Financial Transactions with Ansible, Terraform, and OpenSCAP this week in the Cloud/Virtualization forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Rob Spoor
  • Henry Wong
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
Bartenders:
  • Frits Walraven
  • Himai Minh
  • Jj Roberts

Swing + 4K + Windows + Scaling

 
Saloon Keeper
Posts: 8019
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've got a Windows laptop, 14" with a 4K screen. I have my system display settings set to 200%. In general, I'd say my Java apps come up scaled the way I'd expect. I am also a photographer, so a number of my apps involve displaying images. Here's the rub: I want a JPanel (or something) in the app that would allow me to display an image at 100% even if the rest of the app is at a different scale. Is this possible?

Alternatively, how could I configure a single app to run at 100% and then write the app so that, internally, the app scales everything except image panels up to 200%. I did try to write a Scale class that would recursively go through a Component tree and re-scale it but it was only a partial success.

Life was much simpler at 1920x1080.
 
Carey Brown
Saloon Keeper
Posts: 8019
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's my Scale class in case someone's interested.

 
Saloon Keeper
Posts: 23440
159
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, I don't know if I got this clearly, but here's a stab:

First, a Java app probably cannot tell what scaling your OS has applied to your display. I doubt that there's a "write once/run anywhere" function to obtain that info. As a side note, if your desktop is truly scaling, it's probably not getting optimal image quality from any app. Best results are usually from setting display resolution to match the hardware being used at a 1:1 scale.

I'm long out of practice on Swing, but unless I've gone completely senile, images are scaled by the graphics handle that renders them. As you can see, I've forgotten what that handle is called, but whatever. So you should be able to scale images on a per-image basis. "size" isn't the same thing as scale here.

One feature I think is avaiable (assuming I'm not remembering the wrong GUI) is I think that there are a set of graphics functions that can convert absolute physical dimensions (mm/inches) to GUI-local dimensions, which would be useful in computing the scale factor. Although I don't know if that feature allows for OS-level scaling.
 
Carey Brown
Saloon Keeper
Posts: 8019
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Tim, it sounds like you're advocating my "alternative" approach of 100% or 1:1. I figure there's a way to run a Java app at 100% without ALL apps being required to run at 100% but I don't know how to do that. And, presuming I have something like an environment variable to indicate app swing scaling, how would I write a swing app so that all font sizes, textfields, buttons, etc use that scaling, e.g. 200%, while keeping image panels at 100%?
 
Tim Holloway
Saloon Keeper
Posts: 23440
159
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm completely unclear on what your "100%" is.

You set your desktop display scaling at the OS level (historically in Windows, right-mouse on desktop, select Display). As I said, to avoid fuzziness and distortion, the best choice for that is whatever your hardware allows. If's especially important to get an integer scale on LED displays, since unlike CRT's, they're pixel-precise (allowing for anti-aliasing). And of course, any ratio other than 1:1 would be wasteful, since you don't get full value from every pixel.

Apps are not "scaled", they are dimensioned. Every app has full control over the locations and sizes (geometry) of its windows within the limits of the desktop displays. You cannot give them a finer scaling than the desktop has, since the top-level renderer is the desktop itself.

You can scale one or more images within an application's windows, but, as I said, that part is controllable on a per-image basis as part of the rendering process. Again, the scaling will be added to whatever scaling the desktop does, since the contents of application windows are likewise ultimately rendered by the desktop. So again, the scale of the desktop limits the scale of the image.

For the window sizes and positions, each window can control its own values. This information (geometry) is often recorded in an application's preferences file. Similarly go the user's font and color choices, where applicable.

 
Rancher
Posts: 3232
30
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I want a JPanel (or something) in the app that would allow me to display an image at 100%



I believe the scaling factor is defined in the AffineTransform of the Graphics object. So this factor will be applied to all the Swing components when they are painted.

So you should be able to remove the default scaled transform and do your custom painting with code like:

 
Tim Holloway
Saloon Keeper
Posts: 23440
159
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes! thank you very much! The "handle" whose name I forgot was Graphics2D and the AffineTransformation is the per-item scaler. You also can rotate images within this context, if that's of any interest.
 
Carey Brown
Saloon Keeper
Posts: 8019
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, I define 100% to be the pixel resolution of the hardware, which is 3840x2160. I have windows scaling set to 200%, or 1920x1080. If I launch my Java app full screen I get a JFrame that is 1920x1080, not 3840x2160. It won't matter if I use afineTransform if Java/Swing doesn't think I have enough pixels for the image display area. I'm thinking that Windows would have a way to launch a single Java app and tell it not to scale but I don't know what that is. That leaves me with the problem that, for example, buttons will be minuscule. What do I have to do to make the button display as though scaling was set to 200%? Obviously I could set the font size and preferred size larger, but this would be tedious to for an entire user interface, hence my Scale class (which I've said has some rough edges)?
 
Tim Holloway
Saloon Keeper
Posts: 23440
159
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can't help but be reminded of an old cartoon where the guy watching a commercial on his TV set says "Whoah! The TV in that commercial does have a better quality picture than my TV!"

You can't have higher resolution in portions of your display than you can for the display itself. I can't vouch for LEDs, but it would have required CRTs to dynamically change the sweep rate of the electron beam in the middle of a scan line. The desktop, as I said, owns the master renderer, so everything else is limited by how it's set.

The only exception to one-resolution-per screen that I know of was the Commodore Amiga PC, but it actually could change the horizontal sweep rate. Not within a line, but you could pull up and down "window shades" that had different resolutions. They had special graphics hardware, however.

Of course, the real question I have, is why ruin the clarity of your desktop by scaling it? You are aware, I hope, that almost all desktop components and apps can be adjusted via preferences so that, for example, your icons aren't 1/16h inch square.

In fact, I can adjust scaling in Firefox on a per-website basis using the Ctrl-+ and Ctrl-minus keys. And often do.
 
Carey Brown
Saloon Keeper
Posts: 8019
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sure, how do I implement Ctrl-+?

What preferences do I set so that icons don't come out 1/16th inch?
 
Tim Holloway
Saloon Keeper
Posts: 23440
159
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:Sure, how do I implement Ctrl-+?

What preferences do I set so that icons don't come out 1/16th inch?



Ctrl-+ is just a hotkey for the Firefox application program. A Java app might use it to select an AffineTransform.

Icon size for Windows is a video display function. Should be a "Use large icons" option somewhere. I haven't run Windows in too many years to remember where. Plus, of course, Microsoft likes to move stuff around between releaseslike automakers change tailfins on cars.

On the Linux Cinnamon desktop, I get no less than 5 different icon size options, though.
 
Carey Brown
Saloon Keeper
Posts: 8019
70
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
We seem to be talking at cross purposes here. You said that "the desktop owns the master renderer". And that I can't have one JPanel at one resolution and a different one at another. OK, so I have them all at 100% (1:1, 3840x2160, whatever), then I need to draw the Swing components twice as large and they need to have text that is twice as large. I can set preferences and fonts and get 85% there but it is incredibly tedious. I gather from your responses that: a) this is an uncommon request, and that b) other that writing my own look-and-feel package there's no readily available support for something like this in swing.

I have a number of photography apps that work this way, GUI widgets at window's scaling and image display area at 100%, just that none of them are written in Java.
 
Tim Holloway
Saloon Keeper
Posts: 23440
159
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think it's more a case of getting the ground rules clarified. First there's what the desktop supports, then there's what the applications can request of it. I'm having to deduce backwards, here, as for example presuming that you had sub-optimal desktop scaling because you didn't realize that the desktop could be configured for a less eye-hurting icon, menu and caption size.

I'm now beginning to suspect that you are trying to use absolute sizes and locations in your Swing app and discovering that that's Not A Good Way To Do It. Now obviously if you want your images to be life-sized, that part will have to scale precisely. However for general menu/dialog/appwindow elements you should be using relative layout managers. not absolute ones. The problems appear to be seeing are, in fact, precisely why the LayoutManager concept was developed.

Usually I have a couple of fonts that I define globally to represent the typefaces, styles, and sizes I want to display. At a minimum I would generally have a bold font for control labels and a regular font for control values. A lot of the other Swing components size themselves to fit the fonts (if any) that they will be using. In cases where that's not sufficient, I'd subclass controls to personalize them for the app. Much better than having to grind through a lot of options on a per-control basis.

Fonts, of course, are constructed based on TextAttributes passed to the font factory. The default font size is 12 points, and I think that comes out to about 1/8 inch high. And note that that's an absolute physical size, just like you want your images to be. So if you construct a text element with one of those fonts and it renders at the wrong size, there's something wrong with scaling at the system level.

The UIManager is supposed to be making intelligent font and component size defaults (such as the use of 12-point fonts) when the application starts up, and that certainly shouldn't be insurance-policy-sized text*. However, you can always set override values on it before you start building UI elements and that should do it.

---
* I applied for a job once at a well-known insurance company. Part of the paperwork was light-grey text on yellow flimsy paper and about 6 points high.
 
I've read about this kind of thing at the checkout counter. That's where I met this tiny ad:
SKIP - a book about connecting industrious people with elderly land owners
https://coderanch.com/t/skip-book
reply
    Bookmark Topic Watch Topic
  • New Topic