在 Javafx

如何解决在 Javafx

我有两个滚动窗格,其中包含要对齐的网格。它们的单元格宽度都应该是 40,所以我不确定为什么它们会变得不对齐。尽管它们一开始看起来对齐,但它们逐渐变得不对齐。

Here,they are aligned.

But as you can see,it gradually becomes unaligned.

顶部网格(带有数字)和底部网格都包含在单独的滚动窗格中。如果我不这样做而是将两个网格放在一个 VBox 中并将其放入一个滚动窗格中,那么一切都会对齐。但是,我需要它们在单独的滚动窗格中,以便我可以向下滚动下部网格,同时保持数字到位,并且仍然使数字与网格水平滚动(我双向绑定了两个滚动窗格的 hscrollvalues)。

private void layerdisplay() {
    BeatNumbers bn = new BeatNumbers(this.finalBeat,this.overlay,this::togglePlay,this.features::setBeat);

    VBox layerGrid = new VBox();

    for (String layerName : this.layers.keySet()) {
      LayerGrid lg = new LayerGrid(this.layers.get(layerName),layerName,this.finalBeat,this.features::addUnit,this.features::deleteUnit,this.features::playUnit,this.features::stopAllUnits,this.features::refresh);

      layerGrid.getChildren().add(lg);
    }

    StackPane pane = new StackPane();
    pane.getChildren().add(layerGrid);
    pane.getChildren().add(this.overlay);

    this.gridScrollPane.setContent(pane);
    this.numberPane.setContent(bn);

    VBox Box = new VBox();
    Box.getChildren().addAll(this.numberPane,this.gridScrollPane);

    this.setCenter(Box);
}

你知道如何让 BeatNumbers 和 layerGrid 保持一致吗?当我向下滚动时,BeatNumbers 必须固定在屏幕顶部,但当我水平滚动时必须与网格一起水平移动。

谢谢!

编辑:这是一个最低限度的可重现示例:

这是运行示例的代码

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MinimumReproducibleExample extends Application {

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


  @Override
  public void start(Stage stage) {
    VBox notAlignedButScrolls = new NotAlignedButScrolls();
    Scene scene = new Scene(notAlignedButScrolls,400,300);
    
    stage.setTitle("Not Aligned But Scrolls");
    stage.setScene(scene);
    stage.show();

    VBox alignedButDoesNotScroll = new AlignedButDoesNotScroll();
    Scene scene2 = new Scene(alignedButDoesNotScroll,300);
    Stage stage2 = new Stage();
    stage2.setTitle("Aligned But Does Not Scroll");
    stage2.setScene(scene2);
    stage2.show();
  }
}

这是 NotAlignedButScrolls 的类,它创建了一个示例,其中两个网格按我希望的方式滚动,但数字逐渐与网格失去对齐。

import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

public class NotAlignedButScrolls extends VBox {

  public NotAlignedButScrolls() {
    super();

    // Setting up the scroll panes

    // This is the top scroll pane
    ScrollPane numberPane = new ScrollPane();
    numberPane.addEventFilter(ScrollEvent.SCROLL,event -> {
      if (event.getDeltaY() != 0) {
        event.consume();
      }
    });
    numberPane.setHbarPolicy(ScrollBarPolicy.NEVER);
    numberPane.setVbarPolicy(ScrollBarPolicy.NEVER);
    numberPane.setMaxHeight(15);
    numberPane.setMinHeight(15);

    // This is the lower scroll pane
    ScrollPane gridScrollPane = new ScrollPane();
    gridScrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
    gridScrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);

    // Bind their horizontal scroll values together
    gridScrollPane.hvalueproperty().bindBidirectional(numberPane.hvalueproperty());

    // Set up the content for each scroll pane
    HBox beatNumbers = this.beatNumbers();

    VBox layerGrid = new VBox();
    for (int i = 0; i < 28; i++) {
      layerGrid.getChildren().add(this.gridPane());
    }

    gridScrollPane.setContent(layerGrid);
    numberPane.setContent(beatNumbers);

    gridScrollPane.prefheightproperty().bind(this.heightproperty());

    // Put everything together

    VBox Box = new VBox();
    Box.getChildren().addAll(numberPane,gridScrollPane);

