Coder Social home page Coder Social logo

scijava-ui-swing's Issues

Activating auto-imports in Python triggers NoClassDefFoundError

As reported in this question on SO, activating (deprecated) auto-imports in Python leads to the following error being thrown:

[WARNING] Auto-imports are active, but deprecated.
Traceback (most recent call last):
  File "New_.py", line 33, in <module>
java.lang.NoClassDefFoundError: javax/vecmath/Point3f

To reproduce, run this python script with auto-imports enabled (Edit > Auto-import (deprecated) in the script editor):

print("Foo")

Support html hyperlinks in labels and messages

When using a hyperlink in a widget label or message:

#@ String (value = "<html><a href=\"http://imagej.net\">Link</a> in a message</html>", visibility = "MESSAGE", persist = false) message
#@ Integer (label = "<html><a href=\"http://imagej.net\">Link</a> in a label</html>", value = 42) number

the links are rendered blue and underlined, but they're not active hyperlinks.

We should improve SwingMessageWidget to support links by adding an ActionListener and calling platformService.open(url).

This was brought up by @LauLauThom, see this forum topic.

Ensure JSpinner text is selected on focus

3d3b555 partially implements a solution for text boxes in a JSpinner to be selected on focus. It works nicely for tabbing, but sometimes on click selection happens but is then lost.

Presumably this is a race condition with queuing the text box selection and some sort of validation of the JSpinner. But it's not clear what.

There are many SO posts discussing this but none seemed perfect resolutions.

Secondary goals:

  • Understand why we would want to select text on focus lost
  • Test on OS's besides mac
  • Do NOT rely on sleep statements to queue selection after any JSpinner validation has passed

Create a Script Recorder for recording module executions

Rather than a "Recorder" which must be proactively started, this new UI should take the form of an event history from which scripts can be generated. SciJava Common already has an EventHistory that was a first attempt at remembering these details in a way that does not retain hard references to potentially large and complex objects.

Requires scijava/scijava-common#57 first.

Dependency-wise, this work might rather belong in scijava/script-editor, since that component depends on scijava-ui-swing, not vice versa. The idea is that generating a script from a chunk of history should open a new Script Editor window accordingly.

Unusable viewport in tables

On the display of tables: The current viewport of the scrollpane is extremely awkward. The horizontal scrollbar never appears, and thus a table with many (> ~20 columns on my screen) becomes unreadable. Here is an example:

image

Those dots actually contain numeric values. AFAICT there is no way to make the data visible, rather than exporting the table to a third party application (or resizing each column one by one).

Warning status popup displayed twice

When firing a warning status in a SciJava application, it is displayed twice. Example code:

ImageJ ij = new ImageJ();
ij.ui().showUI();
StatusEvent event = new StatusEvent("test", true);
ij.event().publish(event);

The first popup is created by the DefaultUIService here, the second one by the SwingStatusBar here. Should I just remove it from the status bar or is there a reason for this duplication?

Using swing UI causes command dialogs to show some invisible items

When ImageJ is launched with the swing as the default UI:

ImageJ ij = new ImageJ();
ij.ui().setDefaultUI(ij.ui().getUI("swing"));
ij.ui().showUI();
Dataset blobs = ij.scifio().datasetIO().open("http://imagej.net/images/blobs.gif");
ij.ui().show(blobs);

Any following calls to commands that have a ImageDisplay parameter with type = ItemIO.BOTH or type = ItemIO.INPUT will cause the command dialog to show an item "display" with a long string of its ImageDisplay.toString().

For example, ij.command().run(SubtractFromDataValues.class, true); pops up such dialog with unexpected behavior. Using the legacy UI (e.g. removing the "setDefaultUI" line of code above) does not produce such problem, so I suspect that it is the swing UI causes the problem.

Is this a bug, or is there any correct way to programmatically run a command so that the display item will be invisible? Thanks!

Add button to reset parameter default values

Currently, the parameter input harvested from @ parameters is remembered between script executions and between separate sessions. While that is useful for repeated executions of the same script, there should be a way to restore the defaults defined by value = someValue in the parameter definition, e.g. by adding a Reset button.

