java - 在 JavaFX 中拖动未修饰的舞台

标签 java javafx

我想将舞台设置为“未修饰”,使其可拖动且可最小化。问题是我找不到这样做的方法,因为我遇到的示例是通过插入 main 方法中的方法来实现的。

我想通过在 Controller 类中声明的方法来完成此操作,就像我设法使用下面的“WindowClose()”方法一样。

这是我使用 JavaFX 的第二天,如果这似乎是一个太多的常识问题。提前谢谢大家。

// Main Class/ Method

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Fxmltableview extends Application {

    public static String pageSource = "fxml_tableview.fxml";
    public static Scene scene;

    @Override
    public void start(Stage stage) throws Exception {
        stage.initStyle(StageStyle.UNDECORATED);
        stage.initStyle(StageStyle.TRANSPARENT);

        Parent root = FXMLLoader.load(getClass().getResource(pageSource));

        scene = new Scene(root, Color.TRANSPARENT);

        stage.setScene(scene);
        stage.show();
    }

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

..

// The Controller

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

public class FXMLTableViewController {
    @FXML private TableView<Person> tableView;
    @FXML private TextField firstNameField;
    @FXML private TextField lastNameField;
    @FXML private TextField emailField;

    @FXML
    protected void addPerson (ActionEvent event) {
        ObservableList<Person> data = tableView.getItems();
        data.add(new Person(
                firstNameField.getText(),
                lastNameField.getText(),
                emailField.getText()
                ));

        firstNameField.setText("");
        lastNameField.setText("");
        emailField.setText("");   
    }

    public void WindowClose (ActionEvent event) {
            Platform.exit();
    }
}

最佳答案

策略

您已经在开始方法中引用了该阶段。

您需要的是能够将舞台传递给您的 Controller ,以便 Controller 可以使舞台可由给定节点拖动。

  1. “将参数直接从调用者传递到 Controller ”方法可用于将阶段引用传递给您的 Controller :Passing Parameters JavaFX FXML .

  2. 使用 makeDraggable method from this sample code允许舞台被给定节点拖动。

实现示例

应用程序启动方法的一些伪代码如下:

stage.initStyle(StageStyle.UNDECORATED);
stage.initStyle(StageStyle.TRANSPARENT);

FXMLLoader loader = new FXMLLoader(
  getClass().getResource(
    "fxml_tableview.fxml"
  )
);

stage.setScene(
  new Scene(
    (Parent) loader.load()
  )
);

FXMLTableViewController controller = 
  loader.<FXMLTableViewController>getController();
controller.registerStage(stage);

stage.show();

对于 Controller 的新 registerStage 方法:

@FXML private Rectangle dragNode;

public void registerStage(Stage stage) {
  EffectUtilities.makeDraggable(stage, dragNode)
}

EffectUtilities.makeDraggable() 来 self 之前链接的示例代码。

更新您的 fxml_tableview.fxml 文件以包含在 Controller 中引用的所需的新 dragNode

替代实现

在controller的initialize方法中,在dragNode的sceneProperty和变化场景的window属性上添加一个变化监听器来获得stage变化的通知,这样你就可以调用makeDraggable。

示例代码 EffectUtilities.makeDraggable(stage, byNode)

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.util.Duration;

/** Various utilities for applying different effects to nodes. */
public class EffectUtilities {
  /** makes a stage draggable using a given node */
  public static void makeDraggable(final Stage stage, final Node byNode) {
    final Delta dragDelta = new Delta();
    byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        // record a delta distance for the drag and drop operation.
        dragDelta.x = stage.getX() - mouseEvent.getScreenX();
        dragDelta.y = stage.getY() - mouseEvent.getScreenY();
        byNode.setCursor(Cursor.MOVE);
      }
    });
    byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        byNode.setCursor(Cursor.HAND);
      }
    });
    byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        stage.setX(mouseEvent.getScreenX() + dragDelta.x);
        stage.setY(mouseEvent.getScreenY() + dragDelta.y);
      }
    });
    byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        if (!mouseEvent.isPrimaryButtonDown()) {
          byNode.setCursor(Cursor.HAND);
        }
      }
    });
    byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        if (!mouseEvent.isPrimaryButtonDown()) {
          byNode.setCursor(Cursor.DEFAULT);
        }
      }
    });
  }

  /** records relative x and y co-ordinates. */
  private static class Delta {
    double x, y;
  }
}

关于java - 在 JavaFX 中拖动未修饰的舞台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18792822/

相关文章:

java - 将文本区域值从 FXML 传递到 Controller

java - Guice @Inject 无法使用多个构造函数注入(inject)

java - 如何将数据从另一个类传递到 GUI?

java - 生产者消费者终止

JavaFX 8-将 TableView 列 ContextMenu 锚定在列标题的正下方?

java - 如何根据 JavaFX 8 中的特定祖先获取节点边界?

java - 将触摸事件与鼠标事件分开

java - 初始化静态变量时使用局部变量

java - 线程中出现异常 "main"java.lang.NullPointerException 从 txt 读取元素

java - 通过读取每行的第一个字符将文件读入 JavaFX 网格以模块化地创建表单?