Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexOutOfBoundsException when editor is not shown but updated #637

Closed
tobiasdiez opened this issue Nov 1, 2017 · 4 comments
Closed

IndexOutOfBoundsException when editor is not shown but updated #637

tobiasdiez opened this issue Nov 1, 2017 · 4 comments

Comments

@tobiasdiez
Copy link

tobiasdiez commented Nov 1, 2017

RTF: 0.8.1
OS: Windows

We get an IndexOutOfBoundsException in the following situation:

  • Have the richtext editor in a tab of a TabPane control
  • Switch to different tab (thus the editor is not visible) and invoke an action that updates the text of the editor (e.g. a button that invokes the clear method)
  • This results in the error displayed below.

Sorry for being a bit vague at the moment. I'll try to provide a minimal non-working example soon, but maybe the information provided so far is enough for you to already locate the issue.

java.lang.IndexOutOfBoundsException: 10 not in [0, 1]
        at org.reactfx.util.Lists.checkPosition(Lists.java:110) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.util.Lists.checkPosition(Lists.java:105) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.util.FingerTree$NonEmptyFingerTree.locateProgressively(FingerTree.java:51) ~[reactfx-2.0-M5.jar:?]
        at org.fxmisc.richtext.model.ReadOnlyStyledDocument$Pos.offsetBy(ReadOnlyStyledDocument.java:448) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.richtext.model.ReadOnlyStyledDocument.offsetToPosition(ReadOnlyStyledDocument.java:265) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.richtext.model.GenericEditableStyledDocumentBase.offsetToPosition(GenericEditableStyledDocumentBase.java:119) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.richtext.model.SimpleEditableStyledDocument.offsetToPosition(SimpleEditableStyledDocument.java:10) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.richtext.GenericStyledArea.offsetToPosition(GenericStyledArea.java:952) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.richtext.CaretImpl.lambda$new$1(CaretImpl.java:104) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.reactfx.value.Val$2.computeValue(Val.java:705) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.ValBase.getValue(ValBase.java:17) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.ValBase.newObserver(ValBase.java:40) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.ValBase.newObserver(ValBase.java:8) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.addObserver(ObservableBase.java:110) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.addInvalidationObserver(Val.java:52) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.addListener(Val.java:70) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.observeInvalidations(Val.java:432) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.MappedVal.connect(MappedVal.java:28) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.ValBase.observeInputs(ValBase.java:26) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.addObserver(ObservableBase.java:108) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.observe(ObservableBase.java:100) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.observeInvalidations(Val.java:61) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val$1.observeInputs(Val.java:104) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.addObserver(ObservableBase.java:108) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.observe(ObservableBase.java:100) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.EventStream.subscribe(EventStream.java:53) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.SuspendableBase.observeInputs(SuspendableBase.java:49) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.addObserver(ObservableBase.java:108) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.addInvalidationObserver(Val.java:52) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.addListener(Val.java:70) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val$2.connect(Val.java:693) ~[reactfx-2.0-M5.jar:?]

        at org.reactfx.value.ValBase.observeInputs(ValBase.java:26) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.addObserver(ObservableBase.java:108) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.addInvalidationObserver(Val.java:52) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.value.Val.addListener(Val.java:80) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.EventStreams$3.observeInputs(EventStreams.java:106) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.addObserver(ObservableBase.java:108) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.ObservableBase.observe(ObservableBase.java:100) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.EventStream.subscribe(EventStream.java:53) ~[reactfx-2.0-M5.jar:?]
        at org.fxmisc.richtext.GenericStyledArea.createCell(GenericStyledArea.java:1299) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.richtext.GenericStyledArea.lambda$new$9(GenericStyledArea.java:658) ~[richtextfx-0.8.1.jar:0.8.1]
        at org.fxmisc.flowless.CellPool.getCell(CellPool.java:28) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.CellListManager.cellForItem(CellListManager.java:86) ~[flowless-0.6.jar:?]
        at org.reactfx.collection.MappedList.get(MappedList.java:27) ~[reactfx-2.0-M5.jar:?]
        at org.reactfx.collection.MemoizationListImpl.get(MemoizationList.java:99) ~[reactfx-2.0-M5.jar:?]
        at org.fxmisc.flowless.CellListManager.getCell(CellListManager.java:69) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.CellPositioner.getSizedCell(CellPositioner.java:217) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.CellPositioner.placeStartAt(CellPositioner.java:127) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.Navigator.placeStartAtMayCrop(Navigator.java:201) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.Navigator.visit(Navigator.java:129) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.StartOffStart.accept(TargetPosition.java:85) ~[flowless-0.6.jar:?]
        at org.fxmisc.flowless.Navigator.layoutChildren(Navigator.java:78) ~[flowless-0.6.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1087) ~[jfxrt.jar:?]
        at org.fxmisc.flowless.VirtualFlow.layoutChildren(VirtualFlow.java:257) ~[flowless-0.6.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1087) ~[jfxrt.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1093) ~[jfxrt.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1093) ~[jfxrt.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1093) ~[jfxrt.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1093) ~[jfxrt.jar:?]
        at javafx.scene.Parent.layout(Parent.java:1093) ~[jfxrt.jar:?]
        at javafx.scene.Scene.doLayoutPass(Scene.java:552) ~[jfxrt.jar:?]
        at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2397) ~[jfxrt.jar:?]
        at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355) ~[jfxrt.jar:?]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_121]
        at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354) ~[jfxrt.jar:?]
        at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381) ~[jfxrt.jar:?]
        at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510) ~[jfxrt.jar:?]
        at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490) ~[jfxrt.jar:?]
        at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319) ~[jfxrt.jar:?]
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) ~[jfxrt.jar:?]
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) ~[jfxrt.jar:?]
        at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) ~[jfxrt.jar:?]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]
