GUI scaling for different screen resolutions and sizes - java

As a beginner programmer I have been making very simple programs and dabbling in GUIs using Java. It occurred to me the other day that everything I have made is done and tested on the same resolution screen so I tried changing my resolution and the GUIs were just awful, half of them did not even fit all the components on to the screen.
I assume using scaling variables for the components is the solution but what do the pros typically use when scaling their apps? I was thinking possibly getting the screen resolution/size ( I can't remember the tool for it but I've definitely seen it ) then scaling based on those results but perhaps there is a more simple technique that I haven't considered.

Typically you want to decide on a minimum supported screen resolution and design for that, using something like setPreferredSize(width, height) to size your top-level windows. If the user has a larger-resolution screen, they can resize your application; like MadProgrammer implied, your layout manager should be set up to resize gracefully.
If you really want to be responsive, you can isolate the code that sets up your layout manager in a method that takes the current screen resolution (that you can get using the method here) and arrange components differently based on, say, the width of the screen.

Related

How do you utilize SWT's Hi-DPI support for widget sizing?

Does SWT (or JFace) have a public convenience method for converting conventional units to their scaled counterparts? I've found mention of a DPIUtil class but that's part of an internal namespace
If there's not a convenience method available, then is there a reliable way to access the zoom level? I see there's Device#getDeviceZoom() but that is protected. There is Device#getDPI() which is public so it might be useful. Does that take scaling into consideration, or is it naïve and just declares that DPI is 96 for everything?
I'm applying default sizing hints to some panels and I'd like them to take the monitor scaling setting into consideration. E.g., Say on a regular display I want the default to be 300px, but at 150% scaling I want to calculate it to be 450px. The calculation is obviously simple but I need the multiplier.
NOTE: This is related but different from my previous question How do you utilize SWT's Hi-DPI support for icons? because SWT provides classes to specifically handle this with images.
I haven't found anything other than DPIUtil for determining the scale (zoom) factor.
But you don't normally need this information. Specifying a size of 300px will be automatically scaled to 450px by SWT on a 150 scaled device (and any 150 scaled image you provide will be used). I have an iMac with two screens - a 5k screen scaled at 200 and a 2.5k screen not scaled - SWT apps appear the same size on both.
The scaling is actually done in the OS rather than SWT (at least that is how it works on macOS). The OS scales up the sizes, renders fonts at the higher resolution and uses the high resolution images if available. So programs don't need to do anything other than provide hi-res images.
This way even old programs that don't know about zoomed displays still appear at a sensible size.

Java image/map object

Using Java and SWT, I am trying to display a map (provided as an image) and mark points on it. First idea is to use a canvas, draw the image (scaled to the largest possible size for this canvas) and then draw the markings (fixed size) to the scaled coordinates. However I would also like to zoom in and move the image, and would prefer not to develop all this functionality from scratch. However I am not having much luck finding an existing solution, though I would guess there should be something out there.
The criteria would be:
based on SWT (or compatible)
allows exchange of the image (possibly with different sizes)
handles user interaction (selection a point on the image, zooming in/out of the image)
Does anybody know a standard/common solution?
Depending on how complex your system will potentially grow, maybe using GEF is an option.
The whole rendering is done on SWT.Canvas and it provides Zooming/Scrolling/Moving out of the Box.
Downside: Its dependant on RCP, so this is likely to be only an option if you need to build an otherwise complex application - in all other cases GEF will be quite heavyweight to set up.

What is the best way to accommodate for different screen sizes in a game?

I am creating a Java game for Windows and I have come across a problem: there are lots of different screens and resolutions when it comes to Windows. What would be the best way to make it so that it looks just about the same on all screens?
You basically have three options:
Fix the size of the game window to something small that will fit n all screens (800*600 maybe)? This is easy to do, but could annoy users with big screens.....
Make the game resolution-independent, so that that it is rendered to a scale to fit the current window size. This is how most FPS games work for example. The main downside of this is that you need to do some extra scaling maths in your code and there may be some runtime overhead for rescaling images etc.
Make the game screen dynamically resizable, so that the components within it rearrange and resize themselves to fit the available space (like with a web page). This is the hardest to implement as you have to make use of appropriate layout managers and test lots of different combinations, but can give the nicest user "experience". I've successfully used MigLayout to do this in the past with a Swing game.
Any of these options could be best for you depending on the circumstances. It will probably depend mainly on the type/design of your game and your willingness to spend time on making the more complicated methods work well.

Dealing with different resolutions for pixel based android game

I am developing a 2D platformer game for the android platform, so I don't really care about the screen DPI, but much more about the actual resolution in pixels. From what I've gathered on the net, there are a couple of different resolutions (and aspect ratios) present. According to my search, the two resolutions that are currently widespread are 480x320 (1.5) and 800x480 (1.666), is that right? I'd like to target these two resolutions to reach most customers.
Now, I can deal with the different aspect ratios by showing a black border of 40 pixel for the bigger display, essentialy reducing it to 720x480 pixel and a ratio of 1.5.
The problem with my game is that it is essential for gameplay that the players see the same amount of the world on each screen. Otherwise, some players would get an unfair advantage. Furthermore, I trigger some events depending on the visibility. For example, an enemy is only allowed to start shooting when the player starts seeing it. Otherwise, the enemies' bullets would seem to come from nowhere.
So I figured I need to either create my graphics for one resolution and scale them for the other. Or I create separate graphics for each resolution. Is that right? Unfortunately, both ways are suboptimal for pixel graphics.
On another note: How can I restrict my game to these resolutions only (especially for the Android Market)? I know about the "supports-screens" tag in the manifest, but that works depending on the effective screen-size, not the size in pixel, or am I mistaken?
I am also interested in personal experiences of other android game developers when it comes to resolution independence.
Thanks!
My question would be: what do you think would do on a PC? For game development, Android should be looked at much more like a PC target than a console. You just intrinsically need to accept that there will be some diversity of screens that you can't totally predict up-front.
So I think there are two main approaches to take:
(1) Use a constant "display size" as if you were setting a fixed video resolution on the PC and letting the user's monitor deal with it. On these devices of course there is no monitor, just one fixed display, so it doesn't make sense to modify the core resolution. Instead, you can set up the SurfaceView showing your game to have a fixed resolution, and let the platform's compositor take care of scaling it (in hardware) as it composites to the screen.
(2) More intelligently adjust to the actual resolution of the screen you find yourself running in. Scale up or down graphics yourself to create the playing area you want. Maybe have some different sizes of textures and select the appropriate ones for the screen resolution.
You could probably also do a combination of these, where you have a couple fixed sizes you pick for the surface view depending on the total resolution available which the game can run well with. In either case, you can do letter-boxing as appropriate to keep your aspect ratio constant on different screens, if that is what you want.
There are three approaches to differences in aspect ratio:
Show opaque borders on some ratios ("letterboxing").
Show more of the game world on some ratios.
Don't work at all on some ratios.
With approach (1) you waste screen space on some devices. Not such a big deal for televisions, but miserable on handheld devices where screen space is limited. With approach (2) players on some devices get advantages (they can see more of the world) and disadvantages (sprites are smaller, so touch precision is harder). Approach (3) just sucks.
Obviously it depends on the details of your game which is better, but as a player I much prefer approach (2). The constituency who care if players on other devices get a bit of a hypothetical advantage is pretty small compared to the constituency who care if their screen is partly obscured by unnecessary black bars.
(Similar approaches and remarks apply to differences in resolution.)

Zoom in Java Swing application

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

Categories

Resources