JavaFX 容器结构滚动面板
JavaFX Container Structure Scrollpane
我的 GameBoard 需要的 GridPane(它应该包含我的模拟器地形的 "tiles" 数量)不适合 ScrollPane。
改变层次结构并使用彩色容器来确定问题本身对解决问题没有帮助。
包含游戏板的主容器 FXML
<SplitPane dividerPositions="0.5" BorderPane.alignment="CENTER">
<items>
<AnchorPane>
<children>
<TextArea layoutX="1.0" layoutY="-14.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<ScrollPane prefWidth="800" prefHeight="500" hbarPolicy="ALWAYS" vbarPolicy="ALWAYS" >
<GameBoardCC fx:id="gameBoard" >
</ScrollPane>
</items>
</SplitPane>
自定义控件本身:
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.221">
<GridPane fx:id="gameBoard"
style="-fx-background-color: green">
</GridPane>
</fx:root>
基本上是添加这些项目的代码,我很确定我从 Whosebug 获得了大部分代码
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// create node
TerrainNode node = new TerrainNode ("Item " + i + "/" + j, i * 100, j *100, 100, 100);
node.setOpacity (0.5);
// add node to group
gameBoard.getChildren ( ).add (node);
}
}
滑块行为的图片,出于某种原因,这些节点没有添加到网格窗格中,而是添加到网格窗格之外?
Pictures of the Slider Situation
我希望将滑块设置为 "stuck" 50%(虽然这不是我现在主要关心的问题)并且因为我的模拟应该具有可变网格大小的瓷砖和固定瓷砖大小,滚动条应该出现在例如 20x20 网格或将来当客户端变得太小时。
正如@fabian 指定的那样,让 GridPane 做它的事情。 JavaFX 提供的每个布局窗格都有一个特定的功能。我建议您浏览不同类型的布局窗格并了解它们的基本用途。请参考下图中的所有绿色框 :)
当然您选择的布局 (GridPane) 是正确的。但是执行不正确。 GridPane 根据提供的 column/row 索引布置其子项。您不需要处理那里的布局定位。
下面是这个想法的简单示例:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.stream.Stream;
public class GameBoardDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ToggleGroup tg = new ToggleGroup();
RadioButton size1 = new RadioButton("5 X 5");
RadioButton size2 = new RadioButton("5 X 10");
RadioButton size3 = new RadioButton("10 X 10");
RadioButton size4 = new RadioButton("10 X 15");
RadioButton size5 = new RadioButton("15 X 15");
Stream.of(size1, size2, size3, size4, size5).forEach(rb -> {
rb.setToggleGroup(tg);
rb.setId(rb.getText());
});
GridPane options = new GridPane();
options.setHgap(10);
options.addRow(0, size1, size2, size3, size4, size5);
GridPane board = new GridPane();
board.setPrefSize(800, 500);
ScrollPane scrollBoard = new ScrollPane(board);
VBox.setVgrow(scrollBoard, Priority.ALWAYS);
tg.selectedToggleProperty().addListener((obs, old, val) -> {
RadioButton rb = (RadioButton) val;
double rows, columns;
switch (rb.getText()) {
case "5 X 5":
rows = 5;
columns = 5;
break;
case "5 X 10":
rows = 5;
columns = 10;
break;
case "10 X 10":
rows = 10;
columns = 10;
break;
case "10 X 15":
rows = 10;
columns = 15;
break;
default:
rows = 15;
columns = 15;
}
board.getChildren().clear();
for (int rowIndex = 0; rowIndex < rows; rowIndex++) {
for (int columnIndex = 0; columnIndex < columns; columnIndex++) {
Rectangle node = new Rectangle(100, 100);
node.setFill(Color.LIGHTBLUE);
node.setStroke(Color.BLACK);
StackPane terrainNode = new StackPane(node, new Label("Item " + rowIndex + "-" + columnIndex));
board.add(terrainNode, columnIndex, rowIndex);
}
}
});
VBox root = new VBox();
root.setPadding(new Insets(10));
root.setSpacing(15);
root.getChildren().addAll(options, scrollBoard);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("BoardGame");
primaryStage.show();
}
}
我的 GameBoard 需要的 GridPane(它应该包含我的模拟器地形的 "tiles" 数量)不适合 ScrollPane。
改变层次结构并使用彩色容器来确定问题本身对解决问题没有帮助。
包含游戏板的主容器 FXML
<SplitPane dividerPositions="0.5" BorderPane.alignment="CENTER">
<items>
<AnchorPane>
<children>
<TextArea layoutX="1.0" layoutY="-14.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<ScrollPane prefWidth="800" prefHeight="500" hbarPolicy="ALWAYS" vbarPolicy="ALWAYS" >
<GameBoardCC fx:id="gameBoard" >
</ScrollPane>
</items>
</SplitPane>
自定义控件本身:
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.221">
<GridPane fx:id="gameBoard"
style="-fx-background-color: green">
</GridPane>
</fx:root>
基本上是添加这些项目的代码,我很确定我从 Whosebug 获得了大部分代码
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// create node
TerrainNode node = new TerrainNode ("Item " + i + "/" + j, i * 100, j *100, 100, 100);
node.setOpacity (0.5);
// add node to group
gameBoard.getChildren ( ).add (node);
}
}
滑块行为的图片,出于某种原因,这些节点没有添加到网格窗格中,而是添加到网格窗格之外?
Pictures of the Slider Situation
我希望将滑块设置为 "stuck" 50%(虽然这不是我现在主要关心的问题)并且因为我的模拟应该具有可变网格大小的瓷砖和固定瓷砖大小,滚动条应该出现在例如 20x20 网格或将来当客户端变得太小时。
正如@fabian 指定的那样,让 GridPane 做它的事情。 JavaFX 提供的每个布局窗格都有一个特定的功能。我建议您浏览不同类型的布局窗格并了解它们的基本用途。请参考下图中的所有绿色框 :)
当然您选择的布局 (GridPane) 是正确的。但是执行不正确。 GridPane 根据提供的 column/row 索引布置其子项。您不需要处理那里的布局定位。
下面是这个想法的简单示例:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.stream.Stream;
public class GameBoardDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ToggleGroup tg = new ToggleGroup();
RadioButton size1 = new RadioButton("5 X 5");
RadioButton size2 = new RadioButton("5 X 10");
RadioButton size3 = new RadioButton("10 X 10");
RadioButton size4 = new RadioButton("10 X 15");
RadioButton size5 = new RadioButton("15 X 15");
Stream.of(size1, size2, size3, size4, size5).forEach(rb -> {
rb.setToggleGroup(tg);
rb.setId(rb.getText());
});
GridPane options = new GridPane();
options.setHgap(10);
options.addRow(0, size1, size2, size3, size4, size5);
GridPane board = new GridPane();
board.setPrefSize(800, 500);
ScrollPane scrollBoard = new ScrollPane(board);
VBox.setVgrow(scrollBoard, Priority.ALWAYS);
tg.selectedToggleProperty().addListener((obs, old, val) -> {
RadioButton rb = (RadioButton) val;
double rows, columns;
switch (rb.getText()) {
case "5 X 5":
rows = 5;
columns = 5;
break;
case "5 X 10":
rows = 5;
columns = 10;
break;
case "10 X 10":
rows = 10;
columns = 10;
break;
case "10 X 15":
rows = 10;
columns = 15;
break;
default:
rows = 15;
columns = 15;
}
board.getChildren().clear();
for (int rowIndex = 0; rowIndex < rows; rowIndex++) {
for (int columnIndex = 0; columnIndex < columns; columnIndex++) {
Rectangle node = new Rectangle(100, 100);
node.setFill(Color.LIGHTBLUE);
node.setStroke(Color.BLACK);
StackPane terrainNode = new StackPane(node, new Label("Item " + rowIndex + "-" + columnIndex));
board.add(terrainNode, columnIndex, rowIndex);
}
}
});
VBox root = new VBox();
root.setPadding(new Insets(10));
root.setSpacing(15);
root.getChildren().addAll(options, scrollBoard);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("BoardGame");
primaryStage.show();
}
}