简体   繁体   English

全屏缩放应用 JavaFX 8

[英]Full screen scaling application JavaFX 8

this is going to be a second part to my first post about full screening.这将是我关于全面筛选的第一篇文章的第二部分。

Scaling start screen with full screen in JavaFX 在 JavaFX 中全屏缩放开始屏幕

With a little bit of tweaking the start screen scales when full screen but now, I can't seem to get the game itself to scale correctly.在全屏时稍微调整开始屏幕比例但现在,我似乎无法让游戏本身正确缩放。

package application.console;

import java.util.List;

import application.areas.startingArea.SA;
import application.areas.vanguardForest.VFCmds;
import application.areas.vanguardForest.VFNavi;
import application.areas.vanguardForest.VFPkups;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

public class Console extends Region {

    public static double WIDTH = 990;
    public static double HEIGHT = 525;
    
    private final Font cinzel;
    
    private final BorderPane root;
    
    private final VBox console;
    private final ScrollPane scroll;
    
    private final HBox inputBar;
    private final TextField input;
    private final Text carrot;
    
    public Console() {
        this.root = new BorderPane();
        root.setStyle("-fx-background-color: #232323;");
        
        this.cinzel = Font.loadFont("file:fonts/static/Cinzel-Medium.ttf", 16);
        
        this.console = new VBox();
        console.setPrefWidth(WIDTH);
        console.setPrefHeight(HEIGHT);
        
        this.scroll = new ScrollPane();
        scroll.setContent(console);
        scroll.setStyle("-fx-background: #232323;"
                + "-fx-background-color: transparent;"
                + "-fx-border-color: #232323;"
                + "-fx-focus-color: #232323;");
        scroll.setHbarPolicy(ScrollBarPolicy.NEVER);
        scroll.setVbarPolicy(ScrollBarPolicy.NEVER);
        scroll.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, null, null)));
        
        console.setStyle("-fx-background-color: #232323;"
                + "-fx-focus-color: #232323;");
        
        console.heightProperty().addListener(new ChangeListener<Object>() {
            @Override
            public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
                
                scroll.setVvalue((Double)newValue);
            }
            
        });
        
        this.inputBar = new HBox();
        inputBar.setPrefSize(WIDTH, 16);
        
        this.input = new TextField();
        input.setStyle("-fx-background-color: transparent;"
                + "-fx-text-fill: #FFFFFF;"
                + "-fx-highlight-fill: #FFFFFF;"
                + "-fx-highlight-text-fill: #232323;"
                );
        input.setFont(cinzel);
        input.setPrefWidth(WIDTH);
        
        this.carrot = new Text(" > ");
        carrot.setFont(Font.loadFont("file:fonts/static/Cinzel-Medium.ttf", 24));
        carrot.setFill(Color.WHITE);
        
        
        inputBar.getChildren().addAll(carrot, input);
        
        root.setMinSize(WIDTH, (HEIGHT - input.getHeight()));
        
        input.setOnAction(e -> {
            
            String s = (input.getText()).stripTrailing();
            
            
            if ((SA.isBuried || SA.inVF) && SS.gameStart) {
                Cmds.commands(s);   //has general functions
                VFCmds.commands(s); //doesn't have function until specific command 
                VFPkups.pickUp(s); //commands that allows pickups to be made within the game
                VFNavi.commands(s); //commands navigation for selected area
            } else {
                Cmds.commands(s);
            }

            input.clear();
        });
        
        root.getChildren().addAll(console, scroll, inputBar);
        root.setBottom(inputBar);
        
    }
    
    @Override 
    protected void layoutChildren() {
        double xScale = getWidth() / root.getWidth();
        double yScale = getHeight() / root.getHeight();
        double scale = Math.min(xScale, yScale);
        
        for (BorderPane bp : List.of(root)) {
            scaleAndCenter(bp, scale); 
        }
        
        for (VBox vb : List.of(console)) {
            scaleAndCenter(vb, scale);
        }
        
        for (HBox hb : List.of(inputBar)) {
            scaleAndCenter(hb, scale);
        }
        
        for (ScrollPane sp : List.of(scroll)) {
            scaleAndCenter(sp, scale); 
        }
        
        for (TextField tf : List.of(input)) {
            scaleAndCenter(tf, scale);
        }
        
        for (Text text : List.of(carrot)) {
            scaleAndCenter(text, scale); 
        }
    }

    private void scaleAndCenter(BorderPane root, double scale) {
        double w = scale * root.getWidth();
        double h = scale * root.getHeight();
        

        root.setPrefSize(w, h);
        root.relocate((getWidth() - w) / 2, (getHeight() - h) / 2);
    }
    
    private void scaleAndCenter(VBox vb, double scale) {
        double w = scale * vb.getWidth();
        double h = scale * vb.getHeight();
        
        vb.setPrefSize(w, h);
        vb.relocate((getWidth() - w) / 2, (getHeight() - h) / 2);
    }
    
    private void scaleAndCenter(HBox hb, double scale) {
        double w = scale * hb.getWidth();
        double h = scale * hb.getHeight();
        
        hb.setPrefSize(w, h);
        hb.relocate((getWidth() - w) / 2, (getHeight() - h) / 2);
    }
    
    private void scaleAndCenter(TextField input, double scale) {
        double w = scale * input.getWidth();
        double h = scale * input.getHeight();
        
        input.setPrefSize(w, 16);
        input.relocate((getWidth() - w) / 2, (getHeight() - h) / 2);

    }
    
    private void scaleAndCenter(ScrollPane scroll, double scale) {
        double w = scale * scroll.getWidth();
        double h = scale * scroll.getHeight();
        
        scroll.setPrefSize(w, h);
        scroll.relocate((getWidth() - w) / 2, (getHeight() - h) / 2);
    }
    
    private void scaleAndCenter(Text text, double scale) {
        double w = scale * text.getLayoutBounds().getWidth();
        double h = scale * text.getLayoutBounds().getHeight();
        double size = scale * text.getFont().getSize();
        
        text.setFont(Font.font(
                text.getFont().getFamily(),
                size));
        text.relocate((getWidth() - w) / 2, (getHeight() - h) / 2);
    }
}

