文档



JavaFX:事件处理

A DraggablePanelsExample.java

有关描述,请参见使用事件过滤器

法律条款和版权声明

/*
 * 版权所有 (c) 2012, 2014, Oracle及其附属公司。
 * 保留所有权利。使用受许可条款约束。
 *
 * 此文件可在以下许可下使用和许可:
 *
 * 源代码的重新发布和使用,无论是否进行修改,只要满足以下条件:
 *
 *  - 必须保留上述版权声明、此条件列表和以下免责声明。
 *  - 以二进制形式重新发布的代码必须在文档和/或其他提供的材料中复制上述版权声明、此条件列表和以下免责声明。
 *  - 未经特定事先书面许可,不得使用Oracle或其贡献者的名称来认可或推广从本软件派生的产品。
 *
 * 本软件由版权持有人和贡献者“按原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性和适用于特定目的的保证。
 * 在任何情况下,版权所有者或贡献者均不对任何直接、间接、偶然、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购、使用损失、数据或利润损失、业务中断等)承担任何责任,无论是合同责任、严格责任还是侵权行为(包括疏忽或其他)。
 */

代码

package draggablepanelsexample;
 
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
public final class DraggablePanelsExample extends Application {
    private final BooleanProperty dragModeActiveProperty =
            new SimpleBooleanProperty(this, "dragModeActive", true);
 
    @Override
    public void start(final Stage stage) {
        final Node loginPanel =
                makeDraggable(createLoginPanel());
        final Node confirmationPanel =
                makeDraggable(createConfirmationPanel());
        final Node progressPanel =
                makeDraggable(createProgressPanel());
 
        loginPanel.relocate(0, 0);
        confirmationPanel.relocate(0, 67);
        progressPanel.relocate(0, 106);
 
        final Pane panelsPane = new Pane();
        panelsPane.getChildren().addAll(loginPanel,
                                        confirmationPanel,
                                        progressPanel);
 
        final BorderPane sceneRoot = new BorderPane();
 
        BorderPane.setAlignment(panelsPane, Pos.TOP_LEFT);
        sceneRoot.setCenter(panelsPane);
 
        final CheckBox dragModeCheckbox = new CheckBox("Drag mode");
        BorderPane.setMargin(dragModeCheckbox, new Insets(6));
        sceneRoot.setBottom(dragModeCheckbox);
 
        dragModeActiveProperty.bind(dragModeCheckbox.selectedProperty());
 
        final Scene scene = new Scene(sceneRoot, 400, 300);
        stage.setScene(scene);
        stage.setTitle("Draggable Panels Example");
        stage.show();
    }
 
    public static void main(final String[] args) {
        launch(args);
    }
 
