org.fxmisc.wellbehaved.event.Nodes Java Examples

The following examples show how to use org.fxmisc.wellbehaved.event.Nodes. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MdTextController.java    From zest-writer with GNU General Public License v3.0 6 votes vote down vote up
public void initKeyMapping(StyleClassedTextArea sourceText) {
    Platform.runLater(() -> {
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.S, SHORTCUT_DOWN), e -> handleSaveButtonAction())));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.G, SHORTCUT_DOWN), e -> handleBoldButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.I, SHORTCUT_DOWN), e -> handleItalicButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.B, SHORTCUT_DOWN), e -> handleBarredButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.K, SHORTCUT_DOWN), e -> handleTouchButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.PLUS, SHORTCUT_DOWN), e -> handleExpButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.EQUALS, SHORTCUT_DOWN), e -> handleIndButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.E, SHORTCUT_DOWN), e -> handleCenterButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.D, SHIFT_DOWN, SHORTCUT_DOWN), e -> handleRightButtonAction(null))));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.SPACE, SHORTCUT_DOWN), e -> handleUnbreakableAction())));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.L, SHORTCUT_DOWN), e -> handleGoToLineAction())));
        Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.F, SHORTCUT_DOWN), e -> handleFindReplaceDialog())));
        if (FunctionTreeFactory.isMacOs()) {
            Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.Q, SHORTCUT_DOWN), e -> currentSourceText.selectAll())));
        }
        if (MainApp.getConfig().isEditorSmart()) {
            //Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.TAB), e -> handleSmartTab())));
            //Nodes.addInputMap(sourceText, sequence(consume(keyPressed(KeyCode.ENTER), e -> handleSmartEnter())));
        }
    });
}
 
Example #2
Source File: FileEditorTabPane.java    From markdown-writer-fx with BSD 2-Clause "Simplified" License 6 votes vote down vote up
boolean canCloseEditor(FileEditor fileEditor) {
	if (!fileEditor.isModified())
		return true;

	Alert alert = mainWindow.createAlert(AlertType.CONFIRMATION,
		Messages.get("FileEditorTabPane.closeAlert.title"),
		Messages.get("FileEditorTabPane.closeAlert.message"), fileEditor.getTab().getText());
	alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO, ButtonType.CANCEL);

	// register first characters of Yes and No buttons as keys to close the alert
	for (ButtonType buttonType : Arrays.asList(ButtonType.YES, ButtonType.NO)) {
		Nodes.addInputMap(alert.getDialogPane(),
			consume(keyPressed(KeyCode.getKeyCode(buttonType.getText().substring(0, 1).toUpperCase())), e -> {
				if (!e.isConsumed()) {
					alert.setResult(buttonType);
					alert.close();
				}
			}));
	}

	ButtonType result = alert.showAndWait().get();
	if (result != ButtonType.YES)
		return (result == ButtonType.NO);

	return saveEditor(fileEditor);
}
 
Example #3
Source File: SmartEdit.java    From markdown-writer-fx with BSD 2-Clause "Simplified" License 6 votes vote down vote up
SmartEdit(MarkdownEditorPane editor, MarkdownTextArea textArea) {
		this.editor = editor;
		this.textArea = textArea;
		this.smartFormat = new SmartFormat(editor, textArea);

		Nodes.addInputMap(textArea, sequence(
			consume(keyPressed(ENTER),							this::enterPressed),
			consume(keyPressed(TAB),							this::tabPressed),
			consume(keyPressed(TAB, SHIFT_DOWN),				this::shiftTabPressed),
			consume(keyPressed(BACK_SPACE),						this::backspacePressed),
			consume(keyPressed(D, SHORTCUT_DOWN),				this::deleteLine),
			consume(keyPressed(UP, ALT_DOWN),					this::moveLinesUp),
			consume(keyPressed(DOWN, ALT_DOWN),					this::moveLinesDown),
			consume(keyPressed(UP, SHORTCUT_DOWN, ALT_DOWN),	this::duplicateLinesUp),
			consume(keyPressed(DOWN, SHORTCUT_DOWN, ALT_DOWN),	this::duplicateLinesDown),

			consume(keyPressed(F, SHORTCUT_DOWN, SHIFT_DOWN),	smartFormat::format),
			consume(keyPressed(F, SHORTCUT_DOWN, SHIFT_DOWN, ALT_DOWN),	smartFormat::format)
		));

//		textArea.selectionProperty().addListener((ob, o, n) ->
//			System.out.println(findNodes(n.getStart(), n.getEnd(), (s, e, node) -> true, true)));

		editor.markdownASTProperty().addListener((ob, o, n) -> updateStateProperties());
		textArea.selectionProperty().addListener((ob, o, n) -> updateStateProperties());
	}
 
Example #4
Source File: SyntaxHighlightingCodeArea.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public SyntaxHighlightingCodeArea() {
    // captured in the closure
    final EventHandler<WindowEvent> autoCloseHandler = e -> syntaxAutoRefresh.ifPresent(Subscription::unsubscribe);

    // handles auto shutdown of executor services
    // by attaching a handler to the stage responsible for the control
    Val.wrap(sceneProperty())
       .filter(Objects::nonNull)
       .flatMap(Scene::windowProperty)
       .values()
       .filter(Objects::nonNull)
        .subscribe(c -> c.addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, autoCloseHandler));


    // prevent ALT from focusing menu
    addEventFilter(KeyEvent.KEY_PRESSED, e -> {
        if (e.isAltDown()) {
            e.consume();
        }
    });


    // Make TAB 4 spaces
    InputMap<KeyEvent> im = InputMap.consume(
        EventPattern.keyPressed(KeyCode.TAB),
        e -> replaceSelection("    ")
    );

    Nodes.addInputMap(this, im);
}
 
Example #5
Source File: ContentEditor.java    From milkman with MIT License 4 votes vote down vote up
private void setupCodeArea() {
		codeArea = new CodeArea();
//		codeArea.setWrapText(true);
		setupParagraphGraphics();
		EventStream<Object> highLightTrigger = EventStreams.merge(codeArea.multiPlainChanges(),
				EventStreams.changesOf(highlighters.getSelectionModel().selectedItemProperty()),
				EventStreams.eventsOf(format, MouseEvent.MOUSE_CLICKED));


		//behavior of TAB: 2 spaces, allow outdention via SHIFT-TAB, if cursor is at beginning
		Nodes.addInputMap(codeArea, InputMap.consume(
				EventPattern.keyPressed(KeyCode.TAB),
				e -> codeArea.replaceSelection("  ")
		));

		Nodes.addInputMap(codeArea, InputMap.consume(
				EventPattern.keyPressed(KeyCode.TAB, SHIFT_DOWN),
				e -> {
					var paragraph = codeArea.getParagraph(codeArea.getCurrentParagraph());
					var indentation = StringUtils.countStartSpaces(paragraph.getText());

					//is the cursor in the white spaces
					if (codeArea.getCaretColumn() <= indentation){
						var charsToRemove = Math.min(indentation, 2);

						codeArea.replaceText(new IndexRange(codeArea.getAbsolutePosition(codeArea.getCurrentParagraph(), 0),
								codeArea.getAbsolutePosition(codeArea.getCurrentParagraph(), (int) charsToRemove)),
								"");
					}
				}
		));

		// sync highlighting:
//		Subscription cleanupWhenNoLongerNeedIt = highLightTrigger
//				 .successionEnds(Duration.ofMillis(500))
//				 .subscribe(ignore -> {
//					System.out.println("Triggered highlight via end-of-succession");
//					 highlightCode();
//				 });

		// async highlighting:
		Subscription cleanupWhenNoLongerNeedIt = highLightTrigger.successionEnds(Duration.ofMillis(500))
				.supplyTask(this::highlightCodeAsync).awaitLatest(codeArea.multiPlainChanges()).filterMap(t -> {
					if (t.isSuccess()) {
						return Optional.of(t.get());
					} else {
						t.getFailure().printStackTrace();
						return Optional.empty();
					}
				}).subscribe(this::applyHighlighting);

		KeyCombination.Modifier controlKey = KeyCombination.CONTROL_DOWN;
		if (SystemUtils.IS_OS_MAC){
			controlKey = KeyCombination.META_DOWN;
		}
		val keyCombination = PlatformUtil.getControlKeyCombination(KeyCode.F);
		codeArea.setOnKeyPressed(e -> {
			if (keyCombination.match(e)) {
				focusSearch();
			}
		});
	}
 
