简体   繁体   中英

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

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.

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?

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.

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). Study the BorderPane documentation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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