所以我正在 javafx 上重新创建计算器的结构。不是为了功能,而是为了外观。我创建了按钮并将它们之间的水平和垂直间距设置为 16。但是,当我有一个文本字段对象来显示数字/结果(同样不是为了功能,而是为了显示)时,按钮会受到文本字段对象大小的影响。因此,我放置文本字段对象的第一行有一个巨大的间隙。
这是我该部分的代码:
// layout manager: organize window contents
GridPane root = new GridPane();
// Scene: contains window content
// parameters: layout manager; width window; height window
Scene mainScene = new Scene(root, 600, 600);
// attach/display Scene on Stage (window)
mainStage.setScene( mainScene );
// create TextField
TextField nameField = new TextField("");
root.add(nameField, 3, 1);
root.setStyle( "-fx-font-size: 24;" );
// to add space between rows and columns
root.setHgap( 16 ); // between horizontal objects
root.setVgap( 16 ); // between vertical objects
// create all buttons
Button button0 = new Button("0");
Button button1 = new Button("1");
Button button2 = new Button("2");
Button button3 = new Button("3");
Button button4 = new Button("4");
...
// parameters: object, column # (X), row # (Y)
// first row
root.add(buttonAllClear, 3, 2);
root.add(buttonClear, 4, 2);
root.add(buttonDelete, 5, 2);
root.add(buttonDivides, 6, 2);
// second row
root.add(button7, 3, 3);
root.add(button8, 4, 3);
root.add(button9, 5, 3);
root.add(buttonTimes, 6, 3);
//
//when I run the code i get:
//[ text field ]
//ac c del /
//7 8 9 *
//4 5 6 -
//1 2 3 +
//0 . =
//but i want:
//[ text field ]
//ac c del /
//7 8 9 *
//4 5 6 -
//1 2 3 +
//0 . =
您可以在 columnSpan
中的节点上设置
GridPane
,使其跨越定义的列数。
或者,您无法将计算器的文本字段放置在网格中,而是使用一个包含文本字段和按钮网格的 VBox。
此示例演示了两种方法,使用
columnSpan
作为等于按钮,并将文本字段放置在 VBox
中的单独行中。
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Arrays;
public class CalcApp extends Application {
@Override
public void start(Stage stage) {
String[][] buttonText = {
{"ac", "c", "del", "/"},
{ "7", "8", "9", "*"},
{ "4", "5", "6", "-"},
{ "1", "2", "3", "+"},
{ "1", "2", "="}
};
GridPane buttonGrid = new GridPane(5, 5);
for (int r = 0; r < buttonText.length; r++) {
String[] rowText = buttonText[r];
Button[] buttonsInRow =
Arrays.stream(rowText)
.map(CalcApp::createButton)
.toArray(Button[]::new);
buttonGrid.addRow(r, buttonsInRow);
}
buttonGrid.getChildren().stream()
.filter(CalcApp::isEqualsButton)
.forEach(equalsButton ->
GridPane.setColumnSpan(
equalsButton,
2
)
);
int nCols = buttonText[0].length;
for (int c = 0; c < nCols; c++) {
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setPercentWidth(100.0 / nCols);
buttonGrid.getColumnConstraints().add(columnConstraints);
}
TextField textField = new TextField();
textField.setStyle("-fx-font-size: 20px;");
textField.setMinHeight(TextField.USE_PREF_SIZE);
VBox layout = new VBox(10, textField, buttonGrid);
layout.setPadding(new Insets(10));
VBox.setVgrow(buttonGrid, Priority.SOMETIMES);
stage.setScene(new Scene(layout));
stage.show();
}
private static boolean isEqualsButton(Node n) {
return n instanceof Button b && "=".equals(b.getText());
}
private static Button createButton(String text) {
Button button = new Button(text);
button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
button.setMinSize(Button.USE_PREF_SIZE, Button.USE_PREF_SIZE);
GridPane.setVgrow(button, Priority.ALWAYS);
GridPane.setHgrow(button, Priority.ALWAYS);
button.setStyle("-fx-font-size: 20px;");
return button;
}
public static void main(String[] args) {
launch();
}
}
TilePane
而不是 GridPane
,但将 TextField
保留在包含按钮的 TilePane
之外。