Skip to content

Commit 506316b

Browse files
committed
Fix input harvester scrolling bug
When a dialog is large enough to create scroll bars, and the dialog contains a message widget (String with visibility=MESSAGE), the dialog's view would snap back to scroll the first such message widget into view. It happens when setText is called on the widget's JTextArea, even when the text being set is the same as it was previously. I'm guessing this is a bug in Java somehow. Not sure whether the snap-back is intended to occur when the text changes, but in the case of SciJava message parameters, the text typically never changes, so we can avoid the issue in the vast majority of scenarios by only calling setText when the text *has* actually changed. Unfortunately, a JTextPane in text/html mode is backed by some pretty fancy logic that normalizes the input HTML, such that the final assigned text does not precisely match the input text. For example: Hello becomes something like: <html> <body> Hello </body> </html> and then a naive string comparison fails. To work around this fact, this patch introduces a dummy JTextPane for the sole purpose of filtering the input text, so that it can be compared against the real JTextPane's current text before we attempt to assign it needlessly. Closes #74.
1 parent 608b935 commit 506316b

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

src/main/java/org/scijava/ui/swing/widget/SwingMessageWidget.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
package org.scijava.ui.swing.widget;
3131

3232
import java.io.IOException;
33+
import java.util.Objects;
3334

3435
import javax.swing.JEditorPane;
3536
import javax.swing.JPanel;
@@ -124,6 +125,24 @@ public boolean supports(final WidgetModel model) {
124125
@Override
125126
public void doRefresh() {
126127
// maybe dialog owner changed message content
127-
pane.setText(get().getText());
128+
String text = get().getText();
129+
if (!Objects.equals(htmlify(text), pane.getText())) {
130+
// NB: Only change the text if it actually changed.
131+
// This avoids triggering a scrollRectToVisible-type behavior where the
132+
// containing scroll pane's view gets adjusted to include this text area.
133+
// Not sure if it's a bug, strictly speaking, but it causes undesirable
134+
// sudden scrolling, as reported in scijava/scijava-ui-swing#74.
135+
pane.setText(text);
136+
}
137+
}
138+
139+
// HACK: Normalize text to final HTML representation
140+
// by feeding it through a dummy JEditorPane instance.
141+
private JEditorPane dummy;
142+
private String htmlify(String text) {
143+
if (text == null) return null;
144+
if (dummy == null) dummy = new JEditorPane("text/html", "");
145+
dummy.setText(text);
146+
return dummy.getText();
128147
}
129148
}

0 commit comments

Comments
 (0)