gpt4 book ai didi

java - 最大化窗口和布局 channel

转载 作者:太空宇宙 更新时间:2023-11-04 10:56:53 26 4
gpt4 key购买 nike

因此,这里的目标是为 ScrollPane 使用自定义 ScrollBar,而在最大化/最小化窗口时不会遇到布局问题。

考虑示例程序:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Layout extends Application
{
@Override
public void start(Stage stage)
{
BorderPane main = new BorderPane();
main.setPrefSize(800, 600);

BorderPane center = new BorderPane(); // begin center
center.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
main.setCenter(center); // end center

BorderPane left = new BorderPane(); // begin left

ScrollPane pane = new ScrollPane();
pane.setFitToWidth(true);

Pane p1 = new Pane(); // child 1
p1.setPrefSize(200, 100);
p1.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY)));
this.makeResizable(p1);
Pane p2 = new Pane(); // child 2
p2.setPrefSize(200, 100);
p2.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
this.makeResizable(p2);
VBox content = new VBox(10, p1, p2); // content in scroll pane
pane.setContent(content);

// replace normal bars
pane.setHbarPolicy(ScrollBarPolicy.NEVER);
pane.setVbarPolicy(ScrollBarPolicy.NEVER);

// with custom
ScrollBar sb = new ScrollBar();
sb.setOrientation(Orientation.VERTICAL);
sb.minProperty().bind(pane.vminProperty());
sb.maxProperty().bind(pane.vmaxProperty());
sb.visibleAmountProperty().bind(pane.heightProperty().divide(content.heightProperty()));
sb.managedProperty().bind(sb.visibleAmountProperty().lessThan(1.0)); // bar should be managed when it is needed (content too long)
sb.visibleProperty().bind(sb.managedProperty()); // and also visible only when managed
sb.valueProperty().bindBidirectional(pane.vvalueProperty());

left.setCenter(pane); // content
left.setRight(sb); // scroll bar
main.setLeft(left); //end left

Scene scene = new Scene(main);
stage.setScene(scene);
stage.show();
}

// Simple for testing
double prevY;
boolean dragging;

// Makes node resizable on drag.
private void makeResizable(Region region)
{
region.addEventFilter(MouseEvent.MOUSE_PRESSED, e ->
{
this.dragging = true;
region.setPrefHeight(region.getHeight());
this.prevY = e.getSceneY();
});
region.addEventFilter(MouseEvent.MOUSE_DRAGGED, e ->
{
if (!this.dragging) return;
region.setPrefHeight(region.getPrefHeight() + (e.getSceneY() - this.prevY));
this.prevY = e.getSceneY();
});
region.addEventFilter(MouseEvent.MOUSE_RELEASED, e -> this.dragging = false);
}

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

它将生成左侧带有 ScrollPane 的 GUI,并在内容(2 个节点 p1p2)超出边界时出现自定义的 ScrollBar。为了方便测试 - p1p2 在用鼠标拖动时都会调整大小(尝试一下)。虽然 ScrollBar 按预期显示并工作,但如果我们开始最大化和最小化窗口,布局就会存在缺陷。

例如:

  1. 启动程序
  2. 调整内容大小,以便出现 ScrollBar,但不要太大多(使它最大化,以便当你最大化它时,它会在范围内)
  3. 最大化窗口 - 您会注意到栏可能已经消失,但出现了“空白区域”。
  4. 现在,如果您以某种方式进行刷新(例如再次调整内容大小),栏将会由于布局传递更新而消失。

其他错误:

  1. 启动程序并最大化。
  2. 调整内容大小,使其仍包含在最大化窗口中,但足够大,以至于当您最小化时,它会超出边界。
  3. 最小化
  4. 注意 ScrollBar 是如何错位的。

如果您尝试其他东西,几乎不会出现其他错误,但所有错误都源于当您最大化/最小化这种情况时发生的事实(使用第一个示例):

  1. ScrollBar 是托管且可见的(考虑到内容超出)。
  2. 最大化
  3. 窗口大小已调整,布局已计算(使用旧值 - Managed=true &&visible=true)
  4. 布局发生,一切就位,所有属性都会收到更新,包括 sb.visibleAmountProperty() 使 ScrollBar 设置为受管理且可见为 false(因为它们已绑定(bind),请参阅代码)。
  5. ScrollBar 变得不可见且不受管理,但布局已经发生,并且不会重新运行。

如何使其与窗口最大化一起使用?我还能如何绑定(bind) ScrollBar 使其在最大化时不会中断?请注意,我们谈论的是最大化,而不是调整大小(这是有效的)。

最佳答案

我找到了一种解决方法,但这似乎并不是绝对最好的方法,如果有更合适的方法 - 请分享。

sb.managedProperty().addListener(e -> Platform.runLater(() -> content.requestLayout()));

由于这将“稍后”运行(并且也因为在主线程上第一个应该完成先前的布局),这将导致重新布局发生。

为什么不是最好的?好吧,对于一个人来说,当不是真正需要(而不是最大化)时也会调用它,从而导致双重布局(并且我们无法通过某些 if 语句真正解决这个问题)。

关于java - 最大化窗口和布局 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47274265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com