Jon*_*cka 9 java size javafx snapshot
我有Scene它设置为Scene我primaryStage说的-除其他节点-包含VBox了TableView和一些按钮.当我使用表中的行拍摄快照时TableRow.snapshot(null, null),Scene会更改其大小.宽度改变大约10个像素,而高度改变大约40个 - 有时大于600(!) - 像素.
发生这种情况是因为Node.snapshot(null, null)调用 Scene.doCSSLayoutSyncForSnapshot(Node node)似乎获得了大小中所有节点的首选大小,并使用它重新计算大小.这会以某种方式返回错误的值,因为我的节点只指定了首选大小,并且在调用此方法之前看起来很棒.有什么方法可以防止这种情况吗?
大小更改是一个问题,但主要阶段不会更改Scene其包含的大小也是一个问题.
我试图创建一个MCVE来重现这个问题,但经过几天尝试这样做之后,我仍然无法重现这个问题.原始程序包含大约2000行代码,我不想在这里发布.
为什么Scene.doCSSLayoutSyncForSnapshot(Node node)在首先正确布局时会影响我的布局?在调用此方法之前,我可以以某种方式确保布局已正确同步,以确保它不会更改任何内容吗?
解决了问题。必须复制我的整个项目,然后删除部分代码,直到问题消失。
反正。我的应用程序基本上包含三个组件。导航组件、表格组件和状态栏组件。它看起来像这样:
我遇到的问题是,每当我拍摄表格中的一行快照时,状态栏的宽度以及表格组件的宽度和高度都会增加。
显然,这是由于状态栏组件的填充造成的。它的左右填充均为 5 像素,一旦我删除填充,问题就消失了。
添加的 10 个像素宽度使得BorderPane包含所有这些的内容以相同数量的像素扩展,并且由于表格宽度与宽度绑定BorderPane,因此它增加了相同的数量。但我仍然不明白的是,为什么Stage包含 的BorderPane不调整到新的宽度。
该组件在调用之前已正确填充Scene.doCSSLayoutSyncForSnapshot(Node node),所以我不明白为什么要添加十个像素的额外宽度。
无论如何:从状态栏组件中删除填充并在状态栏内填充组件解决了问题。如果有人对此有一个很好的解释,我会洗耳恭听。
这是一个 MCVE,您可以通过在表中拖动一行来重现该问题:
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MCVE extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private VBox detailsView;
private StatusBar statusBar;
public void start(Stage primaryStage) throws SQLException {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("MCVE");
initRootLayout();
showStatusBar();
showDetailsView();
detailsView.prefWidthProperty().bind(rootLayout.widthProperty());
detailsView.prefHeightProperty().bind(rootLayout.heightProperty());
}
@Override
public void init() throws Exception {
super.init();
}
public void initRootLayout() {
rootLayout = new BorderPane();
primaryStage.setWidth(1000);
primaryStage.setHeight(600);
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
public void showStatusBar() {
statusBar = new StatusBar();
rootLayout.setBottom(statusBar);
}
public void showDetailsView() {
detailsView = new VBox();
rootLayout.setCenter(detailsView);
setDetailsView(new Table(this));
detailsView.prefHeightProperty().bind(primaryStage.heightProperty());
detailsView.setMaxHeight(Region.USE_PREF_SIZE);
}
public static void main(String[] args) {
launch(args);
}
public VBox getDetailsView() {
return detailsView;
}
public void setDetailsView(Node content) {
detailsView.getChildren().add(0, content);
}
public StatusBar getStatusBar() {
return statusBar;
}
class StatusBar extends HBox {
public StatusBar() {
setPadding(new Insets(0, 5, 0, 5));
HBox leftBox = new HBox(10);
getChildren().addAll(leftBox);
/**
* CONTROL SIZES
*/
setPrefHeight(28);
setMinHeight(28);
setMaxHeight(28);
// Leftbox takes all the space not occupied by the helpbox.
leftBox.prefWidthProperty().bind(widthProperty());
setStyle("-fx-border-color: black;");
}
}
class Table extends TableView<ObservableList<String>> {
private ObservableList<ObservableList<String>> data;
public Table(MCVE app) {
prefWidthProperty().bind(app.getDetailsView().widthProperty());
prefHeightProperty()
.bind(app.getDetailsView().heightProperty());
widthProperty().addListener((obs, oldValue, newValue) -> {
System.out.println("Table width: " + newValue);
});
setRowFactory(r -> {
TableRow<ObservableList<String>> row = new TableRow<ObservableList<String>>();
row.setOnDragDetected(e -> {
Dragboard db = row.startDragAndDrop(TransferMode.ANY);
db.setDragView(row.snapshot(null, null));
ArrayList<File> files = new ArrayList<File>();
// We create a clipboard and put all of the files that
// was selected into the clipboard.
ClipboardContent filesToCopyClipboard = new ClipboardContent();
filesToCopyClipboard.putFiles(files);
db.setContent(filesToCopyClipboard);
});
row.setOnDragDone(e -> {
e.consume();
});
return row;
});
ObservableList<String> columnNames = FXCollections.observableArrayList("Col1", "col2", "Col3", "Col4");
data = FXCollections.observableArrayList();
for (int i = 0; i < columnNames.size(); i++) {
final int colIndex = i;
TableColumn<ObservableList<String>, String> column = new TableColumn<ObservableList<String>, String>(
columnNames.get(i));
column.setCellValueFactory((param) -> new SimpleStringProperty(param.getValue().get(colIndex).toString()));
getColumns().add(column);
}
// Adds all of the data from the rows the data list.
for (int i = 0; i < 100; i++) {
// Each column from the row is a String in the list.
ObservableList<String> row = FXCollections.observableArrayList();
row.add("Column 1");
row.add("Column 2");
row.add("Column 3");
row.add("Column 4");
// Adds the row to data.
data.add(row);
}
// Adds all of the rows in data to the table.
setItems(data);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
534 次 |
| 最近记录: |