Skip to content

Commit

Permalink
Fix input harvester scrolling bug
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ctrueden committed Sep 18, 2024
1 parent 608b935 commit 506316b
Showing 1 changed file with 20 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
package org.scijava.ui.swing.widget;

import java.io.IOException;
import java.util.Objects;

import javax.swing.JEditorPane;
import javax.swing.JPanel;
Expand Down Expand Up @@ -124,6 +125,24 @@ public boolean supports(final WidgetModel model) {
@Override
public void doRefresh() {
// maybe dialog owner changed message content
pane.setText(get().getText());
String text = get().getText();
if (!Objects.equals(htmlify(text), pane.getText())) {
// NB: Only change the text if it actually changed.
// This avoids triggering a scrollRectToVisible-type behavior where the
// containing scroll pane's view gets adjusted to include this text area.
// Not sure if it's a bug, strictly speaking, but it causes undesirable
// sudden scrolling, as reported in scijava/scijava-ui-swing#74.
pane.setText(text);
}
}

// HACK: Normalize text to final HTML representation
// by feeding it through a dummy JEditorPane instance.
private JEditorPane dummy;
private String htmlify(String text) {
if (text == null) return null;
if (dummy == null) dummy = new JEditorPane("text/html", "");
dummy.setText(text);
return dummy.getText();
}
}

0 comments on commit 506316b

Please sign in to comment.