在JavaFX中拖动未修饰的舞台 [英] Dragging an undecorated Stage in JavaFX

查看:95
本文介绍了在JavaFX中拖动未修饰的舞台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将舞台设置为UNDECORATED,使其可拖动且可最小化。问题是我无法找到这样做的方法,因为我通过插入main方法中的方法来实现这一点。

I would like to have a Stage set to "UNDECORATED" made draggable and minimizable. The problem is that I can't find a way to do so since the examples I come accross that do this do so via methods inserted inside the main method.

我会喜欢通过控制器类中声明的方法完成此操作,就像我设法使用下面的WindowClose()方法一样。

I would like to have this done via a method declared in the controller class, like how I managed to do with the "WindowClose()" method below.

这是我的第二天使用JavaFX,如果这似乎是一个常见的知识问题。提前全部谢谢。

This is my second day working with JavaFX, if this seems too much of a common knowledge question. Thank you all in advance.

// 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();
    }
}


推荐答案

策略

您已经在start方法中引用了舞台。

You already have a reference to the stage in your start method.

您需要的是能够将舞台传递给您的控制器,以便控制器可以使舞台可以通过给定节点拖动。

What you need is to be able to pass the stage to your controller, so that the controller can make the stage draggable by a given node.


  1. 直接从调用者传递参数到控制器方法可用于将阶段引用传递给控制器​​:传递参数JavaFX FXML

使用此示例代码中的makeDraggable方法允许由给定节点拖动舞台。

Use the makeDraggable method from this sample code to allow the stage to be dragged by a given node.

示例实施

Application start方法的一些伪代码如下:

Some psuedo-code for the Application start method follows:

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方法:

And for the Controller's new registerStage method:

@FXML private Rectangle dragNode;

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

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

EffectUtilities.makeDraggable() comes from the sample code I linked earlier.

更新 fxml_tableview.fxml 文件,以包含控制器中引用的所需新 dragNode

Update your fxml_tableview.fxml file to include the required new dragNode referenced in the controller.

替代实现

在控制器的initialize方法中,添加更改侦听器dragNode的sceneProperty和更改后的场景的窗口属性,以获得阶段更改的通知,以便您可以调用makeDraggable。

In the initialize method of the controller, add a change listener on the dragNode's sceneProperty and the changed scene's window property to get notified of the stage change so that you can invoke 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;
  }
}

这篇关于在JavaFX中拖动未修饰的舞台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