ScrollPane不“知道”何时展开

时间:2018-06-21 23:00:11

标签: java javafx scrollpane

我不确定该怎么称呼,但是您一定会理解我的意思... 至少我希望你能。

首先:我的窗格中包含ScrollPane。此窗格还包含两个按钮,可以在其上的ScrollPane中创建矩形。

我可以拖动这些矩形,然后将它们移出视线。到目前为止,除了ScrollPane之外,其他所有东西都可以正常工作。通常,您需要ScrollPane扩展他的Scroll,因此,如果您放开Rectangle,可以滚动到该Rectangle并再次抓住它,但是友好的JavaFX不知道如何扩展Scroll,因此我无法再次进入此Rectangle。 / p>

或者我只是想念一些重要的部分(这很可能会发生)

我的代码中有些话:我认为这不是我现有代码中的问题,而是更多需要解决的问题。我为ScrollPane所做的唯一更改是,将ScrollBarPolicy设置为always,并设置ScrollPane Pannable,但是当我单击Rectangle时会消耗掉它,因此我可以移动它们而不平移ScrollPane。

enter image description here

您在上面看到的是一个全角矩形,而另一半部分不在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);
    }
 }

将这三个类包装在一个名为“应用程序”的程序包中,您很高兴。

1 个答案:

答案 0 :(得分:2)

您正在使用translateXtranslateY来确定Rectangle的新位置。

当父级确定其大小时,不会考虑诸如translate属性之类的转换。将孩子视为位于(layoutX, layoutY)。如果要正确调整Pane的大小,则需要修改这些属性。

createEntity中的某些其他内容似乎很奇怪:

  • 您重新创建Pane,而不是在fxml中创建一次。
  • 您加载了一个似乎从未使用过的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();
    });
}