Risolto il problema. Ho dovuto copiare tutto il mio progetto e quindi rimuovere parti del codice fino a quando il problema non è scomparso.
In ogni caso. Fondamentalmente avevo tre componenti nella mia applicazione. Un componente di navigazione, un componente di tabella e una barra di stato compontent. Si presentava così:

Il problema che avevo era che la larghezza della barra di stato e la larghezza e l'altezza del componente tabella è stata aumentata ogni volta che ho preso una fotografia istantanea di una riga della tabella.
Apparentemente, ciò era dovuto al riempimento del componente di stato della barra. Aveva una spaziatura destra e sinistra di 5 pixel e, una volta rimossa la padding, il problema scomparve.
I 10 pixel aggiunti in larghezza hanno reso lo BorderPane
che conteneva tutto questo espandibile con la stessa quantità di pixel, e poiché la larghezza della tabella era legata alla larghezza BorderPane
, aumentava dello stesso importo. Ciò che ancora non capisco, è il motivo per cui lo BorderPane
BorderPane
non si adatta alla nuova larghezza.
Il componente è stato riempito correttamente prima dell'invocazione di Scene.doCSSLayoutSyncForSnapshot(Node node)
, quindi non capisco perché viene aggiunta la larghezza extra di dieci pixel.
In ogni caso: la rimozione del padding dal componente della barra di stato e il riempimento dei componenti all'interno della barra di stato ha risolto il problema. Se qualcuno ha una buona spiegazione per questo, sono tutto orecchie.
Ecco un MCVE in cui è possibile riprodurre il problema trascinando una riga nella tabella:
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);
}
}
}
così si può provare a impostare vincoli sui nodi prima del evocando quella funzione e annullarle, voglio dire, ' setMinSize (Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE); 'e' setMaxSize (Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE); 'potrebbe aiutare dal modo in cui hai descritto il tuo problema, :) – Elltz
Grazie per non aver pubblicato tutte le 2000 righe di codice. Ma se riesci a scrivere un breve esempio compilabile per riprodurre il problema che sarebbe utile. Altrimenti un link a tutto il tuo codice se non riesci a riprodurre un piccolo campione? – Amber
Suggerisco di utilizzare [Vista panoramica] (http://fxexperience.com/scenic-view/) che consente di visualizzare tutte le proprietà su una vista durante il runtime della GUI dell'utente. Questo ti permetterà almeno di verificare se il problema che descrivi è davvero il problema. Puoi anche pubblicare alcune schermate usando Vista panoramica. Questo strumento consente inoltre di visualizzare tutti gli eventi che si verificano nella GUI dell'utente. Lo uso molto :-) – Westranger