@JordanMartinez
Copy link
Contributor

This seems very similar to #579.

@JordanMartinez
Copy link
Contributor

Just FYI. I can't reproduce the bug with the following TestFX test, which seems to follow the directions you specify:

import com.nitorcreations.junit.runners.NestedRunner;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import org.fxmisc.richtext.InlineCssTextArea;
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(NestedRunner.class)
public class MiscellaneousTests {

    public class InvisibleUpdateTests extends InlineCssTextAreaAppTest {

        TabPane pane;

        @Override
        public void start(Stage stage) throws Exception {
            area = new InlineCssTextArea("some example\n text to go here\n across a couple of \n lines....");
            pane = new TabPane(
                    new Tab("main area", area),
                    new Tab("other tab", new Label("some text"))
            );
            scene = new Scene(pane);
            this.stage = stage;

            stage.setScene(scene);
            stage.setWidth(400);
            stage.setHeight(400);
            stage.show();

            // select the area's tab
            pane.getSelectionModel().select(0);
        }

        @Test
        public void test() {
            // when select a different tab (label's tab)
            // so that area is no longer visible
            pane.getSelectionModel().select(1);
//            WaitForAsyncUtils.waitForFxEvents();

            // and update the area in some way (e.g. clearing its text)
            interact(() -> area.clear());

            // no exception should be thrown
        }
    }
}

@tobiasdiez
Copy link
Author

@JordanMartinez Thank you very much for having a look at the problem! I tried to cook up a minimal example that displays the error and on the way realized it actually was not a problem with different tabs or the update while being invisible. The issue (and a lot of different related stuff) was actually caused by running clear and appendText not on the JavaFX thread! As soon as I used Platform.runLater everything seems to work fine! Thus the original issue can be closed. However, I would strongly advice to add calls to Toolkit.checkFxUserThread in the methods that update the code area!

@JordanMartinez
Copy link
Contributor

Glad you figured out the problem. I agree with your suggestion and have opened a new issue for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants