Обновить интерфейс программы на JavaFX через XML

199
06 ноября 2021, 03:20

Вводная.
Я студент (читать как "беспросветный дурачок") и передо мной встала задача - написать программу, которая бы читала и писала файлы XML. И я решил сделать добавить ей немного полезности - не просто прога, которую написал, сдал и забыл, а сделать мини-клиент, в котором я мог бы модифицировать настройки игры. No Man's Sky, если кого интересует. Интерфейс я сделал с помощью SceneBuilder на JavaFX13(до этого с ним опыта не имел, препод просто порекомендовал ознакомиться именно с ним).
Интерфейс:

Проблема.
Каким способом я должен загружать данные из XML так, что бы они отображались в графическом интерфейсе? Насколько я понял, весь менеджмент интерфейса идет от класса контроллера и я как-то туда должен послать объект Document со загруженными данными.
Проект по сути пустой, но для удобства прикреплю документы, что бы было более наглядно:
Main:

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        //inicialitzacio de finestra 
        Parent root = FXMLLoader.load(getClass().getResource("hellofx.fxml"));
        primaryStage.setTitle("No Man's Sky Launcher");
        primaryStage.setScene(new Scene(root, 350, 673));
// по моей логике здесь я должен открывать документ и проверять значение конфига, после чего вставлять значение в интерфейс.
// но как достать отсюда элементы, что находятся в контроллере, я не понимаю. 
        primaryStage.show();
    }

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

}