Doing it this way, I get an error saying这样做,我收到一条错误消息

Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics@18.0.1/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:901)
    at javafx.graphics@18.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalArgumentException: Children: duplicate children added: parent = BorderPane@56dca201

If I were to remove the BorderPane from the class, it'll just show up a white window.如果我要从 class 中删除BorderPane ,它只会显示一个白色的 window。

package application.console;

import javafx.scene.Parent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;

public class game {

    public static Parent runGame() {
        
        Console c = new Console();
        AnchorPane anchor = new AnchorPane(c); 
        
        AnchorPane.setTopAnchor(c, 0.0);
        AnchorPane.setRightAnchor(c, 0.0);
        AnchorPane.setBottomAnchor(c, 0.0);
        AnchorPane.setLeftAnchor(c, 0.0);
        
        BorderPane root = new BorderPane();
        root.setCenter(anchor);
        
        return root;
    }
    
}

Reasoning onto why making it a Parent : It allows me to turn it into a scene.(though there could be many different ways to do that) How would I implement full screening to the console and get it to show?推理为什么将其设为Parent :它允许我将它变成一个场景。(尽管可能有许多不同的方法可以做到这一点)我将如何对控制台实施全屏显示并让它显示?

There is a lot of code in your question, most is irrelevant to your issue, so I won't discuss it here.你的问题中代码较多,大部分与你的问题无关,这里不展开讨论。 In particular your problem has nothing to do with scaling.特别是您的问题与缩放无关。

The error message tells you what you did wrong:错误消息告诉您做错了什么:

duplicate children added: parent = BorderPane

The code which caused that is this:造成这种情况的代码是这样的:

this.root = new BorderPane();
// . . .
root.getChildren().addAll(
    console, 
    scroll, 
    inputBar
);
root.setBottom(inputBar);

You added inputBar to the root BorderPane twice.您将inputBar添加到root BorderPane 两次。

I don't advise adding to the children of a border pane directly either.我也不建议直接添加到边框窗格的子项。 Instead, use the positional setters on the borderPane to set the positions of the children (those setters will internally add the set nodes as children).相反,使用 borderPane 上的位置设置器来设置子级的位置(这些设置器将在内部将设置节点添加为子级)。 Study the BorderPane documentation.研究BorderPane文档。

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

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