Harmonize file filter logic for File inputs

We currently have inconsistent logic when setting up a file filter for File and File[] inputs.

The extensions style is only supported for File[] inputs, not for File, see:

Actually, the file filter seems to work for drag-and-drop (in FileHandler):

final List<File> files = SwingFileWidget.filterFiles(allFiles,
filter);

... but not for the Browse button.

Related scijava-common issue: scijava/scijava-common#197

SwingFileWidget: support 'pattern' style

In addition to a style attribute like extensions:tif/tiff, we should support a way to define file name patterns, such as pattern:WildType*.tif (wildcard pattern) and/or pattern:^[A-Za-z0-9]+\.png (regex pattern).

Getting the style modifier will be simplified once scijava/scijava-common#405 is merged and released.

Open questions:

  • Two different style attributes for wildcards and regexes? E.g. regex-pattern and wildcard-pattern, or regex and pattern, ...
  • Additional flags to specify case (in)sensitivity? For regex patterns, we could use standard syntax like /[A-Z]/gmi or (?i)[A-Z]; I'm not sure about conventions for the wildcard case...

Handle missing min/max gracefully for sliders/scrollbars

Currently, the UI hangs when trying to use a numeric parameter with style=slider, but min or max undefined:

#@ int (style=slider) a

This should be handled gracefully, by checking for softMin != null and softMax != null here:

// add optional widgets, if specified
if (model.isStyle(NumberWidget.SCROLL_BAR_STYLE)) {
int smx = softMax.intValue();
if (smx < Integer.MAX_VALUE) smx++;
scrollBar =
new JScrollBar(Adjustable.HORIZONTAL, softMin.intValue(), 1, softMin
.intValue(), smx);
scrollBar.setUnitIncrement(stepSize.intValue());
setToolTip(scrollBar);
getComponent().add(scrollBar);
scrollBar.addAdjustmentListener(this);
}
else if (model.isStyle(NumberWidget.SLIDER_STYLE)) {
slider =
new JSlider(softMin.intValue(), softMax.intValue(), softMin.intValue());
slider.setMajorTickSpacing((softMax.intValue() - softMin.intValue()) / 4);
slider.setMinorTickSpacing(stepSize.intValue());
slider.setPaintLabels(true);
slider.setPaintTicks(true);
setToolTip(slider);
getComponent().add(slider);
slider.addChangeListener(this);
}

If no slider or scroll bar can be rendered, we should fallback to the standard textfield/spinner combination and log a warning message.

Respect multiple styles in chooseFile and chooseFiles methods

We currently check for equality in the chooseFile and chooseFiles methods of AbstractSwingUI:

