GUI scale problem when using JPanel

Hi,

When the GUI scale is changed through Edit → Options → Appearance, and most probably when the default value is not 1, the GUI scale in the plugin I coded using JPanel is not changed accordingly. Here is an example when using a GenericDialogPlus where buttons added directly to the GenericDialogPlus are in the right resolution but not the Jbuttons defined in a JPanel:

JRadioButton nuclearRadioButton = new JRadioButton("Nuclear marker");
nuclearRadioButton.setSelected(true);
JRadioButton membranarRadioButton = new JRadioButton("Nuclear membrane marker");
membranarRadioButton.setSelected(false);
JRadioButton cytoplasmicRadioButton = new JRadioButton("Cytoplasmic marker");
cytoplasmicRadioButton.setSelected(false);

ButtonGroup bg1=new ButtonGroup();    
bg1.add(nuclearRadioButton);
bg1.add(membranarRadioButton);
bg1.add(cytoplasmicRadioButton);

JPanel markerTypePanel = new JPanel();
markerTypePanel.setBorder(BorderFactory.createTitledBorder(""));
GridBagLayout markerTypePanelLayout = new GridBagLayout();
		
GridBagConstraints markerTypePanelConstraints = new GridBagConstraints();
markerTypePanelConstraints.anchor = GridBagConstraints.NORTHWEST;
markerTypePanelConstraints.fill = GridBagConstraints.HORIZONTAL;
markerTypePanelConstraints.gridwidth = 1;
markerTypePanelConstraints.gridheight = 1;
markerTypePanelConstraints.gridx = 0;
markerTypePanelConstraints.gridy = 0;
markerTypePanel.setLayout(markerTypePanelLayout);
markerTypePanel.add(nuclearRadioButton,markerTypePanelConstraints);
markerTypePanelConstraints.gridy++;
markerTypePanel.add(membranarRadioButton,markerTypePanelConstraints);
markerTypePanelConstraints.gridy++;
markerTypePanel.add(cytoplasmicRadioButton,markerTypePanelConstraints);

GenericDialogPlus gd1 = new GenericDialogPlus("Marker creation");
gd1.addMessage("What is the type of the marker?");
gd1.addComponent(markerTypePanel);

String[] compartments = new String[3];
compartments[0] = "Nuclear marker";
compartments[1] = "Nuclear membrane marker";
compartments[2] = "Cytoplasmic marker";
		
gd1.addRadioButtonGroup("What is the type of the marker?", compartments, 3, 1, "Nuclear marker");
gd1.showDialog();

This is what it looks like:
image

I’m sure there must be a way to easily change the resolution of JRadioButton (or other Swing components) embedded into a JPanel, but I can’t find it. Is anyone able to help?

Thanks a lot,
Thierry

1 Like

Hi @tpecot,

the font size for ImageJ1-type dialogs is set here in the GenericDialog class:

You can query Prefs.getGuiScale() and set the font size for your own components accordingly.


For the record: the Java Swing dialogs generated from #@ script parameters likewise do not respect the GUI scale setting in Edit › Options › Appearance…, as this seems to be a pure ImageJ1 setting.

Here’s a (Groovy) script illustrating this:

#@ String (visibility=MESSAGE, value="<html><b>What is the type of the marker?</b></html>") msg
#@ String (choices={"Nuclear marker", "Nuclear membrane marker", "Cytoplasmic marker"}, style="radioButtonVertical", label=" ") type

print "Chosen marker type: $type"

Have a look at this more extensive older thread:

ImageJ uses mainly AWT (with some Swing components). The default OS scaling works best on MacOSX.

On Windows and Linux the OS scaling (or ImageJ scaling) works more or less.

Your GUI is a mix of AWT and Swing. I would use only the JRadioButton or the AWT counterpart.

Swing can be OS scaled with the VM argument (if using e.g. Java 1.8.xxx - since Java 9 automatic scaling is supported which fits for a pure Swing application):

-Dsun.java2d.uiScale=2.0 (for HighDPI)