FXML-файл:

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<VBox fillWidth="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="673.0" prefWidth="350.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Interface_Controller">
   <children>
      <ImageView fitHeight="150.0" fitWidth="350.0" pickOnBounds="true" VBox.vgrow="ALWAYS">
         <image>
            <Image url="@../header.jpg" />
         </image>
         <cursor>
            <Cursor fx:constant="DEFAULT" />
         </cursor>
      </ImageView>
      <AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="350.0">
         <children>
            <Label layoutX="188.0" layoutY="221.0" text="Base Quality" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="221.0" />
            <Button id="btn_saveChanges" fx:id="btn_save" layoutX="14.0" layoutY="761.0" mnemonicParsing="false" onAction="#updateInterface" text="Save changes" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" />
            <Button id="btn_startGame" disable="true" layoutX="241.0" layoutY="611.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="88.0" text="Start game!" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
            <Label layoutX="240.0" layoutY="20.0" text="Resolution" AnchorPane.rightAnchor="53.0" AnchorPane.topAnchor="20.0" />
            <CheckBox id="cbox_fullscreen" fx:id="cbox_fullscreen" layoutX="21.0" layoutY="26.0" mnemonicParsing="false" nodeOrientation="RIGHT_TO_LEFT" text="FullScreen" AnchorPane.leftAnchor="41.0" AnchorPane.topAnchor="20.0" />
            <CheckBox id="cbox_borderless" fx:id="cbox_borderless" layoutX="23.0" layoutY="57.0" mnemonicParsing="false" nodeOrientation="RIGHT_TO_LEFT" text="Borderless" AnchorPane.leftAnchor="41.0" AnchorPane.topAnchor="60.0" />
            <Label layoutX="183.0" layoutY="57.0" text="W:" AnchorPane.rightAnchor="153.0" AnchorPane.topAnchor="60.0" />
            <Label layoutX="259.0" layoutY="57.0" text="x H:" AnchorPane.rightAnchor="71.0" AnchorPane.topAnchor="60.0" />
            <TextField id="txt_width" fx:id="txt_width" disable="true" layoutX="206.0" layoutY="53.0" prefHeight="25.0" prefWidth="48.0" promptText="1920" AnchorPane.rightAnchor="96.0" AnchorPane.topAnchor="57.0" />
            <TextField id="txt_height" fx:id="txt_height" disable="true" layoutX="285.0" layoutY="53.0" prefHeight="25.0" prefWidth="48.0" promptText="1080" AnchorPane.rightAnchor="17.0" AnchorPane.topAnchor="57.0" />
            <ComboBox id="cmbbox_shadowDetail" fx:id="cmb_textureQuality" disable="true" layoutX="254.0" layoutY="97.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.leftAnchor="254.0" AnchorPane.topAnchor="97.0">
                <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Low" />
                        <String fx:value="Medium" />
                        <String fx:value="High" />
                        <String fx:value="Ultra" />
                    </FXCollections>
                </items>
            </ComboBox>
            <Label layoutX="167.0" layoutY="141.0" text="Shadow Quality" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="141.0" />
            <Label layoutX="169.0" layoutY="101.0" text="Texture Quality" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="101.0" />
            <ComboBox id="cmbbox_textureDetail" fx:id="cmb_planetQuality" disable="true" layoutX="254.0" layoutY="177.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="177.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Low" />
                        <String fx:value="Medium" />
                        <String fx:value="High" />
                        <String fx:value="Ultra" />
                    </FXCollections>
                </items>
            </ComboBox>
            <Label layoutX="157.0" layoutY="301.0" text="Terrain Tesselation" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="301.0" />
            <ComboBox id="cmbbox_reflections" fx:id="cmb_baseQuality" disable="true" layoutX="254.0" layoutY="217.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="217.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Low" />
                        <String fx:value="Medium" />
                        <String fx:value="High" />
                        <String fx:value="Ultra" />
                    </FXCollections>
                </items>
            </ComboBox>
            <ComboBox id="cmbbox_generationDetail" fx:id="cmb_anisotropyLevel" disable="true" layoutX="254.0" layoutY="257.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="257.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="1" />
                        <String fx:value="2" />
                        <String fx:value="4" />
                        <String fx:value="8" />
                        <String fx:value="16" />
                    </FXCollections>
                </items>
            </ComboBox>
            <Label layoutX="181.0" layoutY="261.0" text="Anisotropy Level" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="261.0" />
            <ComboBox id="cmbbox_motionBlur" fx:id="cmb_terrainTesselation" disable="true" layoutX="254.0" layoutY="297.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="297.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Low" />
                        <String fx:value="Medium" />
                        <String fx:value="High" />
                        <String fx:value="Ultra" />
                    </FXCollections>
                </items>
            </ComboBox>
            <ComboBox id="cmbbox_terrainQuality" fx:id="cmb_animationQuality" disable="true" layoutX="254.0" layoutY="337.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="337.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Low" />
                        <String fx:value="Medium" />
                        <String fx:value="High" />
                        <String fx:value="Ultra" />
                    </FXCollections>
                </items>
            </ComboBox>
            <Label layoutX="149.0" layoutY="381.0" text="Ambient Occlusion" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="381.0" />
            <ComboBox id="cmbbox_ambientOcclusion" fx:id="cmb_ambientOcclusion" disable="true" layoutX="254.0" layoutY="377.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="377.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Off" />
                        <String fx:value="GTAO_Low" />
                        <String fx:value="GTAO_Medium" />
                        <String fx:value="GTAO_HIgh" />
                    </FXCollections>
                </items>
            </ComboBox>
            <Label layoutX="154.0" layoutY="341.0" text="Animation Quality" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="341.0" />
            <ComboBox id="cmbbox_ambientOcclusion" fx:id="cmb_shadowQuality" disable="true" layoutX="254.0" layoutY="137.0" prefHeight="25.0" prefWidth="78.0" visibleRowCount="4" AnchorPane.rightAnchor="18.0" AnchorPane.topAnchor="137.0">
            <items>
                    <FXCollections fx:factory="observableArrayList">
                        <String fx:value="Low" />
                        <String fx:value="Medium" />
                        <String fx:value="High" />
                        <String fx:value="Ultra" />
                    </FXCollections>
                </items>
            </ComboBox>
            <Label layoutX="176.0" layoutY="181.0" text="Planet Quality" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="181.0" />
            <Slider fx:id="sl_fovOnFoot" disable="true" layoutX="28.0" layoutY="125.0" majorTickUnit="20.0" min="60.0" prefHeight="14.0" prefWidth="101.0" showTickLabels="true" AnchorPane.rightAnchor="221.0" AnchorPane.topAnchor="125.0" />
            <Label layoutX="43.0" layoutY="105.0" text="FoV on Foot: " AnchorPane.rightAnchor="236.0" AnchorPane.topAnchor="105.0" />
            <Slider fx:id="sl_fovInFoot" disable="true" layoutX="28.0" layoutY="175.0" majorTickUnit="20.0" min="60.0" prefHeight="14.0" prefWidth="101.0" showTickLabels="true" AnchorPane.rightAnchor="221.0" AnchorPane.topAnchor="175.0" />
            <Label layoutX="38.0" layoutY="155.0" text="FoV in Sheep: " AnchorPane.rightAnchor="236.0" AnchorPane.topAnchor="155.0" />
            <Slider fx:id="sl_motionBlur" disable="true" layoutX="28.0" layoutY="225.0" majorTickUnit="60.0" max="180.0" prefHeight="14.0" prefWidth="101.0" showTickLabels="true" AnchorPane.rightAnchor="221.0" AnchorPane.topAnchor="225.0" />
            <Label layoutX="45.0" layoutY="205.0" text="Motion Blur: " AnchorPane.rightAnchor="236.0" AnchorPane.topAnchor="205.0" />
            <TextField id="txt_width" fx:id="txt_highThreads" disable="true" layoutX="90.0" layoutY="297.0" prefHeight="25.0" prefWidth="48.0" AnchorPane.rightAnchor="212.0" />
            <Label layoutX="14.0" layoutY="301.0" text="High Threads" AnchorPane.rightAnchor="265.0" AnchorPane.topAnchor="301.0" />
            <TextField id="txt_width" fx:id="txt_lowThreads" disable="true" layoutX="90.0" layoutY="337.0" prefHeight="25.0" prefWidth="48.0" AnchorPane.rightAnchor="212.0" />
            <Label layoutX="18.0" layoutY="341.0" text="Low Threads" AnchorPane.rightAnchor="265.0" />
         </children>
         <VBox.margin>
            <Insets />
         </VBox.margin></AnchorPane>
   </children>
</VBox>

Конфиг игры:

<?xml version="1.0" encoding="utf-8"?>
<Data template="TkGraphicsSettings">
    <Property name="Version" value="4" />
    <Property name="FullScreen" value="true" />
    <Property name="Borderless" value="false" />
    <Property name="Monitor" value="0" />
    <Property name="MonitorNames">
        <Property name="MonitorNames_00" value="0|Intel(R) HD Graphics 630|Generic PnP Monitor" />
    </Property>
    <Property name="ResolutionWidth" value="1920" />
    <Property name="ResolutionHeight" value="1080" />
    <Property name="VsyncEx" value="Triple" />
    <Property name="GraphicsDetail" value="TkGraphicsDetailPreset.xml">
        <Property name="TextureQuality" value="TkGraphicsDetailTypes.xml">
            <Property name="GraphicDetail" value="Low" />
        </Property>
        <Property name="AnimationQuality" value="TkGraphicsDetailTypes.xml" />
        <Property name="ShadowQuality" value="TkGraphicsDetailTypes.xml" />
        <Property name="PostProcessingEffects" value="TkGraphicsDetailTypes.xml" />
        <Property name="VolumetricsQuality" value="TkGraphicsDetailTypes.xml" />
        <Property name="TerrainTessellation" value="TkGraphicsDetailTypes.xml">
            <Property name="GraphicDetail" value="High" />
        </Property>
        <Property name="PlanetQuality" value="TkGraphicsDetailTypes.xml">
            <Property name="GraphicDetail" value="Low" />
        </Property>
        <Property name="BaseQuality" value="TkGraphicsDetailTypes.xml">
            <Property name="GraphicDetail" value="High" />
        </Property>
        <Property name="AmbientOcclusion" value="GTAO_High" />
        <Property name="AnisotropyLevel" value="16" />
    </Property>
    <Property name="MotionBlurStrength" value="180.000000" />
    <Property name="VignetteAndScanlines" value="true" />
    <Property name="FoVOnFoot" value="75.000000" />
    <Property name="FoVInShip" value="75.000000" />
    <Property name="Brightness" value="50" />
    <Property name="MaxframeRate" value="60" />
    <Property name="NumHighThreads" value="1" />
    <Property name="NumLowThreads" value="2" />
    <Property name="TextureStreamingVk" value="Auto" />
    <Property name="ShowRequirementsWarnings" value="true" />
    <Property name="RemoveBaseBuildingRestrictions" value="false" />
    <Property name="MouseClickSpeedMultiplier" value="0.500000" />
    <Property name="UseTerrainTextureCache" value="false" />
    <Property name="UseArbSparseTexture" value="false" />
    <Property name="HDRMode" value="Off" />
    <Property name="AdapterName" value="GeForce GTX 1050 Ti" />
    <Property name="AdapterIndex" value="0" />
    <Property name="NumGraphicsThreadsBeta" value="0" />
</Data>
Answer 1

Что бы при открытии программы загружать данные из XML, надо создать в контроллере


//метод, который запускается при открытии программы
public void initialize() {
        try {
            //Открыть XML: 
            DocumentBuilderFactory fcd = DocumentBuilderFactory.newInstance();      
            DocumentBuilder creadorDocument = fcd.newDocumentBuilder();
            Document doc = creadorDocument.parse("TKGRAPHICSSETTINGS.mxml");
            //Метод, что бы обновить интерфейс
            updateForm(doc);
        }catch(IOException e) {
            System.out.println("ERROR");
        }catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

В main ничего трогать не надо.

READ ALSO
Почему в объекте переменные родителя

Почему в объекте переменные родителя

Был на тестировании по Java и столкнулся со следующей задачей

169
Всплывающая подсказка для JSpinner

Всплывающая подсказка для JSpinner

Я добавляю всплывающую подсказку для счетчика и хочу установить фиксированное местоположение для нееДелаю это так:

112
java: Как реализовать прием и передачу udp пакетов в разных потоках для параллельной работы?

java: Как реализовать прием и передачу udp пакетов в разных потоках для параллельной работы?

пишу приложение для android, при реализации, приведенной ниже, работает прием пакетов, но не работает отправкаесли убрать запуск потока для приема...

160
Проблемы в преобразовании данных в Java

Проблемы в преобразовании данных в Java

Начинаю разбираться в Java и у меня проблемы в преобразовании list в массив

110