    this.getChildren().add(Box);
  }

  private HBox beatNumbers() {
    HBox beatNumbers = new HBox();

    HBox.setHgrow(beatNumbers,Priority.ALWAYS);

    for (int i = 0; i < 150; i++) {
      VBox unit = new VBox();
      unit.setMinWidth(40);
      unit.setStyle("-fx-border-width: 0 1 0 0;-fx-border-color: green;");

      Label measureNumber = new Label(String.valueOf(i + 1));
      measureNumber.setStyle("-fx-text-fill: black");

      unit.getChildren().add(measureNumber);
      beatNumbers.getChildren().add(unit);
    }

    return beatNumbers;
  }

  private HBox gridPane() {
    HBox gridPane = new HBox();
    gridPane.setMinHeight(40);
    HBox.setHgrow(gridPane,Priority.ALWAYS);
    gridPane.setStyle("-fx-background-color: gray;-fx-border-style: solid;"
        + "-fx-border-color: black;-fx-border-width: 0 0 1 0");

    for (int i = 0; i < 150; i++) {
      VBox cell = new VBox();
      cell.setMinWidth(40);
      setCellStyle(cell);

      gridPane.getChildren().add(cell);
    }
    return gridPane;
  }

  private void setCellStyle(VBox cell) {
    String style = "-fx-border-style: solid;-fx-border-color: black;-fx-border-width: 0 1 0 0;";

    cell.setStyle("-fx-background-color: null;" + style);
    cell.setonMouseEntered(e -> cell.setStyle("-fx-background-color: lightgray;" + style));
    cell.setonMouseExited(e -> cell.setStyle("-fx-background-color: null;" + style));
  }
}

最后,这里是 AlignedButDoesNotScroll 的类,它创建了一个示例,其中两个网格正确对齐,但是当您向下滚动时,顶部网格未固定在屏幕顶部。

import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

public class AlignedButDoesNotScroll extends VBox {

  public AlignedButDoesNotScroll() {
    super();

    // Setting up the only scroll pane

    ScrollPane gridScrollPane = new ScrollPane();
    gridScrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
    gridScrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);

    // Set up the content for the scroll pane
    HBox beatNumbers = this.beatNumbers();

    VBox layerGrid = new VBox();
    for (int i = 0; i < 28; i++) {
      layerGrid.getChildren().add(this.gridPane());
    }

    // Put everything together

    VBox Box = new VBox();
    Box.getChildren().addAll(beatNumbers,layerGrid);

    gridScrollPane.setContent(Box);
    gridScrollPane.prefheightproperty().bind(this.heightproperty());

    this.getChildren().add(gridScrollPane);
  }

  private HBox beatNumbers() {
    HBox beatNumbers = new HBox();

    HBox.setHgrow(beatNumbers,Priority.ALWAYS);
    gridPane.setStyle("-fx-background-color: gray;-fx-border-style: solid;"
        + "-fx-border-color: black;-fx-border-width: 0 0 1 0");

    for (int i = 0; i < 150; i++) {
      VBox cell = new VBox();
      cell.setMinWidth(40);
      setCellStyle(cell);

      gridPane.getChildren().add(cell);
    }
    return gridPane;
  }

  private void setCellStyle(VBox cell) {
    String style = "-fx-border-style: solid;-fx-border-color: black;-fx-border-width: 0 1 0 0;";

    cell.setStyle("-fx-background-color: null;" + style);
    cell.setonMouseEntered(e -> cell.setStyle("-fx-background-color: lightgray;" + style));
    cell.setonMouseExited(e -> cell.setStyle("-fx-background-color: null;" + style));
  }
}

NotAlignedButScrolls

AlignedButDoesNotScroll

我希望这有助于解释问题。再次感谢!

解决方法

问题是两个ScrollPanes的视口大小不一样。较低的一个较小以容纳滚动条。

这样的事情可以帮助...

gridScrollPane.viewportBoundsProperty().addListener((obs,oldVal,newVal) -> {
    double w = newVal.getWidth() + 2; // this 2 accounts for 1 pixel borders
    numberPane.setPrefWidth(w);
    numberPane.setMaxWidth(w);
});

另一种选择是将两个 ScrollPanes 的 VBar 策略强制为 ALWAYS。不过那看起来不太好。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?