我的背景是黑色的
Rectangle
. [...] 另外,我想舞台的大小要固定到
矩形
简单地为背景分配一个背景会简单得多
StackPane
. 这将允许您调整大小
MenuView
并保持背景的大小与背景的大小相同
菜单视图
防止窗口的大小调整应该为
Stage
使用
setResizable
.
您正在使用“不健康”数量的转换属性(我指的是
translateX
和
translateY
以下结构将更适合预期结果:
MenuView (root)
|- VBox (place menu items below title)
|- HBox (title container)
|- ...
|- MenuItem
|- MenuItem
|- MenuItem
我还想改变其他一些事情:
@Override
public void start(Stage stage) {
MenuView menuView = new MenuView(600, 600);
Scene scene = new Scene(menuView);
stage.setTitle("Poneymon");
stage.setScene(scene);
menuView.requestFocus();
stage.setResizable(false); // prevent resizing of stage
stage.show();
}
public class MenuView extends StackPane {
static final Font FONT = Font.font("", FontWeight.BOLD, 50);
int currentItem = 0;
public MenuView(int w, int h) {
setPrefSize(w, h);
createContent();
setOnKeyPressedEvent();
}
private List<MenuItem> menuItems;
private void createContent() {
MenuItem exitItem = new MenuItem("Exit");
exitItem.setOnActivate(() -> Platform.exit());
menuItems = Arrays.asList(
new MenuItem("Start a game"),
new MenuItem("Parameters"),
exitItem);
VBox container = new VBox(10, createTitle("Poneymon"));
container.getChildren().addAll(menuItems);
container.setMaxSize(USE_PREF_SIZE, USE_PREF_SIZE);
getMenuItem(0).setActive(true);
setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)));
getChildren().add(container);
}
private Node createTitle(String title) {
final double movement = 25;
HBox letters = new HBox();
letters.setAlignment(Pos.CENTER);
// add space on top equla to the upwards movement of the letters
letters.setPadding(new Insets(movement, 0, 0, 0));
for (int i = 0; i < title.length(); i++) {
Text letter = new Text(title.charAt(i) + "");
letter.setFont(FONT);
letter.setFill(Color.WHITE);
letters.getChildren().add(letter);
TranslateTransition tt = new TranslateTransition(Duration.seconds(2), letter);
tt.setDelay(Duration.millis(i * 50));
tt.setToY(-movement);
tt.setAutoReverse(true);
tt.setCycleCount(TranslateTransition.INDEFINITE);
tt.play();
}
return letters;
}
private MenuItem getMenuItem(int index) {
return menuItems.get(index);
}
private void setOnKeyPressedEvent() {
this.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(KeyEvent e) {
if (e.getCode() == KeyCode.UP) {
if (currentItem > 0) {
getMenuItem(currentItem).setActive(false);
getMenuItem(--currentItem).setActive(true);
}
}
if (e.getCode() == KeyCode.DOWN) {
if (currentItem < menuItems.size() - 1) {
getMenuItem(currentItem).setActive(false);
getMenuItem(++currentItem).setActive(true);
}
}
if (e.getCode() == KeyCode.ENTER) {
getMenuItem(currentItem).activate();
}
}
});
}
}
public class MenuItem extends HBox {
static final Font FONT = Font.font("", FontWeight.BOLD, 30);
private Group c1 = createTriCircle();
private Group c2 = createTriCircle();
private Text text;
private Runnable script;
private static Circle createCircle(double centerX, double centerY) {
final double innerRadius = 2;
final double outerRadius = 5;
Circle circle = new Circle(centerX, centerY, (innerRadius + outerRadius) / 2, null);
circle.setStroke(Color.WHITE);
circle.setStrokeWidth(outerRadius - innerRadius);
return circle;
}
private static Group createTriCircle() {
return new Group(
createCircle(0, 0),
createCircle(5, 0),
createCircle(2.5, -5));
}
public MenuItem(String name) {
super(15);
setAlignment(Pos.CENTER);
text = new Text(name);
text.setFont(FONT);
setEffect(new GaussianBlur(2));
getChildren().addAll(c1, text, c2);
setActive(false);
setOnActivate(() -> System.out.println(name + " activated"));
}
public void setActive(boolean b) {
c1.setVisible(b);
c2.setVisible(b);
text.setFill(b ? Color.WHITE : Color.GREY);
}
public void setOnActivate(Runnable r) {
script = r;
}
public void activate() {
if (script != null) {
script.run();
}
}
}
要调整标题和菜单项之间的距离,可以使用
VBox.setMargin
.