    private Node makeDraggable(final Node node) {
        final DragContext dragContext = new DragContext();
        final Group wrapGroup = new Group(node);
 
        wrapGroup.addEventFilter(
                MouseEvent.ANY,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        if (dragModeActiveProperty.get()) {
                            // disable mouse events for all children
                            mouseEvent.consume();
                        }
                    }
                });
 
        wrapGroup.addEventFilter(
                MouseEvent.MOUSE_PRESSED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        if (dragModeActiveProperty.get()) {
                            // remember initial mouse cursor coordinates
                            // and node position
                            dragContext.mouseAnchorX = mouseEvent.getX();
                            dragContext.mouseAnchorY = mouseEvent.getY();
                            dragContext.initialTranslateX =
                                    node.getTranslateX();
                            dragContext.initialTranslateY =
                                    node.getTranslateY();
                        }
                    }
                });
 
        wrapGroup.addEventFilter(
                MouseEvent.MOUSE_DRAGGED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        if (dragModeActiveProperty.get()) {
                            // shift node from its initial position by delta
                            // calculated from mouse cursor movement
                            node.setTranslateX(
                                    dragContext.initialTranslateX
                                        + mouseEvent.getX()
                                        - dragContext.mouseAnchorX);
                            node.setTranslateY(
                                    dragContext.initialTranslateY
                                        + mouseEvent.getY()
                                        - dragContext.mouseAnchorY);
                        }
                    }
                });
                
        return wrapGroup;
    }
 
    private static Node createLoginPanel() {
        final ToggleGroup toggleGroup = new ToggleGroup();
 
        final TextField textField = new TextField();
        textField.setPrefColumnCount(10);
        textField.setPromptText("Your name");
 
        final PasswordField passwordField = new PasswordField();
        passwordField.setPrefColumnCount(10);
        passwordField.setPromptText("Your password");
 
        final ChoiceBox<String> choiceBox = new ChoiceBox<>(
                FXCollections.observableArrayList(
                        "English", "\u0420\u0443\u0441\u0441\u043a\u0438\u0439",
                        "Fran\u00E7ais"));
        choiceBox.setTooltip(new Tooltip("Your language"));
        choiceBox.getSelectionModel().select(0);
 
        final HBox panel =
                createHBox(6,
                    createVBox(2, createRadioButton("High", toggleGroup, true),
                                  createRadioButton("Medium", toggleGroup,
                                                    false),
                                  createRadioButton("Low", toggleGroup, false)),
                    createVBox(2, textField, passwordField),
                    choiceBox);
        panel.setAlignment(Pos.BOTTOM_LEFT);
        configureBorder(panel);
 
        return panel;
    }
 
    private static Node createConfirmationPanel() {
        final Label acceptanceLabel = new Label("Not Available");
 
        final Button acceptButton = new Button("Accept");
        acceptButton.setOnAction(
                new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(final ActionEvent event) {
                        acceptanceLabel.setText("Accepted");
                    }
                });
 
        final Button declineButton = new Button("Decline");
        declineButton.setOnAction(
                new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(final ActionEvent event) {
                        acceptanceLabel.setText("Declined");
                    }
                });
 
        final HBox panel = createHBox(6, acceptButton,
                                         declineButton,
                                         acceptanceLabel);
        panel.setAlignment(Pos.CENTER_LEFT);
        configureBorder(panel);
 
        return panel;
    }
 
    private static Node createProgressPanel() {
        final Slider slider = new Slider();
 
        final ProgressIndicator progressIndicator = new ProgressIndicator(0);
        progressIndicator.progressProperty().bind(
                Bindings.divide(slider.valueProperty(),
                                slider.maxProperty()));
 
        final HBox panel = createHBox(6, new Label("Progress:"),
                                         slider,
                                         progressIndicator);
        configureBorder(panel);
 
        return panel;
    }
 
    private static void configureBorder(final Region region) {
        region.setStyle("-fx-background-color: white;"
                            + "-fx-border-color: black;"
                            + "-fx-border-width: 1;"
                            + "-fx-border-radius: 6;"
                            + "-fx-padding: 6;");
    }
 
    private static RadioButton createRadioButton(final String text,
                                                 final ToggleGroup toggleGroup,
                                                 final boolean selected) {
        final RadioButton radioButton = new RadioButton(text);
        radioButton.setToggleGroup(toggleGroup);
        radioButton.setSelected(selected);
 
        return radioButton;
    }
 
    private static HBox createHBox(final double spacing,
                                   final Node... children) {
        final HBox hbox = new HBox(spacing);
        hbox.getChildren().addAll(children);
        return hbox;
    }
 
    private static VBox createVBox(final double spacing,
                                   final Node... children) {
        final VBox vbox = new VBox(spacing);
        vbox.getChildren().addAll(children);
        return vbox;
    }
 
    private static final class DragContext {
        public double mouseAnchorX;
        public double mouseAnchorY;
        public double initialTranslateX;
        public double initialTranslateY;
    }
}
关闭窗口

目录

JavaFX: 事件处理

展开 折叠