JavaFx, как добавить menuBar и DrawingPane

Я занят демонстрацией, рисую несколько линий в окне прокрутки. Пока все хорошо, но теперь можно нарисовать линии на панели меню, что, конечно, не должно быть возможным. Смотрите код ниже. Пожалуйста помоги!

Вот что происходит:

Смотрите вывод здесь

Неправильный код:

package Example12a;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class Example12a extends Application {

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

    private Line curLine;

    @Override
    public void start(Stage stage) throws Exception {
        Pane drawingPane = new Pane();
        BorderPane theBorderPane = new BorderPane();

        drawingPane.setPrefSize(800, 800);
        drawingPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

        MenuBar menuBar = new MenuBar();
        // --- Menu File
        Menu menuFile = new Menu("File");
        MenuItem add = new MenuItem("Save");
        add.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                System.out.println("Save");
            }
        }); 
        menuFile.getItems().addAll(add);
        //yOffset = (int)menuBar.getHeight();        
        Menu menuEdit = new Menu("Edit");
        Menu menuView = new Menu("View");
        menuBar.getMenus().addAll(menuFile, menuEdit, menuView);
        theBorderPane.setTop(menuBar);

        ScrollPane scrollPane = new ScrollPane(theBorderPane);
        scrollPane.setPrefSize(300, 300);
        scrollPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
        scrollPane.setFitToWidth(true);
        scrollPane.setFitToHeight(true);
        scrollPane.setStyle("-fx-focus-color: transparent;");

        theBorderPane.setOnMousePressed(event -> {
            if (!event.isPrimaryButtonDown()) {
                return;
            }

            curLine = new Line(
                event.getX(), event.getY(), 
                event.getX(), event.getY()
            );
            theBorderPane.getChildren().add(curLine);
        });

        theBorderPane.setOnMouseDragged(event -> {
            if (!event.isPrimaryButtonDown()) {
                return;
            }

            if (curLine == null) {
                return;
            }

            curLine.setEndX(event.getX());
            curLine.setEndY(event.getY());

            double mx = Math.max(curLine.getStartX(), curLine.getEndX());
            double my = Math.max(curLine.getStartY(), curLine.getEndY());

            if (mx > theBorderPane.getMinWidth()) {
                theBorderPane.setMinWidth(mx);
            }

            if (my > theBorderPane.getMinHeight()) {
                theBorderPane.setMinHeight(my);
            }
        });

        theBorderPane.setOnMouseReleased(event -> curLine = null);

        theBorderPane.setCenter(drawingPane);
        Scene scene = new Scene(scrollPane);
        stage.setMinWidth(100);
        stage.setMinHeight(100);
        stage.setScene(scene);

        stage.show();
    }
}

1 ответ

Решение

Исправлена ​​ваша раскладка.

То, что я сделал, было:

BorderPane теперь ваша корневая панель.

ScrollPane - это центр BorderPane, а его содержимое - это Drawing Pane.

MenuBar по-прежнему является верхней частью BorderPane.

Я также изменил События мыши с borderPane на Drawing Pane, и линии добавляются в Drawing Pane вместо borderPane.

Так что работает нормально.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class Example12a extends Application {

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

    private Line curLine;

    @Override
    public void start(Stage stage) throws Exception {
        Pane drawingPane = new Pane();
        BorderPane theBorderPane = new BorderPane();

        drawingPane.setPrefSize(800, 800);
        drawingPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

        MenuBar menuBar = new MenuBar();
        // --- Menu File
        Menu menuFile = new Menu("File");
        MenuItem add = new MenuItem("Save");
        add.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                System.out.println("Save");
            }
        }); 
        menuFile.getItems().addAll(add);
        //yOffset = (int)menuBar.getHeight();        
        Menu menuEdit = new Menu("Edit");
        Menu menuView = new Menu("View");
        menuBar.getMenus().addAll(menuFile, menuEdit, menuView);
        theBorderPane.setTop(menuBar);

        ScrollPane scrollPane = new ScrollPane(drawingPane);
        scrollPane.setPrefSize(300, 300);
        scrollPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
        scrollPane.setFitToWidth(true);
        scrollPane.setFitToHeight(true);
        scrollPane.setStyle("-fx-focus-color: transparent;");

        drawingPane.setOnMousePressed(event -> {
            if (!event.isPrimaryButtonDown()) {
                return;
            }

            curLine = new Line(
                event.getX(), event.getY(), 
                event.getX(), event.getY()
            );
            drawingPane.getChildren().add(curLine);
        });

        drawingPane.setOnMouseDragged(event -> {
            if (!event.isPrimaryButtonDown()) {
                return;
            }

            if (curLine == null) {
                return;
            }

            curLine.setEndX(event.getX());
            curLine.setEndY(event.getY());

            double mx = Math.max(curLine.getStartX(), curLine.getEndX());
            double my = Math.max(curLine.getStartY(), curLine.getEndY());

            if (mx > drawingPane.getMinWidth()) {
                drawingPane.setMinWidth(mx);
            }

            if (my > drawingPane.getMinHeight()) {
                drawingPane.setMinHeight(my);
            }
        });

        theBorderPane.setOnMouseReleased(event -> curLine = null);

        theBorderPane.setCenter(scrollPane);
        Scene scene = new Scene(theBorderPane);
        stage.setMinWidth(100);
        stage.setMinHeight(100);
        stage.setScene(scene);

        stage.show();
    }
}

введите описание изображения здесь

Замечания:

если вы пытаетесь создать программу для рисования, я бы предпочел визуализировать все линии на холсте вместо использования класса Line. Холст намного быстрее со многими линиями.

Другие вопросы по тегам