Если вы хотите, чтобы узлы в графе не перемещались при перемещении разделителей, я думаю, что наиболее логичный подход - сделать их не частью SplitPane
. Используйте StackPane
с фактическим графиком в самом низком z-порядке и SplitPane
в более высоком z-порядке; стилизуйте панели, содержащиеся в SplitPane
, так, чтобы центральная панель была прозрачной, а левая и правая панели - непрозрачными, и сделайте сам SplitPane
прозрачным фоном.
Этот подход основан на стандартных механизмах компоновки, и позволяет избежать необходимости использовать слушателей для изменения макета после его обновления системой.
Вот макет этого подхода:
import java.io.IOException;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application {
@Override
public void start(Stage stage) throws IOException {
BorderPane root = new BorderPane();
// menu bar in top, status in bottom...
StackPane graphStack = new StackPane();
Pane graphPane = new Pane();
populateGraphPane(graphPane);
VBox controls = new VBox(5,
new Label("Controls"),
new Button("A Button"),
new TextField()
);
AnchorPane graphOverlay = new AnchorPane();
Label graphLabel = new Label("Graph");
AnchorPane.setTopAnchor(graphLabel, 5.0);
AnchorPane.setLeftAnchor(graphLabel, 5.0);
graphOverlay.getChildren().add(graphLabel);
VBox details = new VBox(5, new Label("Details"));
SplitPane split = new SplitPane(controls, graphOverlay, details);
graphStack.getChildren().addAll(graphPane, split);
split.setDividerPositions(0.33, 0.67);
// Styles: IRL do this in an external CSS style sheet
// Make the background white, but make the overlay transparent so we see the graph below it:
graphPane.setStyle("-fx-background-color: white ;");
controls.setStyle("-fx-background-color: white ; -fx-color: red ; -fx-focus-color: #FF7F50 ; -fx-faint-focus-color: #FF7F5022 ; -fx-padding: 5 ; ");
details.setStyle("-fx-background-color: white ; -fx-padding: 5 ;");
graphOverlay.setStyle("-fx-background-color: transparent ;");
split.setStyle("-fx-background-color: transparent ;");
root.setStyle("-fx-text-background-color: red ;");
root.setCenter(graphStack);
Scene scene = new Scene(root, 800, 600);
stage.setScene(scene);
stage.show();
}
private void populateGraphPane(Pane graph) {
Circle top = new Circle(400, 200, 20, Color.WHITE);
Circle left = new Circle(300, 373, 20, Color.WHITE);
Circle right = new Circle(500, 373, 20, Color.WHITE);
Line leftLine = new Line(390, 217, 310, 356);
Line rightLine = new Line(410, 217, 490, 356);
Line bottomLine = new Line(320, 373, 480, 373);
Stream.of(top, left, right).forEach(c -> {
c.setStroke(Color.RED);
c.setStrokeWidth(3);
});
Stream.of(leftLine, rightLine, bottomLine).forEach(l -> {
l.setStroke(Color.RED);
l.setStrokeWidth(3);
});
Group group = new Group();
group.getChildren().addAll(top, left, right, leftLine, rightLine, bottomLine);
graph.getChildren().add(group);
}
public static void main(String[] args) {
launch();
}
}
и несколько снимков экрана:
Если вы хотите избежать скрывая части графика, это относительно легко сделать, установив минимальную / максимальную ширину панелей на графике (что ограничит перемещение разделителей).