Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow MouseEvents to be dispatched to disabled Nodes?

In fx, mouseEvents aren't dispatched to disabled nodes, at the end is a quick example demonstrating the behaviour.

For a Swinger like me, that's a bit surprising: in my land, events are delivered and it's the task of the target (ui-delegate) to decide whether or not the event should be handled. Actually was pointed to this by a recent - perfectly valid, IMO - use-case of showing a tooltip over a disabled component

Technically, the dispatch seems to be cut off in one of Node's impl methods:

/**
 * Finds a top-most child node that intersects the given ray.
 *
 * The result argument is used for storing the picking result.
 */
@Deprecated
public final void impl_pickNode(PickRay pickRay, PickResultChooser result) {

    // In some conditions we can omit picking this node or subgraph
    if (!isVisible() || isDisable() || isMouseTransparent()) {
        return;
    }

which seems to be called during the hit detection process. If so, it would be really deep down in the bowels without much of chance to tweak.

The questions:

  • anything wrong with my code (could easily have missed something obvious ;-)
  • is the above really the underlying reason?
  • is there any configurable option to force the dispatch? If so, how-to?
  • where's the spec of the behaviour? Looked around tutorials/api doc but couldn't find anything.

Code example:

package fx.control;

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

/**
 * @author Jeanette Winzenburg, Berlin
 */
public class MouseEventDisabled extends Application {

    private Parent getContent() {

        Pane parent = new Pane();
        Rectangle r = new Rectangle(100, 100, 200, 200);
        r.addEventHandler(MouseEvent.ANY, event -> System.out.println(event));        
        CheckBox button = new CheckBox("rectangle disabled");
        r.disableProperty().bind(button.selectedProperty());
        parent.getChildren().addAll(r, button);
        return parent;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = getContent();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
like image 845
kleopatra Avatar asked Jun 12 '14 11:06

kleopatra


1 Answers

public final ReadOnlyBooleanProperty disabledProperty

Indicates whether or not this Node is disabled. A Node will become disabled if disable is set to true on either itself or one of its ancestors in the scene graph. A disabled Node should render itself differently to indicate its disabled state to the user. Such disabled rendering is dependent on the implementation of the Node. The shape classes contained in javafx.scene.shape do not implement such rendering by default, therefore applications using shapes for handling input must implement appropriate disabled rendering themselves. The user-interface controls defined in javafx.scene.control will implement disabled-sensitive rendering, however.

A disabled Node does not receive mouse or key events.

Default value: false See Also: isDisabled(), setDisabled(boolean)

like image 169
mKorbel Avatar answered Oct 19 '22 11:10

mKorbel