Class DefaultCodeEditorView
- All Implemented Interfaces:
Styleable, EventTarget
- Direct Known Subclasses:
JsonFormatterView
This is the JavaFX counterpart of the reference code editor: the same component the
reference used (RSyntaxTextArea in an RTextScrollPane), embedded into JavaFX with a
SwingNode. That is deliberate - the editor look of the reference (background,
gutter with line numbers and fold indicator, the fine gutter border, the caret and the token
colours) is defined by the RSyntaxTextArea theme cfg/edit.xml, which ships with
this framework and originates from the reference theme (only the gutter background,
the gutter divider and the scrollbars — DarkScrollBarUI — were adjusted for this
framework).
The pane chrome (header with title and icon, body, footer with note label and buttons) is
not built here: it comes from the FXML (codeEditorPane.fxml), exactly as for every other
pane. An instance is created with DefaultCodeEditorView(BaseApp, Stage) or
DefaultCodeEditorView(BaseApp, Stage, String) and is afterwards set up with
UI.setup(BaseApp, String, ch.autumo.ui.fx.view.BaseBorderView, String),
which loads the FXML onto this view and binds the controller.
Title, icon, footer text and the additional footer buttons are not passed in a constructor:
they are set on the controller before the stage is shown, see
DefaultInfoController.customize(String, String, String) and
DefaultCodeEditorController.setButtons(java.util.List).
Syntax highlighting is RSyntaxTextArea's own tokenizer; the language is selected with
setSyntaxEditingStyle(String) using the SyntaxConstants values (JSON, YAML,
properties, plain text, ...). It is never guessed from the content - setSourceFile(Path)
derives it from the file name's extension, see syntaxStyleForExtension(String); an
application adds its own formats with registerSyntaxStyle(String, String).
Extensible by subclassing: createTextArea(), createScrollPane(RSyntaxTextArea)
and applyEditorTheme() are protected hooks an application can override to change the
editor's behaviour or look. Note that all of them are invoked from the constructor, so overrides
must build their object from the hook parameters and base-class state only - subclass fields are
not yet initialised at that point.
Two things an application that uses the editor has to know:
- It embeds Swing, and the AWT event dispatch thread is not a daemon thread: it keeps the
JVM alive after the JavaFX runtime is gone. The application ends the JVM itself and says
so with
BaseApp.isJvmExitOnStop(). - On macOS the AWT thread can block for ever in a native call while a Swing component is removed, and it holds the AWT tree lock while it does - a JavaFX thread that touches Swing in that moment waits for ever. The editor is therefore built on the AWT thread, the text is mirrored on the JavaFX side, and the JavaFX thread never waits for the AWT thread.
An application that has to know about the changes of the user overrides
textChanged(); a text the application sets itself does not trigger it.
-
Property Summary
Properties inherited from class Region
background, border, cacheShape, centerShape, height, insets, maxHeight, maxWidth, minHeight, minWidth, opaqueInsets, padding, prefHeight, prefWidth, scaleShape, shape, snapToPixel, widthProperties inherited from class Parent
needsLayoutProperties inherited from class Node
accessibleHelp, accessibleRoleDescription, accessibleRole, accessibleText, blendMode, boundsInLocal, boundsInParent, cacheHint, cache, clip, cursor, depthTest, disabled, disable, effectiveNodeOrientation, effect, eventDispatcher, focused, focusTraversable, focusVisible, focusWithin, hover, id, inputMethodRequests, layoutBounds, layoutX, layoutY, localToParentTransform, localToSceneTransform, managed, mouseTransparent, nodeOrientation, onContextMenuRequested, onDragDetected, onDragDone, onDragDropped, onDragEntered, onDragExited, onDragOver, onInputMethodTextChanged, onKeyPressed, onKeyReleased, onKeyTyped, onMouseClicked, onMouseDragEntered, onMouseDragExited, onMouseDragged, onMouseDragOver, onMouseDragReleased, onMouseEntered, onMouseExited, onMouseMoved, onMousePressed, onMouseReleased, onRotate, onRotationFinished, onRotationStarted, onScrollFinished, onScroll, onScrollStarted, onSwipeDown, onSwipeLeft, onSwipeRight, onSwipeUp, onTouchMoved, onTouchPressed, onTouchReleased, onTouchStationary, onZoomFinished, onZoom, onZoomStarted, opacity, parent, pickOnBounds, pressed, rotate, rotationAxis, scaleX, scaleY, scaleZ, scene, style, translateX, translateY, translateZ, viewOrder, visible -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringCSS class of the whole pane, set by the FXML and used to scope the pane styles.Fields inherited from class BaseBorderView
controller, modelFields inherited from class Region
USE_COMPUTED_SIZE, USE_PREF_SIZEFields inherited from class Node
BASELINE_OFFSET_SAME_AS_HEIGHT -
Constructor Summary
ConstructorsConstructorDescriptionDefaultCodeEditorView(BaseApp app, Stage stage) Default code editor view.DefaultCodeEditorView(BaseApp app, Stage stage, String styleResourcePath) Default code editor view. -
Method Summary
Modifier and TypeMethodDescriptionprotected voidApply the RSyntaxTextArea theme and the token colours of the reference, in the theme order: theme first, then the JSON panel's token colours, then the explicit overrides (selection, current line, font, anti-aliasing).voidMove the caret to the document start, as the formatter did after formatting.protected org.fife.ui.rtextarea.RTextScrollPanecreateScrollPane(org.fife.ui.rsyntaxtextarea.RSyntaxTextArea area) Create the scroll pane around the editor widget: line-number gutter with fold indicator, the fine frame of the reference (Constants.BG_COLOR_FIELD, 1px) and dark scrollbars (DarkScrollBarUI- Swing's own look & feel would paint light ones, which clash with the dark editor theme).protected org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaCreate the editor widget: an RSyntaxTextArea with the settings the reference editor had before its theme was applied (tab size, margin, line wrap, colours).static voiddisableInputMethods(Component component) Switches the input methods off for a component and all its children.Get the editor widget wrapped in its JavaFX container; this is the node the controller embeds into the pane body (seeDefaultCodeEditorController.init(URL, ResourceBundle, double)).Get the swing node holding the editor, e.g.getText()Get the current editor text.org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaGet the underlying editor widget.voidregisterSyntaxStyle(String extension, String syntaxStyle) Registers a file-name extension for this editor, e.g.voidsetSourceFile(Path file) Load a file into the editor: its content (read as UTF-8) becomes the editor text and the syntax highlighting language is selected from the file name's extension, seesyntaxStyleForExtension(String).voidsetSyntaxEditingStyle(String syntaxStyle) Select the syntax highlighting language, one of theSyntaxConstantsvalues (SYNTAX_STYLE_JSON,SYNTAX_STYLE_YAML,SYNTAX_STYLE_PROPERTIES,SYNTAX_STYLE_NONE, ...).voidSet the editor text.static StringsyntaxStyleFor(String fileName) RSyntaxTextArea syntax style constant for a file-name extension (case-insensitive).syntaxStyleForExtension(String fileName) RSyntaxTextArea syntax style constant for a file name, derived from its extension (case-insensitive).protected voidCalled when the user changed the text in the editor.Methods inherited from class BaseBorderView
getApp, getController, getModel, getStage, setController, setModel, showMethods inherited from class BorderPane
bottomProperty, centerProperty, clearConstraints, computeMinHeight, computeMinWidth, computePrefHeight, computePrefWidth, getAlignment, getBottom, getCenter, getContentBias, getLeft, getMargin, getRight, getTop, layoutChildren, leftProperty, rightProperty, setAlignment, setBottom, setCenter, setLeft, setMargin, setRight, setTop, topPropertyMethods inherited from class Pane
getChildrenMethods inherited from class Region
backgroundProperty, borderProperty, cacheShapeProperty, centerShapeProperty, computeMaxHeight, computeMaxWidth, getBackground, getBorder, getClassCssMetaData, getCssMetaData, getHeight, getInsets, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getOpaqueInsets, getPadding, getPrefHeight, getPrefWidth, getShape, getUserAgentStylesheet, getWidth, heightProperty, insetsProperty, isCacheShape, isCenterShape, isResizable, isScaleShape, isSnapToPixel, layoutInArea, layoutInArea, layoutInArea, layoutInArea, maxHeight, maxHeightProperty, maxWidth, maxWidthProperty, minHeight, minHeightProperty, minWidth, minWidthProperty, opaqueInsetsProperty, paddingProperty, positionInArea, positionInArea, prefHeight, prefHeightProperty, prefWidth, prefWidthProperty, resize, scaleShapeProperty, setBackground, setBorder, setCacheShape, setCenterShape, setHeight, setMaxHeight, setMaxSize, setMaxWidth, setMinHeight, setMinSize, setMinWidth, setOpaqueInsets, setPadding, setPrefHeight, setPrefSize, setPrefWidth, setScaleShape, setShape, setSnapToPixel, setWidth, shapeProperty, snappedBottomInset, snappedLeftInset, snappedRightInset, snappedTopInset, snapPosition, snapPositionX, snapPositionY, snapSize, snapSizeX, snapSizeY, snapSpace, snapSpaceX, snapSpaceY, snapToPixelProperty, widthPropertyMethods inherited from class Parent
getBaselineOffset, getChildrenUnmodifiable, getManagedChildren, getStylesheets, isNeedsLayout, layout, lookup, needsLayoutProperty, queryAccessibleAttribute, requestLayout, requestParentLayout, setNeedsLayout, updateBoundsMethods inherited from class Node
accessibleHelpProperty, accessibleRoleDescriptionProperty, accessibleRoleProperty, accessibleTextProperty, addEventFilter, addEventHandler, applyCss, autosize, blendModeProperty, boundsInLocalProperty, boundsInParentProperty, buildEventDispatchChain, cacheHintProperty, cacheProperty, clipProperty, computeAreaInScreen, contains, contains, cursorProperty, depthTestProperty, disabledProperty, disableProperty, effectiveNodeOrientationProperty, effectProperty, eventDispatcherProperty, executeAccessibleAction, fireEvent, focusedProperty, focusTraversableProperty, focusVisibleProperty, focusWithinProperty, getAccessibleHelp, getAccessibleRole, getAccessibleRoleDescription, getAccessibleText, getBlendMode, getBoundsInLocal, getBoundsInParent, getCacheHint, getClip, getCursor, getDepthTest, getEffect, getEffectiveNodeOrientation, getEventDispatcher, getId, getInitialCursor, getInitialFocusTraversable, getInputMethodRequests, getLayoutBounds, getLayoutX, getLayoutY, getLocalToParentTransform, getLocalToSceneTransform, getNodeOrientation, getOnContextMenuRequested, getOnDragDetected, getOnDragDone, getOnDragDropped, getOnDragEntered, getOnDragExited, getOnDragOver, getOnInputMethodTextChanged, getOnKeyPressed, getOnKeyReleased, getOnKeyTyped, getOnMouseClicked, getOnMouseDragEntered, getOnMouseDragExited, getOnMouseDragged, getOnMouseDragOver, getOnMouseDragReleased, getOnMouseEntered, getOnMouseExited, getOnMouseMoved, getOnMousePressed, getOnMouseReleased, getOnRotate, getOnRotationFinished, getOnRotationStarted, getOnScroll, getOnScrollFinished, getOnScrollStarted, getOnSwipeDown, getOnSwipeLeft, getOnSwipeRight, getOnSwipeUp, getOnTouchMoved, getOnTouchPressed, getOnTouchReleased, getOnTouchStationary, getOnZoom, getOnZoomFinished, getOnZoomStarted, getOpacity, getParent, getProperties, getPseudoClassStates, getRotate, getRotationAxis, getScaleX, getScaleY, getScaleZ, getScene, getStyle, getStyleableParent, getStyleClass, getTransforms, getTranslateX, getTranslateY, getTranslateZ, getTypeSelector, getUserData, getViewOrder, hasProperties, hoverProperty, idProperty, inputMethodRequestsProperty, intersects, intersects, isCache, isDisable, isDisabled, isFocused, isFocusTraversable, isFocusVisible, isFocusWithin, isHover, isManaged, isMouseTransparent, isPickOnBounds, isPressed, isVisible, layoutBoundsProperty, layoutXProperty, layoutYProperty, localToParent, localToParent, localToParent, localToParent, localToParent, localToParentTransformProperty, localToScene, localToScene, localToScene, localToScene, localToScene, localToScene, localToScene, localToScene, localToScene, localToScene, localToSceneTransformProperty, localToScreen, localToScreen, localToScreen, localToScreen, localToScreen, lookupAll, managedProperty, mouseTransparentProperty, nodeOrientationProperty, notifyAccessibleAttributeChanged, onContextMenuRequestedProperty, onDragDetectedProperty, onDragDoneProperty, onDragDroppedProperty, onDragEnteredProperty, onDragExitedProperty, onDragOverProperty, onInputMethodTextChangedProperty, onKeyPressedProperty, onKeyReleasedProperty, onKeyTypedProperty, onMouseClickedProperty, onMouseDragEnteredProperty, onMouseDragExitedProperty, onMouseDraggedProperty, onMouseDragOverProperty, onMouseDragReleasedProperty, onMouseEnteredProperty, onMouseExitedProperty, onMouseMovedProperty, onMousePressedProperty, onMouseReleasedProperty, onRotateProperty, onRotationFinishedProperty, onRotationStartedProperty, onScrollFinishedProperty, onScrollProperty, onScrollStartedProperty, onSwipeDownProperty, onSwipeLeftProperty, onSwipeRightProperty, onSwipeUpProperty, onTouchMovedProperty, onTouchPressedProperty, onTouchReleasedProperty, onTouchStationaryProperty, onZoomFinishedProperty, onZoomProperty, onZoomStartedProperty, opacityProperty, parentProperty, parentToLocal, parentToLocal, parentToLocal, parentToLocal, parentToLocal, pickOnBoundsProperty, pressedProperty, pseudoClassStateChanged, relocate, removeEventFilter, removeEventHandler, requestFocus, requestFocusTraversal, resizeRelocate, rotateProperty, rotationAxisProperty, scaleXProperty, scaleYProperty, scaleZProperty, sceneProperty, sceneToLocal, sceneToLocal, sceneToLocal, sceneToLocal, sceneToLocal, sceneToLocal, sceneToLocal, sceneToLocal, screenToLocal, screenToLocal, screenToLocal, setAccessibleHelp, setAccessibleRole, setAccessibleRoleDescription, setAccessibleText, setBlendMode, setCache, setCacheHint, setClip, setCursor, setDepthTest, setDisable, setDisabled, setEffect, setEventDispatcher, setEventHandler, setFocused, setFocusTraversable, setHover, setId, setInputMethodRequests, setLayoutX, setLayoutY, setManaged, setMouseTransparent, setNodeOrientation, setOnContextMenuRequested, setOnDragDetected, setOnDragDone, setOnDragDropped, setOnDragEntered, setOnDragExited, setOnDragOver, setOnInputMethodTextChanged, setOnKeyPressed, setOnKeyReleased, setOnKeyTyped, setOnMouseClicked, setOnMouseDragEntered, setOnMouseDragExited, setOnMouseDragged, setOnMouseDragOver, setOnMouseDragReleased, setOnMouseEntered, setOnMouseExited, setOnMouseMoved, setOnMousePressed, setOnMouseReleased, setOnRotate, setOnRotationFinished, setOnRotationStarted, setOnScroll, setOnScrollFinished, setOnScrollStarted, setOnSwipeDown, setOnSwipeLeft, setOnSwipeRight, setOnSwipeUp, setOnTouchMoved, setOnTouchPressed, setOnTouchReleased, setOnTouchStationary, setOnZoom, setOnZoomFinished, setOnZoomStarted, setOpacity, setPickOnBounds, setPressed, setRotate, setRotationAxis, setScaleX, setScaleY, setScaleZ, setStyle, setTranslateX, setTranslateY, setTranslateZ, setUserData, setViewOrder, setVisible, snapshot, snapshot, startDragAndDrop, startFullDrag, styleProperty, toBack, toFront, toString, translateXProperty, translateYProperty, translateZProperty, usesMirroring, viewOrderProperty, visiblePropertyMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface Styleable
getStyleableNode
-
Field Details
-
STYLE_CLASS
CSS class of the whole pane, set by the FXML and used to scope the pane styles.- See Also:
-
-
Constructor Details
-
DefaultCodeEditorView
-
DefaultCodeEditorView
-
-
Method Details
-
disableInputMethods
Switches the input methods off for a component and all its children.Every AWT component has the input methods enabled by default (see the event mask of
java.awt.Component), and while a component is removed macOS asks for its input context:Component.removeNotify()callsgetInputContext(), which ends in the native input method of the operating system. That call can block the AWT event dispatch thread forever - the application then freezes and the JVM does not exit. A component without input methods is removed without that call.The whole hierarchy has to be covered, not only the text area: the gutter and its fold indicator are removed as well, and they ask for their input context, too.
- Parameters:
component- the component and its children
-
createTextArea
protected org.fife.ui.rsyntaxtextarea.RSyntaxTextArea createTextArea()Create the editor widget: an RSyntaxTextArea with the settings the reference editor had before its theme was applied (tab size, margin, line wrap, colours). The default syntax style is plain text; subclasses/callers select a language withsetSyntaxEditingStyle(String).- Returns:
- the editor widget
-
createScrollPane
protected org.fife.ui.rtextarea.RTextScrollPane createScrollPane(org.fife.ui.rsyntaxtextarea.RSyntaxTextArea area) Create the scroll pane around the editor widget: line-number gutter with fold indicator, the fine frame of the reference (Constants.BG_COLOR_FIELD, 1px) and dark scrollbars (DarkScrollBarUI- Swing's own look & feel would paint light ones, which clash with the dark editor theme).- Parameters:
area- the editor widget- Returns:
- the scroll pane holding the editor
-
applyEditorTheme
protected void applyEditorTheme()Apply the RSyntaxTextArea theme and the token colours of the reference, in the theme order: theme first, then the JSON panel's token colours, then the explicit overrides (selection, current line, font, anti-aliasing).The theme is applied after the scroll pane exists, because it also styles the gutter: line numbers, gutter background, gutter border (the fine line right of the numbers) and the fold indicator colours come from
cfg/edit.xml- derived from the file the reference shipped. -
getEditorPane
Get the editor widget wrapped in its JavaFX container; this is the node the controller embeds into the pane body (seeDefaultCodeEditorController.init(URL, ResourceBundle, double)). The container holds aSwingNodewith the RSyntaxTextArea scroll pane.- Returns:
- the scrollable editor widget
-
getTextArea
public org.fife.ui.rsyntaxtextarea.RSyntaxTextArea getTextArea()Get the underlying editor widget.- Returns:
- the code editor
-
getSwingNode
Get the swing node holding the editor, e.g. for focus handling.- Returns:
- the swing node
-
getText
-
setText
Set the editor text.This is a change of the application, not of the user:
textChanged()is not called for it.- Parameters:
text- the text
-
textChanged
protected void textChanged()Called when the user changed the text in the editor.The default does nothing. An application that keeps the edited text somewhere else, or that has to mark the document as modified, overrides it:
@Override protected void textChanged() { Platform.runLater(() -> markModified()); }The call comes from the AWT event dispatch thread - the thread the editor lives on. An application that touches the JavaFX scene has to hand the call over with
Platform.runLater(Runnable). -
setSourceFile
Load a file into the editor: its content (read as UTF-8) becomes the editor text and the syntax highlighting language is selected from the file name's extension, seesyntaxStyleForExtension(String). An unknown extension results in plain text (SyntaxConstants.SYNTAX_STYLE_NONE) - the editor never guesses a language from the content.This is a convenience for the common "open this file" case; to set text and language separately (e.g. generated content), use
setText(String)andsetSyntaxEditingStyle(String)directly.- Parameters:
file- file to show in the editor- Throws:
IOException- if the file cannot be read
-
syntaxStyleForExtension
RSyntaxTextArea syntax style constant for a file name, derived from its extension (case-insensitive). Config/data formats first - these are the files this framework's editors are used for - then common source formats; everything else is plain text.Extensions registered with
registerSyntaxStyle(String, String)are checked first, so an application can add its own formats to this editor.- Parameters:
fileName- file name (only the extension is looked at), may benull- Returns:
- the
SyntaxConstantsvalue,SyntaxConstants.SYNTAX_STYLE_NONEif the extension is unknown
-
registerSyntaxStyle
Registers a file-name extension for this editor, e.g.registerSyntaxStyle("ifcx", SyntaxConstants.SYNTAX_STYLE_YAML). Registered extensions are checked before the built-in table and overwrite a previous registration of the same extension.- Parameters:
extension- file-name extension without dot, case-insensitive, e.g.ifcxsyntaxStyle- the RSyntaxTextArea syntax style constant to use for it
-
syntaxStyleFor
RSyntaxTextArea syntax style constant for a file-name extension (case-insensitive). Config/data formats first - these are the files this framework's editors are used for - then common source formats; everything else is plain text.- Parameters:
fileName- file name (only the extension is looked at), may benull- Returns:
- the
SyntaxConstantsvalue,SyntaxConstants.SYNTAX_STYLE_NONEif the extension is unknown
-
setSyntaxEditingStyle
Select the syntax highlighting language, one of theSyntaxConstantsvalues (SYNTAX_STYLE_JSON,SYNTAX_STYLE_YAML,SYNTAX_STYLE_PROPERTIES,SYNTAX_STYLE_NONE, ...). RSyntaxTextArea highlights exactly one language at a time.- Parameters:
syntaxStyle- the RSyntaxTextArea syntax style constant
-
caretToStart
public void caretToStart()Move the caret to the document start, as the formatter did after formatting.
-