[英]Dragging an undecorated Stage in JavaFX
我希望將舞台設置為“UNDECORATED”,使其可拖動和最小化。 問題是我找不到這樣做的方法,因為我遇到的例子是通過插入到 main 方法中的方法來做到這一點的。
我希望通過在控制器類中聲明的方法來完成此操作,就像我如何設法使用下面的“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();
}
}
戰略
您已經在 start 方法中引用了舞台。
您需要的是能夠將舞台傳遞給您的控制器,以便控制器可以使舞台可被給定節點拖動。
“直接從調用者向控制器傳遞參數”方法可用於將階段引用傳遞給您的控制器: 傳遞參數 JavaFX FXML 。
使用此示例代碼中的makeDraggable 方法允許舞台由給定節點拖動。
示例實現
應用程序啟動方法的一些偽代碼如下:
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()
來自我之前鏈接的示例代碼。
更新您的fxml_tableview.fxml
文件以包含控制器中引用的所需的新dragNode
。
替代實現
在控制器的 initialize 方法中,在 dragNode 的 sceneProperty 和改變的場景的 window 屬性上添加一個更改監聽器,以獲取舞台更改的通知,以便您可以調用 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;
}
}
從 FXML 設置要用於拖動應用程序的控制器或組件的 id
<Pane onMousePressed="#panePressed" onMouseDragged="#paneDragged"/>
來自類Controller.java
@FXML public void panePressed(MouseEvent me){
delta.x = getStage().getX() - me.getScreenX();
delta.y = getStage().getY() - me.getScreenY();
}
@FXML public void paneDragged(MouseEvent me){
getStage().setX(delta.x + me.getScreenX());
getStage().setY(delta.y + me.getScreenY());
}
您必須有 delta 類,它將存儲 delta x 和 y 的值
public class Delta{
public double x,y;
}
要獲得舞台,只需創建 mutator 和 accessor,有關轉換的更多信息,請轉到此處
創建這個 Delta 類。
public class Delta {
double x,y;
}
在控制器類中,創建 Delta 類的實例並添加這兩個方法。
public void panepressed(MouseEvent me)
{
stage = (Stage)((Node)me.getSource()).getScene().getWindow();
delta.x= stage.getX()- me.getScreenX();
delta.y= stage.getY()- me.getScreenY();
}
public void panedraged(MouseEvent me)
{
stage = (Stage)((Node)me.getSource()).getScene().getWindow();
stage.setX(delta.x+me.getScreenX());
stage.setY(delta.y+me.getScreenY());
}
接下來在你的 fxml 文件或場景構建器中分別為 mousepressed 和 mousedragging 添加這兩個方法。
<AnchorPane onMouseDragged="#panedraged" onMousePressed="#panepressed" prefHeight="274.0" prefWidth="250.0" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.