Description
Describe the bug
A Combo
widget that is not read-only does not yield a proper selection index via getSelectionIndex()
after the drop down has been opened and no new element is actively selected. Instead, it yields -1
. One would expect the widget to still return the current index unless some other element is selected or if the text is changed manually. This is also how the widget behaves on the other OSes.
This is particularly problematic because when using such a combo to select a different element, a paint event is triggered when selecting it before the actual selection change is processed, such that if the paint event handler retrieves the selection index, it will always receive -1
. This is why all combos in GraphicsExample
are unusable. They make the application crash on usage.
To Reproduce
- When opening any of the combo boxes in the
GraphicsExample
, such as the one in the Antialiasing -> Graphics category, the application crashes with usually an IOOBE, e.g.:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 3
at org.eclipse.swt.examples.graphics.GraphicAntialiasTab.paint(GraphicAntialiasTab.java:126)
at org.eclipse.swt.examples.graphics.GraphicsExample.lambda$2(GraphicsExample.java:228)
- The following snippet prints the index both in a scheduled way and upon mouse clicks to easily investigate the behavior. After opening the drop down, you will see that only
-1
is printed until some entry is explicitly selected again.
public class SnippetCombo {
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell(display);
shell.setText("Snippet Combo");
shell.setLayout(new GridLayout());
Combo combo = new Combo(shell, SWT.DROP_DOWN);
combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
combo.add("first");
combo.add("second");
combo.select(0);
combo.addMouseListener(MouseListener.mouseDownAdapter(e -> System.out.println("clicked: " + combo.getSelectionIndex())));
timedPrint(combo);
Text text = new Text(shell, SWT.NONE);
text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
private static void timedPrint(Combo combo) {
System.out.println("timed: " + combo.getSelectionIndex());
combo.getDisplay().timerExec(1000, () -> timedPrint(combo));
}
}
Expected behavior
- The
Combo
widget yields the proper selection index even after the drop down was opened unless some custom text is entered across all OSes (i.e., the macOS behavior should be aligned to the one on Windows and Linux). - The
GraphicsExample
does not crash when opening any of the drop down menus in there. In addition to fixingCombo
behavior, those combos could also be made read-only as the application might still crash (or not result in a useful state) if custom text is entered in those combos.
Environment:
- Select the platform(s) on which the behavior is seen:
-
- All OS
-
- Windows
-
- Linux
-
- macOS
-
Additional OS info (e.g. OS version, Linux Desktop, etc)
macOS Sequoia, version 15.5 -
JRE/JDK version
Temurin-21.0.2+13
Version since
The issue was found when testing the build for 4.36 RC2. I additionally tested with 4.35, which shows the same behavior. I guess that the behavior rather changed with some macOS update than with any changes in Eclipse (if at all).
Workaround (or) Additional context
Workarounds:
- Use combos that are read-only
- Do not open drop-down menus