JavaFX désactive le mode de surbrillance et de copie dans WebEngine


Je passe de JEditorPane à WebEngine (JavaFX).
J'avais l'habitude de verrouiller la mise en surbrillance du texte(sélection) dans JEditorPane comme suit.

my_editor.setEditable(false);
my_editor.getInputMap().put(KeyStroke.getKeyStroke("control C"), "none");

Maintenant, j'aime faire la même chose avec WebEngine, comment puis-je faire cela? désactivation de la copie, de la mise en surbrillance et du mode d'édition. Grâce.

Author: alex2410, 2014-11-20

1 answers

Si vous souhaitez désactiver la copie, la mise en surbrillance et la modification à partir de JavaFX, sans utiliser Javascript, une façon de le faire est de piéger les événements et de les traiter en conséquence, en laissant le reste des options intactes.

Utilisons un répartiteur d'événements pour filtrer quelques événements:

Pour les événements clés:

  • Évitez la copie avec Ctrl + C ou Ctrl + Insert
  • Éviter la sélection avec maj + Flèche

Pour les événements de souris:

  • Éviter la sélection de mot, ligne, paragraphe avec clic de souris
  • Eviter la sélection en faisant glisser la souris, mais en permettant de faire glisser les barres de défilement

(d'Autres pourraient être ajoutés si vous avez besoin)

public class WebEventDispatcher implements EventDispatcher {

    private final EventDispatcher oldDispatcher;
    private Point2D limit;

    public WebEventDispatcher(EventDispatcher oldDispatcher) {
        this.oldDispatcher = oldDispatcher;
    }

    public void setLimit(Point2D limit){
        this.limit = limit;
    }

    private boolean allowDrag=false;

    @Override
    public Event dispatchEvent(Event event, EventDispatchChain tail) {
        if (event instanceof MouseEvent){
            MouseEvent m = (MouseEvent)event;
            if (event.getEventType().equals(MouseEvent.MOUSE_CLICKED) || 
                event.getEventType().equals(MouseEvent.MOUSE_PRESSED)) {
                Point2D origin=new Point2D(m.getX(),m.getY());
                allowDrag=!(origin.getX()<limit.getX() && origin.getY()<limit.getY());
            }
            // avoid selection with mouse dragging, allowing dragging the scrollbars
            if (event.getEventType().equals(MouseEvent.MOUSE_DRAGGED)) {
                if(!allowDrag){
                    event.consume();
                }
            }
            // Avoid selection of word, line, paragraph with mouse click
            if(m.getClickCount()>1){
                event.consume();
            }
        }
        if (event instanceof KeyEvent && event.getEventType().equals(KeyEvent.KEY_PRESSED)){
            KeyEvent k= (KeyEvent)event;
            // Avoid copy with Ctrl+C or Ctrl+Insert
            if((k.getCode().equals(KeyCode.C) || k.getCode().equals(KeyCode.INSERT)) && k.isControlDown()){
                event.consume();
            }
            // Avoid selection with shift+Arrow
            if(k.isShiftDown() && (k.getCode().equals(KeyCode.RIGHT) || k.getCode().equals(KeyCode.LEFT) ||
                k.getCode().equals(KeyCode.UP) || k.getCode().equals(KeyCode.DOWN))){
                event.consume();
            }
        }
        return oldDispatcher.dispatchEvent(event, tail);
    }
}

Maintenant, désactivez le menu contextuel pour éviter les options copier/coller, recherchez la zone de contenu de la vue Web sans les barres de défilement, le cas échéant, et définissez le répartiteur d'événements personnalisé.

private Point2D pLimit;
private double width, height;

@Override
public void start(Stage primaryStage) {
    WebView webView = new WebView();
    WebEngine webEngine = webView.getEngine();

    // disable context menu (copy option)
    webView.setContextMenuEnabled(false);

    WebEventDispatcher webEventDispatcher = new WebEventDispatcher(webView.getEventDispatcher());
    webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {

        @Override
        public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
            if(newValue.equals(State.SUCCEEDED)){
                // dispatch all events
                webView.setEventDispatcher(webEventDispatcher);
            }
        }

    });
    webEngine.load("<URL>");

    Scene scene = new Scene(webView);

    primaryStage.setTitle("WebView scrollbar test");
    primaryStage.setScene(scene);
    primaryStage.show();

    webView.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() {

        @Override
        public void onChanged(Change<? extends Node> c) {
            pLimit=webView.localToScene(webView.getWidth(),webView.getHeight());
            webView.lookupAll(".scroll-bar").stream()
                    .map(s->(ScrollBar)s).forEach(s->{
                        if(s.getOrientation().equals(VERTICAL)){
                            width=s.getBoundsInLocal().getWidth();
                        }
                        if(s.getOrientation().equals(HORIZONTAL)){
                            height=s.getBoundsInLocal().getHeight();
                        }
                    });
            // dispatch all events
            webEventDispatcher.setLimit(pLimit.subtract(width, height));
        }
    });

}
 5
Author: José Pereda, 2014-11-20 19:32:52