Пользовательский элемент управления JavaFX

Я создал свой собственный компонент JavaFX, используя приведенный ниже код. Я использовал Behavior, чтобы перехватить сочетания клавиш. Поведение доступно только с помощью директивы -add-export. Это средство не предназначено для использования по умолчанию. Есть ли лучший способ реализовать это без поведения? Не могли бы вы просмотреть код?

    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
}

repositories {
    mavenCentral()
}

javafx {
    version = "15.0.1"
    modules = [ 'javafx.controls', 'javafx.graphics' ]
}

run {
    jvmArgs = ['--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED',
               '--add-exports=javafx.controls/com.sun.javafx.scene.control.inputmap=ALL-UNNAMED']
}
mainClassName="com.wisecoders.textpane.CustomControlApp"
package com.wisecoders.textpane;


import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.control.inputmap.InputMap;
import com.sun.javafx.scene.control.inputmap.KeyBinding;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.*;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class CustomControlApp extends Application {

    private final BorderPane root = new BorderPane();
    private final Scene scene = new Scene(root, 300, 250);

    @Override
    public void start(Stage stage) {
        stage.setTitle("Sample Canvas");

        root.setTop( new TextField());
        MyControl control = new MyControl();
        root.setCenter(control);
        stage.setScene(scene);
        stage.sizeToScene();
        Platform.runLater( control::requestFocus );
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    class MyControl extends Control {

        private final StringBuilder buffer = new StringBuilder();

        public MyControl(){
            setPrefSize(400, 400 );
            setFocusTraversable(true);
            setOnMouseClicked(ev-> requestFocus());
            requestFocus();
            setOnKeyTyped(ev-> { if ( !ev.isShortcutDown() ){
                addTextToBuffer( ev.getCharacter() );
            }});
        }
        public void addTextToBuffer( String str ){
            buffer.append( str );
            ((MyControlSkin)getSkin()).paintCanvas();
        }

        public String getText(){ return buffer.toString(); }

        @Override protected Skin<?> createDefaultSkin() {
            return new MyControlSkin(this);
        }
    }

    class MyControlSkin extends SkinBase<MyControl> {

        final BorderPane borderPane = new BorderPane();
        final ScrollBar rightScroll = new ScrollBar();
        final Canvas canvas = new Canvas();
        final MyControlBehavior behavior;

        public MyControlSkin(MyControl control) {
            super(control);
            behavior = new MyControlBehavior( control );
            rightScroll.setOrientation(Orientation.VERTICAL);
            borderPane.setRight( rightScroll );
            borderPane.setCenter(canvas);
            canvas.setWidth( 150);
            canvas.setHeight( 150 );
            getChildren().add( borderPane );
            paintCanvas();
        }

        public void paintCanvas(){
            GraphicsContext gr = canvas.getGraphicsContext2D();
            gr.clearRect( 0,0, canvas.getWidth(), canvas.getHeight());
            gr.setFill( Color.BLACK);
            gr.fillText( "Buff:" + getSkinnable().getText(), 30, 20 );
        }

        @Override
        public void dispose() {
            super.dispose();
            behavior.dispose();
            getChildren().removeAll();
        }
    }

    class MyControlBehavior extends BehaviorBase<MyControl> {

        final InputMap<MyControl> inputMap;

        public MyControlBehavior(MyControl control) {
            super(control);
            this.inputMap = createInputMap();
            addDefaultMapping( inputMap, new InputMap.KeyMapping(new KeyBinding(KeyCode.C).shortcut().ctrl(), e-> copy() ) );
        }

        public void copy(){
            final Clipboard clipboard = Clipboard.getSystemClipboard();
            final ClipboardContent content = new ClipboardContent();
            content.putString( getNode().getText() );
            clipboard.setContent(content);
        }

        @Override
        public InputMap<MyControl> getInputMap() {
            return inputMap;
        }
    }
    
}

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *