我不确定该怎么称呼,但是您一定会理解我的意思... 至少我希望你能。
首先:我的窗格中包含ScrollPane。此窗格还包含两个按钮,可以在其上的ScrollPane中创建矩形。
我可以拖动这些矩形,然后将它们移出视线。到目前为止,除了ScrollPane之外,其他所有东西都可以正常工作。通常,您需要ScrollPane扩展他的Scroll,因此,如果您放开Rectangle,可以滚动到该Rectangle并再次抓住它,但是友好的JavaFX不知道如何扩展Scroll,因此我无法再次进入此Rectangle。 / p>
或者我只是想念一些重要的部分(这很可能会发生)
我的代码中有些话:我认为这不是我现有代码中的问题,而是更多需要解决的问题。我为ScrollPane所做的唯一更改是,将ScrollBarPolicy设置为always,并设置ScrollPane Pannable,但是当我单击Rectangle时会消耗掉它,因此我可以移动它们而不平移ScrollPane。
您在上面看到的是一个全角矩形,而另一半部分不在ScrollPane边界内,但是ScrollPane不会展开ScrollBar。 没关系,我将Rectangle从那些边界移到多远,滚动条都不会改变,这很不好,因为这是我选择ScrollPane的唯一原因,而且我认为,这是唯一(最简单的)实现此“编辑器”的窗格喜欢”视图。
是的,非常感谢您至少阅读了此书,并始终对我的英语打断^^表示歉意。希望您能给我有关如何解决此问题的建议!
编辑:
这是一个最小的示例: Controller.java
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
public class Controller implements Initializable{
@FXML ScrollPane actionWin;
Rectangle r;
Double orgTranslateX, orgTranslateY, orgSceneX, orgSceneY, newTranslateX, newTranslateY, offsetY, offsetX;
int i = 50;
List<Rectangle> recs = new ArrayList<Rectangle>();
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
actionWin.setPannable(true);
actionWin.setHbarPolicy(ScrollBarPolicy.ALWAYS);
actionWin.setVbarPolicy(ScrollBarPolicy.ALWAYS);
}
@FXML
public void createEntity(){
Pane container = new Pane();
// Button 1
r = new Rectangle();
r.addEventHandler(MouseEvent.ANY, event -> {
if(event.getButton() != MouseButton.MIDDLE) event.consume();
});
r.setOnMousePressed(onMousePressedEventHandler);
r.setOnMouseDragged(onMouseDraggedEventHandler);
r.setX(i);
r.setY(i);
r.setWidth(50);
r.setHeight(20);
i+=30;
recs.add(r);
for(Rectangle rec : recs){
container.getChildren().add(rec);
}
actionWin.setContent(container);
try {
AnchorPane root = (AnchorPane) FXMLLoader.load(getClass().getResource("Main.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
}
EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent arg0) {
orgSceneX = arg0.getSceneX();
orgSceneY = arg0.getSceneY();
orgTranslateX = ((Rectangle) (arg0.getSource())).getTranslateX();
orgTranslateY = ((Rectangle) (arg0.getSource())).getTranslateY();
}};
EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent arg0) {
offsetX = arg0.getSceneX() - orgSceneX;
offsetY = arg0.getSceneY() - orgSceneY;
newTranslateX = orgTranslateX + offsetX;
newTranslateY = orgTranslateY + offsetY;
((Rectangle)(arg0.getSource())).setTranslateX(newTranslateX);
((Rectangle)(arg0.getSource())).setTranslateY(newTranslateY);
}};
}
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="root" maxHeight="720.0" maxWidth="1280.0" minHeight="720.0" minWidth="1280.0" prefHeight="720.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
<children>
<Button fx:id="createEntity_B" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onAction="#createEntity" text="Create Entity" />
<ScrollPane fx:id="actionWin" layoutX="14.0" layoutY="39.0" prefHeight="672.0" prefWidth="996.0" />
</children>
</AnchorPane>
Main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
public void start(Stage primaryStage) {
try {
AnchorPane root = (AnchorPane)
FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
将这三个类包装在一个名为“应用程序”的程序包中,您很高兴。
答案 0 :(得分:2)
您正在使用translateX
和translateY
来确定Rectangle
的新位置。
当父级确定其大小时,不会考虑诸如translate属性之类的转换。将孩子视为位于(layoutX, layoutY)
。如果要正确调整Pane
的大小,则需要修改这些属性。
createEntity
中的某些其他内容似乎很奇怪:
Pane
,而不是在fxml中创建一次。除非您不进行任何算术运算或比较,否则您还应首选原始类型double
而不是引用类型Double
。
<AnchorPane fx:id="root" maxHeight="720.0" maxWidth="1280.0" minHeight="720.0" minWidth="1280.0" prefHeight="720.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
<children>
<Button fx:id="createEntity_B" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onAction="#createEntity" text="Create Entity" />
<ScrollPane fx:id="actionWin" layoutX="14.0" layoutY="39.0" prefHeight="672.0" prefWidth="996.0">
<content>
<Pane fx:id="container"/>
</content>
</ScrollPane>
</children>
</AnchorPane>
@FXML
private Pane container;
@FXML
public void createEntity() {
class DraggedHandler implements EventHandler<MouseEvent> {
double offsetX;
double offsetY;
@Override
public void handle(MouseEvent event) {
Node source = (Node) event.getSource();
Point2D pt = source.localToParent(event.getX(), event.getY());
source.setLayoutX(pt.getX() + offsetX);
source.setLayoutY(pt.getY() + offsetY);
}
}
Rectangle rect = new Rectangle(i, i, 50, 20);
i += 30;
container.getChildren().add(rect);
rect.addEventHandler(MouseEvent.ANY, event -> {
if (event.getButton() != MouseButton.MIDDLE) {
event.consume();
}
});
DraggedHandler handler = new DraggedHandler();
rect.setOnMouseDragged(handler);
rect.setOnMousePressed(evt -> {
Node source = (Node) evt.getSource();
Point2D pt = source.localToParent(evt.getX(), evt.getY());
handler.offsetX = source.getLayoutX() - pt.getX();
handler.offsetY = source.getLayoutY() - pt.getY();
});
}