简体   繁体   English

舞台的 JavaFx USE_COMPUTED_SIZE 不使用 FXML

[英]JavaFx USE_COMPUTED_SIZE for Stage without using FXML

In the JavaFX Scene Builder, I can select a value for the minimum, maximum and preferred width and height of a Control or Container .在 JavaFX Scene Builder 中,我可以为ControlContainer的最小、最大和首选宽度和高度选择一个值。 There are predefined values like USE_COMPUTED_SIZE .有预定义的值,如USE_COMPUTED_SIZE

I came to the conclusion, that I don't like to use FXML for my current project, for several reasons and now I am wondering how to set those values when not using FXML.我得出的结论是,我不喜欢在当前项目中使用 FXML,原因有几个,现在我想知道在不使用 FXML 时如何设置这些值。

How do I do this?我该怎么做呢?

I've tried the following code:我试过以下代码:

initializeControls();
addControls();


setMinHeight(Control.USE_COMPUTED_SIZE);
setMinWidth(Control.USE_COMPUTED_SIZE);

addActionListeners();
addFocusChangeListeners();

However, that results in an Exception when trying to create the Stage:但是,在尝试创建舞台时会导致异常:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: The width and height must be >= 0. Got: width=-1; height=-1
at com.sun.glass.ui.Window.setMinimumSize(Window.java:984)
at com.sun.javafx.tk.quantum.WindowStage.setMinimumSize(WindowStage.java:291)
at javafx.stage.Stage.impl_visibleChanging(Stage.java:1154)
at javafx.stage.Window$9.invalidated(Window.java:743)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:143)
at javafx.stage.Window.setShowing(Window.java:841)
at javafx.stage.Window.show(Window.java:856)
at javafx.stage.Stage.show(Stage.java:255)
at dictionary.MainApp.trainVocablesButtonActionPerformed(MainApp.java:281)
at dictionary.MainApp.lambda$addActionListeners$2(MainApp.java:240)
at dictionary.MainApp$$Lambda$281/81350454.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8216)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$45(GtkApplication.java:126)
at com.sun.glass.ui.gtk.GtkApplication$$Lambda$42/379110473.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

I guess, that I took the USE_COMPUTED_SIZE value from the wrong class or something, but where do I get the correct value from?我想,我从错误的类或其他东西中获取了USE_COMPUTED_SIZE值,但是我从哪里获得正确的值? Or is this whole approach somehow wrong?或者这整个方法有什么错误?

My ultimate goal is to make the stage take as much space as is needed to display all the controls and containers in it, but not more.我的最终目标是让舞台占用尽可能多的空间来显示其中的所有控件和容器,但不能更多。

EDIT#1: Correction: It should take as much space as needed as a Minimum width and height, so that the window is still resizeable but cannot be made so small that controls are not displayed any more.编辑#1:更正:它应该根据需要占用与最小宽度和高度一样多的空间,以便窗口仍然可以调整大小,但不能太小以至于不再显示控件。

EDIT#2: Result of trying to set the minimum width + height on a smaller example app:编辑#2:尝试在较小的示例应用程序上设置最小宽度 + 高度的结果:在此处输入图片说明

Code:代码:

package javafxapplication3;

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.paint.RadialGradientBuilder;
import javafx.scene.paint.Stop;
import javafx.stage.Stage;

public class GridPaneExample extends Application {
private final Paint background = RadialGradientBuilder.create()
            .stops(new Stop(0d, Color.TURQUOISE), new Stop(1, Color.web("3A5998")))
            .centerX(0.5d).centerY(0.5d).build();
    @Override
    public void start(Stage primaryStage) {
        GridPane root = new GridPane();
        root.setPadding(new Insets(5));
        root.setHgap(2);
        root.setVgap(2);
        root.setAlignment(Pos.CENTER);
        final TextField tex = new TextField();
        tex.setPrefWidth(250);
        tex.setPrefHeight(50);
        tex.setPromptText("Press the buttons to Display text here");
        tex.setFocusTraversable(false);
        GridPane.setColumnSpan(tex, 7);
        GridPane.setRowSpan(tex, 2);
        root.add(tex, 0, 0);
        GridPane.setHalignment(tex, HPos.CENTER);
        final Button[][] btn = new Button[5][5];
        char ch = 'A';
        for ( int i = 0; i < btn.length; i++) {
            for ( int j = 0; j < btn.length; j++) {

                btn[i][j] = new Button("" + ch);
                btn[i][j].setPrefSize(50, 50);
                root.add(btn[i][j], j, i+2);
                ch++;
                btn[i][j].setOnMouseClicked((mouseEvent) -> {
                    Button b = (Button) mouseEvent.getSource();
                    tex.appendText(b.getText());
                });
            }
        }

        Scene scene = new Scene(root,background);

        primaryStage.setTitle("Grid Pane Example");


        primaryStage.setScene(scene);

        primaryStage.setWidth(Control.USE_COMPUTED_SIZE);
        primaryStage.setHeight(Control.USE_COMPUTED_SIZE);

        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

One of the comments helped me to find a solution, although it might not be the best solution: After adding all controls to the scene I simply can do the following:其中一条评论帮助我找到了解决方案,尽管它可能不是最佳解决方案:将所有控件添加到场景后,我只需执行以下操作:

setMinWidth(getWidth());
setMinHeight(getHeight());

This works because JavaFX initially sets the stage to a size needed by the controls on its scene.这是有效的,因为 JavaFX 最初将舞台设置为其场景中的控件所需的大小。

Probably late to the party but here is what I found out:可能迟到了,但这是我发现的:

For Textfield there is a static field TextField.USE_COMPUTED_SIZE which has the value -1对于 Textfield,有一个静态字段TextField.USE_COMPUTED_SIZE其值为-1

I assume you can pass -1 to the Stage as well.我假设您也可以将-1传递给舞台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM