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

Allow two or more StyledTextAreas (View) to share the same StyledDocument #225

Closed

Conversation

JordanMartinez
Copy link
Contributor

  • Changed StyledTextArea's base constructor to take an EditableStyledDocument parameter. Then added an intermediary constructor (that returns the same object as previous base constructor) which creates an EditableStyledDocument before calling the new base constructor
  • Moved caret and selection-related variables from StyledTextArea to EditableStyledDocument.
  • Updated EditableStyledDocument's javadoc: now tracks caret and selection.
  • Moved StyledTextArea's getParagraphSelection code implementation to EditableStyledDocument
  • Added a demo, CloneDemo, that illustrates two StyledTextArea objects that share the same document.

…ment (Model) and make EditableStyledDocument keep track of caret and selection

- Changed StyledTextArea's base constructor to take an EditableStyledDocument parameter. Then added an intermediary constructor (that returns the same object as previous base constructor) which creates an EditableStyledDocument before calling the new base constructor
- Moved caret and selection-related variables from StyledTextArea to EditableStyledDocument.
- Updated EditableStyledDocument's javadoc: now tracks caret and selection.
- Moved StyledTextArea's `getParagraphSelection` code implementation to EditableStyledDocument
- Added a demo, CloneDemo, that illustrates two StyledTextArea objects that share the same document.
printAreaCarePosition("area", area);
printAreaCarePosition("clone", clone);

area.replaceText(0, 0, text);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one bug I ran into: after area sets its text back to text, I see only a blank area. The text is there (I only need to navigate to the left in some way or another).

Here's a picture of what that looks like:
untitled window_009

Navigating to the right/down doesn't work (since it's at the end of the area).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This display bug was fixed in commit 18ace83

…ts to avoid memory leaks now that two or more areas can be bound to the same StyledDocument
…ea would appear to be blank because area was scrolled horizontally and navigating left would fix this issue.
@JordanMartinez
Copy link
Contributor Author

I realized that I should change the constructors arguments order so that subclasses can more easily create clones.

- StyledTextArea: now has 4 constructors:
 - one with javadoc that most will use
 - same as above but preserves style
 - one that allows cloning
 - the base that all others call at some point.

 - AreaFactory: order of factory methods were changed to make it easier in source code to track which Area construction method goes with which VirtualizedScrollPane embedding method
@JordanMartinez
Copy link
Contributor Author

FYI Ran into another bug.
Update: It happens in my demo (CloneDemo) when I type Enter 2 times at the end of the first line of text.
Here's the stack trace:

Exception in thread "JavaFX Application Thread" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1967)
    at org.fxmisc.richtext.Paragraph.substring(Paragraph.java:73)
    at org.fxmisc.richtext.StyledDocumentBase.sub(StyledDocumentBase.java:245)
    at org.fxmisc.richtext.StyledDocumentBase.getText(StyledDocumentBase.java:51)
    at org.fxmisc.richtext.StyledDocumentBase.getText(StyledDocumentBase.java:46)
    at org.fxmisc.richtext.EditableStyledDocument.lambda$new$34(EditableStyledDocument.java:70)
    at org.reactfx.value.Val$2.computeValue(Val.java:703)
    at org.reactfx.value.ValBase.getValue(ValBase.java:17)
    at org.reactfx.value.SuspendableValWrapper.getValue(SuspendableValWrapper.java:23)
    at org.reactfx.value.ChangeListenerWrapper.accept(Val.java:765)
    at org.reactfx.util.AbstractReducingStreamNotifications.lambda$head$281(NotificationAccumulator.java:248)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.SuspendableBase.handleEvent(SuspendableBase.java:82)
    at org.reactfx.util.NonAccumulativeStreamNotifications.lambda$head$278(NotificationAccumulator.java:134)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.ProperEventStream.emit(ProperEventStream.java:18)
    at org.reactfx.util.AbstractReducingStreamNotifications.lambda$head$281(NotificationAccumulator.java:248)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.value.ValBase.invalidate(ValBase.java:32)
    at org.reactfx.value.Val$2.lambda$connect$136(Val.java:689)
    at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:321)
    at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    at javafx.collections.ModifiableObservableListBase$SubObservableList.clear(ModifiableObservableListBase.java:346)
    at org.fxmisc.richtext.EditableStyledDocument.setAll(EditableStyledDocument.java:512)
    at org.fxmisc.richtext.EditableStyledDocument.replace(EditableStyledDocument.java:268)
    at org.fxmisc.richtext.StyledTextArea.replace(StyledTextArea.java:1059)
    at org.fxmisc.richtext.StyledTextArea.replaceText(StyledTextArea.java:1050)
    at org.fxmisc.richtext.TextEditingArea.replaceText(TextEditingArea.java:204)
    at org.fxmisc.richtext.EditActions.replaceSelection(EditActions.java:119)
    at org.fxmisc.richtext.StyledTextAreaBehavior.lambda$static$40(StyledTextAreaBehavior.java:73)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$On.lambda$null$23(EventHandlerTemplate.java:156)
    at java.util.Optional.ifPresent(Optional.java:159)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$On.lambda$act$24(EventHandlerTemplate.java:155)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$Builder.lambda$create$21(EventHandlerTemplate.java:117)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$17(EventHandlerTemplate.java:39)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$15(EventHandlerTemplate.java:26)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$19(EventHandlerTemplate.java:49)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$15(EventHandlerTemplate.java:26)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$15(EventHandlerTemplate.java:26)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$15(EventHandlerTemplate.java:26)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$bind$14(EventHandlerTemplate.java:18)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$KeyHandler.process(Scene.java:3964)
    at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
    at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
    at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:197)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:147)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$353(GlassViewEventHandler.java:228)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:227)
    at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
    at com.sun.glass.ui.View.notifyKey(View.java:966)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:745)

@JordanMartinez
Copy link
Contributor Author

When I did the same thing in the other demos, the issue did not arise.

Update: I get the issue in my demo if I type [ENTER] and then type any other key.

…tringIndexOutOfBoundsException. Reason: referenced the list of Paragraphs that wasn't suspendable.
@JordanMartinez
Copy link
Contributor Author

Turns out paragraphs (the suspendable kind) was mistranslated from StyledTextArea to EditableStyledDocument. Clone demo no longer throws the exception. I ran into no errors when I tested FontSwitcher to insure nothing else was affected.

@JordanMartinez
Copy link
Contributor Author

Ready to be merged.

@JordanMartinez
Copy link
Contributor Author

At this point, 2+ StyledTextArea objects can share/use the same EditableStyledDocument. However, with this current implementation, it seems kind of pointless. For example, let's say there is an area (area) and it's clone (clone). If a user wanted to see one view of the document while working on another part within that same document, they would follow these steps.:

  • User clicks in area and scrolls down to see something
  • User clicks in clone to type something.

As soon as the user clicks in clone, however, the caret in area would update itself to the position in clone and, as a side effect, the viewport in area will scroll to display the same viewport that is displayed in clone.

@TomasMikula
Copy link
Member

Yeah, I agree (see my comment in #152).

@JordanMartinez JordanMartinez deleted the finishMVCRefactoring branch December 28, 2015 22:25
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

Successfully merging this pull request may close these issues.

2 participants