import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.input.InputMethodRequests;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class IMETest extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        IMEControl control = new IMEControl();
        Scene scene = new Scene(new StackPane(control), 400, 300);
        stage.setScene(scene);
        stage.show();
    }

    private static class IMEControl extends Control {

        public IMEControl() {}

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

    private static class IMEControlSkin extends SkinBase<IMEControl> {

        private final Label label;

        public IMEControlSkin(IMEControl control) {
            super(control);
            control.setInputMethodRequests(new InputMethodRequests() {
                @Override
                public Point2D getTextLocation(int i) {
                    return null;
                }

                @Override
                public int getLocationOffset(int i, int i1) {
                    return 0;
                }

                @Override
                public void cancelLatestCommittedText() {}

                @Override
                public String getSelectedText() {
                    return null;
                }
            });

            label = new Label();

            control.setOnInputMethodTextChanged(inputMethodEvent -> {
                if (inputMethodEvent.getCommitted() != null) {
                    label.setText(label.getText() + inputMethodEvent.getCommitted());
                }
            });
            label.setText("Composed text: ");
            getChildren().add(label);

            // This line makes the application to crash on Linux:
            control.requestFocus();
        }

        @Override
        protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) {
            super.layoutChildren(contentX, contentY, contentWidth, contentHeight);
            label.setPrefWidth(contentWidth);
            label.setPrefHeight(contentHeight);
        }
    }
}