Example #6
Source File: MarkdownEditorPane.java    From markdown-writer-fx with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public MarkdownEditorPane() {
	textArea = new MarkdownTextArea();
	textArea.setWrapText(true);
	textArea.setUseInitialStyleForInsertion(true);
	textArea.getStyleClass().add("markdown-editor");
	textArea.getStylesheets().add("org/markdownwriterfx/editor/MarkdownEditor.css");
	textArea.getStylesheets().add("org/markdownwriterfx/prism.css");

	textArea.textProperty().addListener((observable, oldText, newText) -> {
		textChanged(newText);
	});

	textArea.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, this::showContextMenu);
	textArea.addEventHandler(MouseEvent.MOUSE_PRESSED, this::hideContextMenu);
	textArea.setOnDragEntered(this::onDragEntered);
	textArea.setOnDragExited(this::onDragExited);
	textArea.setOnDragOver(this::onDragOver);
	textArea.setOnDragDropped(this::onDragDropped);

	smartEdit = new SmartEdit(this, textArea);

	Nodes.addInputMap(textArea, sequence(
		consume(keyPressed(PLUS, SHORTCUT_DOWN),	this::increaseFontSize),
		consume(keyPressed(MINUS, SHORTCUT_DOWN),	this::decreaseFontSize),
		consume(keyPressed(DIGIT0, SHORTCUT_DOWN),	this::resetFontSize),
		consume(keyPressed(W, ALT_DOWN),			this::showWhitespace),
		consume(keyPressed(I, ALT_DOWN),			this::showImagesEmbedded)
	));

	// create scroll pane
	VirtualizedScrollPane<MarkdownTextArea> scrollPane = new VirtualizedScrollPane<>(textArea);

	// create border pane
	borderPane = new BottomSlidePane(scrollPane);

	overlayGraphicFactory = new ParagraphOverlayGraphicFactory(textArea);
	textArea.setParagraphGraphicFactory(overlayGraphicFactory);
	updateFont();
	updateShowLineNo();
	updateShowWhitespace();

	// initialize properties
	markdownText.set("");
	markdownAST.set(parseMarkdown(""));

	// find/replace
	findReplacePane = new FindReplacePane(textArea);
	findHitsChangeListener = this::findHitsChanged;
	findReplacePane.addListener(findHitsChangeListener);
	findReplacePane.visibleProperty().addListener((ov, oldVisible, newVisible) -> {
		if (!newVisible)
			borderPane.setBottom(null);
	});

	// listen to option changes
	optionsListener = e -> {
		if (textArea.getScene() == null)
			return; // editor closed but not yet GCed

		if (e == Options.fontFamilyProperty() || e == Options.fontSizeProperty())
			updateFont();
		else if (e == Options.showLineNoProperty())
			updateShowLineNo();
		else if (e == Options.showWhitespaceProperty())
			updateShowWhitespace();
		else if (e == Options.showImagesEmbeddedProperty())
			updateShowImagesEmbedded();
		else if (e == Options.markdownRendererProperty() || e == Options.markdownExtensionsProperty()) {
			// re-process markdown if markdown extensions option changes
			parser = null;
			textChanged(textArea.getText());
		}
	};
	WeakInvalidationListener weakOptionsListener = new WeakInvalidationListener(optionsListener);
	Options.fontFamilyProperty().addListener(weakOptionsListener);
	Options.fontSizeProperty().addListener(weakOptionsListener);
	Options.markdownRendererProperty().addListener(weakOptionsListener);
	Options.markdownExtensionsProperty().addListener(weakOptionsListener);
	Options.showLineNoProperty().addListener(weakOptionsListener);
	Options.showWhitespaceProperty().addListener(weakOptionsListener);
	Options.showImagesEmbeddedProperty().addListener(weakOptionsListener);

	// workaround a problem with wrong selection after undo:
	//   after undo the selection is 0-0, anchor is 0, but caret position is correct
	//   --> set selection to caret position
	textArea.selectionProperty().addListener((observable,oldSelection,newSelection) -> {
		// use runLater because the wrong selection temporary occurs while edition
		Platform.runLater(() -> {
			IndexRange selection = textArea.getSelection();
			int caretPosition = textArea.getCaretPosition();
			if (selection.getStart() == 0 && selection.getEnd() == 0 && textArea.getAnchor() == 0 && caretPosition > 0)
				textArea.selectRange(caretPosition, caretPosition);
		});
	});
}
 
Example #7
Source File: FindReplacePane.java    From markdown-writer-fx with BSD 2-Clause "Simplified" License 4 votes vote down vote up
Node getNode() {
	if (pane != null)
		return pane;

	initComponents();

	pane.getStyleClass().add("find-replace");
	findField.getStyleClass().add("find");
	previousButton.getStyleClass().addAll("previous", "flat-button");
	nextButton.getStyleClass().addAll("next", "flat-button");
	matchCaseButton.getStyleClass().add("flat-button");
	regexButton.getStyleClass().add("flat-button");
	closeButton.getStyleClass().addAll("close", "flat-button");
	findInfoLabel.getStyleClass().add("info");
	replaceInfoLabel.getStyleClass().add("info");

	previousButton.setGraphic(FontAwesomeIconFactory.get().createIcon(FontAwesomeIcon.CHEVRON_UP));
	nextButton.setGraphic(FontAwesomeIconFactory.get().createIcon(FontAwesomeIcon.CHEVRON_DOWN));
	closeButton.setGraphic(FontAwesomeIconFactory.get().createIcon(FontAwesomeIcon.CLOSE));

	previousButton.setTooltip(new Tooltip(Messages.get("FindReplacePane.previousButton.tooltip")));
	nextButton.setTooltip(new Tooltip(Messages.get("FindReplacePane.nextButton.tooltip")));
	matchCaseButton.setTooltip(new Tooltip(Messages.get("FindReplacePane.matchCaseButton.tooltip")));
	regexButton.setTooltip(new Tooltip(Messages.get("FindReplacePane.regexButton.tooltip")));
	closeButton.setTooltip(new Tooltip(Messages.get("FindReplacePane.closeButton.tooltip")));

	findField.setLeft(FontAwesomeIconFactory.get().createIcon(FontAwesomeIcon.SEARCH));
	findField.setRight(nOfHitCountLabel);
	findField.textProperty().addListener((ov, o, n) -> findAll(true));
	Nodes.addInputMap(findField, sequence(
			// don't know why, but Ctrl+H (set in menubar) does not work if findField has focus
			consume(keyPressed(H, SHORTCUT_DOWN), e -> show(true, false)),
			// don't know why, but F3 (set in menubar) does not work if findField has focus
			consume(keyPressed(F3),		e -> findNext()),

			consume(keyPressed(UP),		e -> findPrevious()),
			consume(keyPressed(DOWN),	e -> findNext()),
			consume(keyPressed(ENTER),	e -> findNext()),
			consume(keyPressed(ESCAPE),	e -> hide())));
	previousButton.setOnAction(e -> findPrevious());
	nextButton.setOnAction(e -> findNext());
	closeButton.setOnAction(e -> hide());

	matchCaseButton.setOnAction(e -> {
		findAll(true);
		matchCase.set(matchCaseButton.isSelected());
	} );
	regexButton.setOnAction(e -> {
		findAll(true);
		regex.set(regexButton.isSelected());
	});
	matchCaseButton.setSelected(matchCase.get());
	regexButton.setSelected(regex.get());

	nOfCountFormat = nOfHitCountLabel.getText();


	replacePane.setVisible(false);

	replaceField.setLeft(FontAwesomeIconFactory.get().createIcon(FontAwesomeIcon.RETWEET));
	Nodes.addInputMap(replaceField, sequence(
			// don't know why, but F3 (set in menubar) does not work if replaceField has focus
			consume(keyPressed(F3),		e -> findNext()),

			consume(keyPressed(UP),		e -> findPrevious()),
			consume(keyPressed(DOWN),	e -> findNext()),
			consume(keyPressed(ENTER),	e -> replace()),
			consume(keyPressed(ENTER, SHORTCUT_DOWN), e -> replaceAll()),
			consume(keyPressed(ESCAPE),	e -> hide())));
	replaceButton.setOnAction(e -> replace());
	replaceAllButton.setOnAction(e -> replaceAll());

	update();

	return pane;
}
 