if (FileWidget.DIRECTORY_STYLE.equals(style)) {

if (style.equals(FileListWidget.FILES_AND_DIRECTORIES)) {

Let's instead use a common utility method to check whether a certain style string matches a given widget style.

See also scijava/scijava-common#333.

SwingFileWidget: support copying from widget text

Consider the following script:

#@ File fileA
#@ File fileB
#@ String someText

In the generated UI dialog, you can copy (CtrlC) from the String input field, but not from the two File inputs. (Pasting works in both widgets.)

Console Menu bar is not aware of Log tab

Currently, the Edit -> Clear command works only if the active tab is 'Console'. We would need to make it aware of the Log tab.
NB: even though orphan menus feel quite awkward, deleting the Edit menu is unwise, as per #79 (comment)

It is considered bad UI design (at least historically by Apple HCI documents) to have functionality that is only accessible in context menus. See e.g. web browsers, which have Cut/Copy/Paste et al. in both context menu and an Edit menu.

SwingUI's chooseFile deadlocks on macOS

The following code deadlocks on my macOS system:

final ImageJ ij = new ImageJ();
ij.launch(args);
final File file = ij.ui().chooseFile(null, FileWidget.OPEN_STYLE);
System.out.println(file);

The joys of the EDT!

Implement an input widget for URIs

Such URIs might be a file path (with implicit file:// prefix), so the Browse button is still useful. But when a non-file URI such as https://... or s3://... is given, it should not mangle it into a java.io.File.

A URIWidget interface in SciJava Common is straightforward; the trickier part is here in scijava-ui-swing, how to get all the same features as the current FileWidget, while minimizing copy-pasting of code. I would like to make an abstract SwingFileEtcWidget or some such, which still takes a generic parameter for data type, but has the common logic for the Browse button for picking files...

Provide a way to save results from swing table

When using script output, such as those in this script:

#@output a
#@output b

a = 2.17
b = "Foobar"

the outputs are displayed in a new table window without any menu. Let's add some possibility to save the table contents to file, similar to how it works for IJ1 ResultsTables.

NPE from SwingObjectWidget

The new Fiji release and update to pom 33.0.0 earlier this week bumped the version of scijava-ui-swing to 0.17.0. Surprisingly, and sadly, this change broke most of our groovy scripts. When running any script with a script parameter input asking for a MoleculeArchive, the main objects we work with in our software Mars, we get a NullPointerException:
Screenshot 2022-09-14 at 16 58 26
This happens when I run the script with a MoleculeArchive already open:

#@ MoleculeArchive archive

println(archive.getName())

and the dialog opens but is blank...
Screenshot 2022-09-14 at 16 58 49

This was even more exciting because our paper was published yesterday (https://elifesciences.org/articles/75899) and much of it depends on groovy scripts. So somehow after years of testing on the day of publication everything in all of our workflows was broken 😢

I did test with the bundle before the release, but of course I somehow didn't test scripts... I narrowed the problem down to the changes in commit 7d36b38 and in particular these lines now:

String[] availableChoices = model.getChoices();
if (availableChoices != null) {
comboBox = new JComboBox<>(availableChoices);
} else {
comboBox = new JComboBox<>(model.getObjectPool().toArray());
}

this change was introduced between version 0.14.0 and 0.15.0

Somehow for our MoleculeArchives availableChoices is an empty list and then when getListCellRendererComponent is called the value is null and the NPE is thrown in the ObjectService when trying to getName...

The else part of the statement works perfectly because model.getObjectPool().toArray() returns a list with the archive and all is good.

However, I think availableChoices will never be null for DefaultMutableModuleItem since the empty list is created upon creation of that type of ModuleItem. So I would imagine this would be a problem for anyone trying to retrieve their particular Objects. Alternatively, maybe there is a mistake in our code or how we define our Objects, but I don't see it currently.

@imagejan do you have any insights here? I will keep investigating but I don't see how to fix the problem without removing this if else statement and leaving the else portion.

For now, the scijava framework came to the rescue. I created MarsSwingObjectWidget in mars-core in our project equivalent to version 0.14.0 with a higher priority to avoid the issue, but I would like to find a fix and remove that...

No parameter attribute for number formats

This issue was recently brought up on the forum... currently, if for example, you want to display the a default value of 0.0178 in the dialog for a user…

#@Double(label="Distance", value=0.01780, persist=false) distance

When the code runs… you get a pre-set value of 0.018 popping up and there is no current method to set the number of decimal places for that input.

As stated by @imagejan on the forum:

"The spinner created in SwingNumberWidget is using the default DecimalFormat which apparently has a maximum of three decimal places.

You can somehow work around the issue by using a slider or scroll bar (within a defined range). But while the actual values can contain more decimal places (as shown by the println statement, there’s still no visual feedback inside the spinner text field:

#@ Double (label="Distance", min=0, max=0.05, value=0.01780, persist=false, stepSize=0.0001, style=slider) distance
println distance

There’s no parameter attribute for number formats, but we could maybe use the style attribute for this; in any case we should try to guess a suitable spinner number format from the combination of min, max and stepSize, or from the default value…"

Sliders and scroll bars should scale to stepSize

When using non-integer numeric inputs with style="slider" or style="scroll bar", the UI widgets only support integer steps (because the underlying JSlider and JScrollbar objects only support int values).

This can be improved by scaling the slider range to the [min; max] range as follows:

  • slider.setMinimum(0)
  • slider.setMaximum( (max-min) / stepSize )
  • slider.setValue( (value-min) / stepSize )
  • value = slider.getValue() * stepSize + min

and setting the slider/scrollbar labels to string representations of the scaled values.

Allow showing file list widget instead of file chooser

When using a single File[] parameter like:

#@ File[] (style="extensions:tif/tiff/ims") files

.. we always show a file chooser dialog using chooseFiles.
Only when a second unrelated parameter is added, a file list widget is shown in a generated input dialog:

#@ File[] (style="extensions:tif/tiff/ims") files
#@ String (required=false) ignoreThis

There should be a possiblity to get an input dialog with the file list widget, without the need to add secondary parameters.

(I thought I had opened a ticket about this long ago, but I couldn't find it, so here it is.)

Spinner increment/decrement precision problem

When collecting an input of double type, there might be precision problem using the spin up/down arrows. The code to produce the problem using script editor:

// @double(min="0.0001", max="5", value="0.0001", persist="false") a
print(a)

I think the problem is that the initial value 0.0001 is somehow rounded down to 0. Since the minimum value is 0.0001, so we are not able to change the value using the spinner.

Similarly, in this code segement:

// @double(min="0.001", max="5", value="0.001", persist="false") a
print(a)

we are able to increase the value from 0.001 to 1.001, but not going back from 1.001 to 0.001.

Not sure which part of the code cause this rounding error.

Spinners are missing up/down arrows with FlatLaf

As reported on the Image.sc Forum:

Unfortunately, spinner buttons in ImageJ2 style ContextCommand plugins are missing. Other L&Fs work.

To reproduce:

  • From the Script Editor, choose Templates → Intro → Widgets (JavaScript).
  • Delete the BigInteger and BigDecimal parameters (there's currently a bug affecting them)
  • When the dialog box appears, observe that none of the numeric parameters have spinner arrows, only text fields

Add FlatLaf as a L&F option

Suggestion for OptionsLookAndFeel:

Swing is for the most part abandonware, but Flatlaf has been making strides in patching several swing limitations, namely lack of consistent scaling in hiDPI screens (which is nasty on Linux). This is mainly an issue for Java 8 (as of today Java11 solves much of it, but it is not perfect. So this would still be relevant once Java11 is adopted).

Some motivations are laid out at the bottom of this comment: scijava/script-editor#56 (comment)

The tasks for this would be:

  1. Adding FlatLaf as dependency
  2. Make sure that initLookAndFeel() returns the FlatLlaf themes (i.e, FlatLightLaf.NAME, FlatIntelliJLaf.NAME, FlatDarkLaf.NAME, FlatDarculaLaf.NAME)
  3. Have run() calling the Flatalaf setup(), something like:
	switch (lookAndFeelName) {
		case (FlatLightLaf.NAME):
			success = FlatLightLaf.setup();
			break;
		case (FlatIntelliJLaf.NAME):
			success = FlatIntelliJLaf.setup();
			break;
		case (FlatDarkLaf.NAME):
			success = FlatDarkLaf.setup();
			break;
		case (FlatDarculaLaf.NAME):
			success = FlatDarculaLaf.setup();
			break;
		default:
			(...) // existing logic
		}

Improve support for Look & Feels

The OptionsLookAndFeel lets you control the L&F for the active JVM. We need to improve it as follows:

  • Persist the L&F setting.
  • Create a LookAndFeelService that sets the initial L&F to match the persisted value.
  • Add API to LookAndFeelService to change the L&F, including existing windows.

Messages are right-aligned

If you make a message like:

@Parameter(visibility = ItemVisibility.MESSAGE)
private final String settingsSection = "-- Settings --";

Then the -- Settings -- string will be right aligned.

But if you add a non-empty label (e.g., " " works well), it becomes left aligned:

@Parameter(label = "x", visibility = ItemVisibility.MESSAGE)
private final String settingsSection = "-- Settings --";

The right-aligned behavior is probably undesirable, and should be changed to left-aligned always.

/cc @milkyklim

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.