Which can also be set at startup with:

System.setProperty(“sun.java2d.uiScale”, 2.0));

I do this for my application based on SWT (for, e.g., embedded Swing panels) at startup to set this to 1 or 2 because SWT only nows this two scales at the moment.

My personal wish would be that AWT would be replaced with SWT which offers the best OS dependant UI at the moment (that’s why I replaced nearly all AWT menus with SWT in my Eclipse ImageJ plugin for the horrible default Linux AWT fonts and menu scaling).

Certainly it would help if Java would fix some AWT scaling and font (Linux) glitches. But I think they won’t support AWT anymore.

1 Like

Thanks a lot to both of you! It’s really helpful, although I’m still not able to make it work, because of my limitations in programming.

@Bio7 If I add System.setProperty("sun.java2d.uiScale", "2.0"); at the beginning of the plugin, it does not change the resolution of the plugin, there’s no exception either, it seems that it has no effect.

@imagejan Your way to change the font size works perfectly (did it for nuclear marker only in this example):
image

However, I cannot obtain the GUI scale currently used by Fiji.

Prefs.getGUIScale() does not exist in my environment. I can use
Prefs.getString​(java.lang.String key) or

Prefs.getDouble​(java.lang.String key,
double defaultValue)

but I get Null for the first one with GUI_SCALE as key or the value I enter for the second one. I’m sure it’s quite stupid error, but I can’t find a way to get the GUI scale.

It must be added at startup of ImageJ or as a VM argument, see also:

https://wiki.archlinux.org/index.php/HiDPI

You misspelled it. The command is Prefs.getGuiScale() contained in the ij.Prefs class:

https://javadoc.scijava.org/ImageJ1/ij/ij/Prefs.html#getGuiScale()

If you want to get the value by key lookup, the String value you have to supply is "gui.scale", or the constant Prefs.GUI_SCALE directly, see:

https://javadoc.scijava.org/ImageJ1/constant-values.html#ij.Prefs.GUI_SCALE

@imagejan Sorry for the confusion, I don’t have Prefs.GetGuiScale() either:

If I try with the correct key, Prefs.getString("gui.scale") I obtain Null as value. All together, it suggests that I don’t have access to the right ij.Prefs, any idea how it’s possible? Thanks!

I think this all could be a little bit confusing.

The easiest method on Windows is to overwrite the OS scaling (disable the ImageJ scaling, etc.), see:

The application looks a little bit blurry on HighDPI but everything in ImageJ is resized correctly.

Of course if you want to ship your plugin a different computer has to apply the settings, too.

However, when using the Swing scaling on Java 1.8 you have to disable the ImageJ scaling!
It might be possible for you to use a more recent Java version >=9 and ImageJ which scales Swing by default.

(post withdrawn by author, will be automatically deleted in 72 hours unless flagged)

Your solution looks really neat, but this is for a plugin that is distributed in Fiji. Actually, this error came out of a tutorial where a user with a 4k screen in Linux couldn’t use the plugin as he couldn’t change the resolution. Hopefully, he had other computers so that wasn’t a problem for the tutorial. However, I’m trying to make it as generic as possible for potential users. In this context, I think changing the font of the Swing components depending on the current Gui scale in Fiji will work, I just need to find a way to get this scale.

Anyway, thanks a lot for your help!!!
Thierry

As I wrote it myself:

it suggests that I don’t have access to the right ij.Prefs

So I changed the version of scijava in the pom.xml file, and I now have access to Prefs.GetGuiScale(). Sometimes, you just have to think a little bit by yourself.

Anyway, thanks a lot to @imagejan and @Bio7.

1 Like

Glad that you found a solution, @tpecot!

Just to clarify (and for other readers who might follow this discussion, or read it in the future):
I guess you mean pom-scijava as a parent of your pom.xml?

SciJava itself doesn’t have any dependency on net.imagej:ij, the artifact that contains the ij.Prefs class; but pom-scijava includes ij in its dependency management.

@imagejan Yes, that’s correct!