Example #8
Source File: OverrideBehaviorDemo.java    From RichTextFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public void start(Stage primaryStage) {
    InlineCssTextArea area = new InlineCssTextArea();

    InputMap<Event> preventSelectionOrRightArrowNavigation = InputMap.consume(
            anyOf(
                    // prevent selection via (CTRL + ) SHIFT + [LEFT, UP, DOWN]
                    keyPressed(LEFT,    SHIFT_DOWN, SHORTCUT_ANY),
                    keyPressed(KP_LEFT, SHIFT_DOWN, SHORTCUT_ANY),
                    keyPressed(UP,    SHIFT_DOWN, SHORTCUT_ANY),
                    keyPressed(KP_UP, SHIFT_DOWN, SHORTCUT_ANY),
                    keyPressed(DOWN,    SHIFT_DOWN, SHORTCUT_ANY),
                    keyPressed(KP_DOWN, SHIFT_DOWN, SHORTCUT_ANY),

                    // prevent selection via mouse events
                    eventType(MouseEvent.MOUSE_DRAGGED),
                    eventType(MouseEvent.DRAG_DETECTED),
                    mousePressed().unless(e -> e.getClickCount() == 1 && !e.isShiftDown()),

                    // prevent any right arrow movement, regardless of modifiers
                    keyPressed(RIGHT,     SHORTCUT_ANY, SHIFT_ANY),
                    keyPressed(KP_RIGHT,  SHORTCUT_ANY, SHIFT_ANY)
            )
    );
    Nodes.addInputMap(area, preventSelectionOrRightArrowNavigation);

    area.replaceText(String.join("\n",
            "You can't move the caret to the right via the RIGHT arrow key in this area.",
            "Additionally, you cannot select anything either",
            "",
            ":-p"
    ));
    area.moveTo(0);

    CheckBox addExtraEnterHandlerCheckBox = new CheckBox("Temporarily add an EventHandler to area's `onKeyPressedProperty`?");
    addExtraEnterHandlerCheckBox.setStyle("-fx-font-weight: bold;");

    Label checkBoxExplanation = new Label(String.join("\n",
            "The added handler will insert a newline character at the caret's position when [Enter] is pressed.",
            "If checked, the default behavior and added handler will both occur: ",
            "\tthus, two newline characters should be inserted when user presses [Enter].",
            "When unchecked, the handler will be removed."
    ));
    checkBoxExplanation.setWrapText(true);

    EventHandler<KeyEvent> insertNewlineChar = e -> {
        if (e.getCode().equals(ENTER)) {
            area.insertText(area.getCaretPosition(), "\n");
            e.consume();
        }
    };
    addExtraEnterHandlerCheckBox.selectedProperty().addListener(
            (obs, ov, isSelected) -> area.setOnKeyPressed( isSelected ? insertNewlineChar : null)
    );

    VBox vbox = new VBox(area, addExtraEnterHandlerCheckBox, checkBoxExplanation);
    vbox.setSpacing(10);
    vbox.setPadding(new Insets(10));

    primaryStage.setScene(new Scene(vbox, 700, 350));
    primaryStage.show();
    primaryStage.setTitle("An area whose behavior has been overridden permanently and temporarily!");
}