Convert settings.fxml to Java code

This commit is contained in:
huangyuhui 2018-08-29 20:28:43 +08:00
parent 7c77c317df
commit 2f35baef39
4 changed files with 465 additions and 220 deletions

3
.gitignore vendored
View File

@ -27,3 +27,6 @@ NVIDIA
# eclipse
.classpath
.project
# netbeans
.nb-gradle

View File

@ -62,67 +62,14 @@ import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
public final class SettingsPage extends StackPane implements DecoratorPage {
public final class SettingsPage extends SettingsView implements DecoratorPage {
private final StringProperty title = new SimpleStringProperty(this, "title", i18n("settings.launcher"));
@FXML
private JFXTextField txtProxyHost;
@FXML
private JFXTextField txtProxyPort;
@FXML
private JFXTextField txtProxyUsername;
@FXML
private JFXPasswordField txtProxyPassword;
@FXML
private JFXTextField txtFontSize;
@FXML
private JFXComboBox<Label> cboLanguage;
@FXML
private JFXComboBox<?> cboDownloadSource;
@FXML
private FontComboBox cboFont;
@FXML
private MultiFileItem<EnumCommonDirectory> fileCommonLocation;
@FXML
private Label lblDisplay;
@FXML
private Label lblUpdate;
@FXML
private Label lblUpdateSub;
@FXML
private Text lblUpdateNote;
@FXML
private JFXRadioButton chkUpdateStable;
@FXML
private JFXRadioButton chkUpdateDev;
@FXML
private JFXButton btnUpdate;
@FXML
private ScrollPane scroll;
@FXML
private MultiFileItem<EnumBackgroundImage> backgroundItem;
@FXML
private StackPane themeColorPickerContainer;
@FXML
private JFXCheckBox chkDisableProxy;
@FXML
private JFXRadioButton chkProxyHttp;
@FXML
private JFXRadioButton chkProxySocks;
@FXML
private JFXCheckBox chkProxyAuthentication;
@FXML
private GridPane authPane;
@FXML
private Pane proxyPane;
private ObjectProperty<Proxy.Type> selectedProxyType;
private InvalidationListener updateListener;
public SettingsPage() {
FXUtils.loadFXML(this, "/assets/fxml/setting.fxml");
FXUtils.smoothScrolling(scroll);
cboDownloadSource.getSelectionModel().select(DownloadProviders.DOWNLOAD_PROVIDERS.indexOf(Settings.instance().getDownloadProvider()));
@ -306,8 +253,8 @@ public final class SettingsPage extends StackPane implements DecoratorPage {
this.title.set(title);
}
@FXML
private void onUpdate() {
@Override
protected void onUpdate() {
RemoteVersion target = UpdateChecker.getLatestVersion();
if (target == null) {
return;

View File

@ -0,0 +1,459 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui;
import com.jfoenix.controls.*;
import javafx.fxml.FXML;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import org.jackhuang.hmcl.setting.EnumBackgroundImage;
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
import org.jackhuang.hmcl.setting.Theme;
import org.jackhuang.hmcl.ui.construct.*;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.i18n.I18n;
public abstract class SettingsView extends StackPane {
protected final JFXTextField txtProxyHost;
protected final JFXTextField txtProxyPort;
protected final JFXTextField txtProxyUsername;
protected final JFXPasswordField txtProxyPassword;
protected final JFXTextField txtFontSize;
protected final JFXComboBox<Label> cboLanguage;
protected final JFXComboBox<Label> cboDownloadSource;
protected final FontComboBox cboFont;
protected final MultiFileItem<EnumCommonDirectory> fileCommonLocation;
protected final Label lblDisplay;
protected final Label lblUpdate;
protected final Label lblUpdateSub;
protected final Text lblUpdateNote;
protected final JFXRadioButton chkUpdateStable;
protected final JFXRadioButton chkUpdateDev;
protected final JFXButton btnUpdate;
protected final ScrollPane scroll;
protected final MultiFileItem<EnumBackgroundImage> backgroundItem;
protected final StackPane themeColorPickerContainer;
protected final JFXCheckBox chkDisableProxy;
protected final JFXRadioButton chkProxyHttp;
protected final JFXRadioButton chkProxySocks;
protected final JFXCheckBox chkProxyAuthentication;
protected final GridPane authPane;
protected final Pane proxyPane;
public SettingsView() {
scroll = new ScrollPane();
getChildren().setAll(scroll);
scroll.setStyle("-fx-font-size: 14; -fx-pref-width: 100%;");
scroll.setFitToHeight(true);
scroll.setFitToWidth(true);
{
VBox rootPane = new VBox();
rootPane.setStyle("-fx-padding: 20;");
{
ComponentList settingsPane = new ComponentList();
{
ComponentSublist updatePane = new ComponentSublist();
updatePane.setTitle(I18n.i18n("update"));
updatePane.setHasSubtitle(true);
{
VBox headerLeft = new VBox();
lblUpdate = new Label(I18n.i18n("update"));
lblUpdateSub = new Label();
lblUpdateSub.getStyleClass().setAll("subtitle-label");
headerLeft.getChildren().setAll(lblUpdate, lblUpdateSub);
updatePane.setHeaderLeft(headerLeft);
}
{
btnUpdate = new JFXButton();
btnUpdate.setOnMouseClicked(e -> onUpdate());
btnUpdate.getStyleClass().setAll("toggle-icon4");
btnUpdate.setGraphic(SVG.update(Theme.blackFillBinding(), 20, 20));
updatePane.setHeaderRight(btnUpdate);
}
{
VBox content = new VBox();
content.setSpacing(8);
chkUpdateStable = new JFXRadioButton(I18n.i18n("update.channel.stable"));
chkUpdateDev = new JFXRadioButton(I18n.i18n("update.channel.dev"));
VBox noteWrapper = new VBox();
noteWrapper.setStyle("-fx-padding: 10 0 0 0;");
lblUpdateNote = new Text(I18n.i18n("update.note"));
noteWrapper.getChildren().setAll(lblUpdateNote);
content.getChildren().setAll(chkUpdateStable, chkUpdateDev, noteWrapper);
updatePane.addChildren(content);
}
settingsPane.addChildren(updatePane);
}
{
fileCommonLocation = new MultiFileItem<>(true);
fileCommonLocation.setTitle(I18n.i18n("launcher.common_directory"));
fileCommonLocation.setDirectory(true);
fileCommonLocation.setChooserTitle(I18n.i18n("launcher.common_directory.choose"));
fileCommonLocation.setHasSubtitle(true);
fileCommonLocation.setCustomText("settings.custom");
settingsPane.addChildren(fileCommonLocation);
}
{
backgroundItem = new MultiFileItem<>(true);
backgroundItem.setTitle(I18n.i18n("launcher.background"));
backgroundItem.setChooserTitle(I18n.i18n("launcher.background.choose"));
backgroundItem.setHasSubtitle(true);
backgroundItem.setCustomText(I18n.i18n("settings.custom"));
settingsPane.addChildren(backgroundItem);
}
{
BorderPane downloadSourcePane = new BorderPane();
{
Label label = new Label(I18n.i18n("settings.launcher.download_source"));
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
downloadSourcePane.setLeft(label);
}
{
cboDownloadSource = new JFXComboBox<>();
FXUtils.setLimitWidth(cboDownloadSource, 400);
cboDownloadSource.getItems().setAll(
new Label(I18n.i18n("download.mojang")),
new Label(I18n.i18n("download.BMCL"))
);
downloadSourcePane.setRight(cboDownloadSource);
}
settingsPane.addChildren(downloadSourcePane);
}
{
BorderPane languagePane = new BorderPane();
Label left = new Label(I18n.i18n("settings.launcher.language"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
languagePane.setLeft(left);
cboLanguage = new JFXComboBox<>();
FXUtils.setLimitWidth(cboLanguage, 400);
languagePane.setRight(cboLanguage);
settingsPane.addChildren(languagePane);
}
{
ComponentList proxyList = new ComponentList();
proxyList.setTitle(I18n.i18n("settings.launcher.proxy"));
VBox proxyWrapper = new VBox();
proxyWrapper.setSpacing(10);
{
chkDisableProxy = new JFXCheckBox(I18n.i18n("settings.launcher.proxy.disable"));
proxyWrapper.getChildren().add(chkDisableProxy);
}
{
proxyPane = new VBox();
proxyPane.setStyle("-fx-padding: 0 0 0 30;");
ColumnConstraints colHgrow = new ColumnConstraints();
colHgrow.setHgrow(Priority.ALWAYS);
{
HBox hBox = new HBox();
chkProxyHttp = new JFXRadioButton(I18n.i18n("settings.launcher.proxy.http"));
chkProxySocks = new JFXRadioButton(I18n.i18n("settings.launcher.proxy.socks"));
hBox.getChildren().setAll(chkProxyHttp, chkProxySocks);
proxyPane.getChildren().add(hBox);
}
{
GridPane gridPane = new GridPane();
gridPane.setHgap(20);
gridPane.setVgap(10);
gridPane.setStyle("-fx-padding: 0 0 0 15;");
gridPane.getColumnConstraints().setAll(new ColumnConstraints(), colHgrow);
gridPane.getRowConstraints().setAll(new RowConstraints(), new RowConstraints());
{
Label host = new Label(I18n.i18n("settings.launcher.proxy.host"));
GridPane.setRowIndex(host, 1);
GridPane.setColumnIndex(host, 0);
GridPane.setHalignment(host, HPos.RIGHT);
gridPane.getChildren().add(host);
}
{
txtProxyHost = new JFXTextField();
txtProxyHost.getStyleClass().setAll("fit-width");
GridPane.setRowIndex(txtProxyHost, 1);
GridPane.setColumnIndex(txtProxyHost, 1);
gridPane.getChildren().add(txtProxyHost);
}
{
Label port = new Label(I18n.i18n("settings.launcher.proxy.port"));
GridPane.setRowIndex(port, 2);
GridPane.setColumnIndex(port, 0);
GridPane.setHalignment(port, HPos.RIGHT);
gridPane.getChildren().add(port);
}
{
txtProxyPort = new JFXTextField();
txtProxyPort.getStyleClass().setAll("fit-width");
GridPane.setRowIndex(txtProxyPort, 2);
GridPane.setColumnIndex(txtProxyPort, 1);
FXUtils.setValidateWhileTextChanged(txtProxyPort, true);
txtProxyHost.getValidators().setAll(new NumberValidator(I18n.i18n("input.number"), false));
gridPane.getChildren().add(txtProxyPort);
}
proxyPane.getChildren().add(gridPane);
}
{
VBox vBox = new VBox();
vBox.setStyle("-fx-padding: 20 0 20 5;");
chkProxyAuthentication = new JFXCheckBox(I18n.i18n("settings.launcher.proxy.authentication"));
vBox.getChildren().setAll(chkProxyAuthentication);
proxyPane.getChildren().add(vBox);
}
{
authPane = new GridPane();
authPane.setHgap(20);
authPane.setVgap(10);
authPane.setStyle("-fx-padding: 0 0 0 15;");
authPane.getColumnConstraints().setAll(new ColumnConstraints(), colHgrow);
authPane.getRowConstraints().setAll(new RowConstraints(), new RowConstraints());
{
Label username = new Label(I18n.i18n("settings.launcher.proxy.username"));
GridPane.setRowIndex(username, 0);
GridPane.setColumnIndex(username, 0);
authPane.getChildren().add(username);
}
{
txtProxyUsername = new JFXTextField();
txtProxyUsername.getStyleClass().setAll("fit-width");
GridPane.setRowIndex(txtProxyUsername, 0);
GridPane.setColumnIndex(txtProxyUsername, 1);
authPane.getChildren().add(txtProxyUsername);
}
{
Label password = new Label(I18n.i18n("settings.launcher.proxy.password"));
GridPane.setRowIndex(password, 1);
GridPane.setColumnIndex(password, 0);
authPane.getChildren().add(password);
}
{
txtProxyPassword = new JFXPasswordField();
txtProxyPassword.getStyleClass().setAll("fit-width");
GridPane.setRowIndex(txtProxyPassword, 1);
GridPane.setColumnIndex(txtProxyPassword, 1);
authPane.getChildren().add(txtProxyPassword);
}
proxyPane.getChildren().add(authPane);
}
proxyWrapper.getChildren().add(proxyPane);
}
proxyList.addChildren(proxyWrapper);
settingsPane.addChildren(proxyList);
}
{
BorderPane themePane = new BorderPane();
Label left = new Label(I18n.i18n("settings.launcher.theme"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
themePane.setLeft(left);
themeColorPickerContainer = new StackPane();
themeColorPickerContainer.setMinHeight(30);
themePane.setRight(themeColorPickerContainer);
settingsPane.addChildren(themePane);
}
{
VBox fontPane = new VBox();
fontPane.setSpacing(5);
settingsPane.addChildren(fontPane);
{
BorderPane borderPane = new BorderPane();
fontPane.getChildren().add(borderPane);
{
Label left = new Label(I18n.i18n("settings.launcher.log_font"));
BorderPane.setAlignment(left, Pos.CENTER_LEFT);
borderPane.setLeft(left);
}
{
HBox hBox = new HBox();
hBox.setSpacing(3);
cboFont = new FontComboBox(12, false);
txtFontSize = new JFXTextField();
FXUtils.setLimitWidth(txtFontSize, 50);
hBox.getChildren().setAll(cboFont, txtFontSize);
borderPane.setRight(hBox);
}
}
lblDisplay = new Label("[23:33:33] [Client Thread/INFO] [WaterPower]: Loaded mod WaterPower.");
fontPane.getChildren().add(lblDisplay);
}
{
StackPane aboutPane = new StackPane();
GridPane gridPane = new GridPane();
gridPane.setHgap(20);
gridPane.setVgap(10);
ColumnConstraints col1 = new ColumnConstraints();
col1.setHgrow(Priority.SOMETIMES);
col1.setMaxWidth(Double.NEGATIVE_INFINITY);
col1.setMinWidth(Double.NEGATIVE_INFINITY);
ColumnConstraints col2 = new ColumnConstraints();
col2.setHgrow(Priority.SOMETIMES);
col2.setMinWidth(20);
col2.setMaxWidth(Double.POSITIVE_INFINITY);
gridPane.getColumnConstraints().setAll(col1, col2);
RowConstraints row = new RowConstraints();
row.setMinHeight(Double.NEGATIVE_INFINITY);
row.setValignment(VPos.TOP);
row.setVgrow(Priority.SOMETIMES);
gridPane.getRowConstraints().setAll(row, row, row, row, row, row);
{
Label label = new Label(I18n.i18n("about.copyright"));
GridPane.setRowIndex(label, 0);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.copyright.statement"));
label.setWrapText(true);
GridPane.setRowIndex(label, 0);
GridPane.setColumnIndex(label, 1);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.author"));
GridPane.setRowIndex(label, 1);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.author.statement"));
label.setWrapText(true);
GridPane.setRowIndex(label, 1);
GridPane.setColumnIndex(label, 1);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.thanks_to"));
GridPane.setRowIndex(label, 2);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.thanks_to.statement"));
label.setWrapText(true);
GridPane.setRowIndex(label, 2);
GridPane.setColumnIndex(label, 1);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.dependency"));
GridPane.setRowIndex(label, 3);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.dependency.statement"));
label.setWrapText(true);
GridPane.setRowIndex(label, 3);
GridPane.setColumnIndex(label, 1);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.claim"));
GridPane.setRowIndex(label, 4);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.claim.statement"));
label.setWrapText(true);
label.setTextAlignment(TextAlignment.JUSTIFY);
GridPane.setRowIndex(label, 4);
GridPane.setColumnIndex(label, 1);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.open_source"));
GridPane.setRowIndex(label, 5);
GridPane.setColumnIndex(label, 0);
gridPane.getChildren().add(label);
}
{
Label label = new Label(I18n.i18n("about.open_source.statement"));
label.setWrapText(true);
GridPane.setRowIndex(label, 5);
GridPane.setColumnIndex(label, 1);
gridPane.getChildren().add(label);
}
aboutPane.getChildren().setAll(gridPane);
settingsPane.addChildren(aboutPane);
}
rootPane.getChildren().add(settingsPane);
}
scroll.setContent(rootPane);
}
}
protected abstract void onUpdate();
}

View File

@ -1,164 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.*?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.jackhuang.hmcl.ui.construct.*?>
<?import org.jackhuang.hmcl.ui.FXUtils?>
<?import javafx.scene.text.Text?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane">
<ScrollPane fx:id="scroll"
style="-fx-font-size: 14; -fx-pref-width: 100%; "
fitToHeight="true" fitToWidth="true">
<VBox fx:id="rootPane" style="-fx-padding: 20;">
<ComponentList fx:id="settingsPane">
<ComponentSublist fx:id="updatePane" title="%update" hasSubtitle="true">
<headerLeft>
<VBox>
<Label fx:id="lblUpdate" text="%update" BorderPane.alignment="CENTER_LEFT"/>
<Label fx:id="lblUpdateSub" styleClass="subtitle-label"/>
</VBox>
</headerLeft>
<headerRight>
<JFXButton fx:id="btnUpdate" onMouseClicked="#onUpdate" styleClass="toggle-icon4">
<graphic>
<fx:include source="/assets/svg/update.fxml" />
</graphic>
</JFXButton>
</headerRight>
<VBox spacing="8">
<JFXRadioButton fx:id="chkUpdateStable" text="%update.channel.stable" />
<JFXRadioButton fx:id="chkUpdateDev" text="%update.channel.dev" />
<VBox style="-fx-padding: 10 0 0 0;">
<Text fx:id="lblUpdateNote" text="%update.note" />
</VBox>
</VBox>
</ComponentSublist>
<MultiFileItem fx:id="fileCommonLocation" title="%launcher.common_directory" directory="true" chooserTitle="%launcher.common_directory.choose" hasSubtitle="true" customText="%settings.custom" />
<MultiFileItem fx:id="backgroundItem" title="%launcher.background" chooserTitle="%launcher.background.choose"
hasSubtitle="true" customText="%settings.custom" />
<BorderPane><left><Label text="%settings.launcher.download_source" BorderPane.alignment="CENTER_LEFT" /></left><right><JFXComboBox fx:id="cboDownloadSource" FXUtils.limitWidth="400">
<items>
<FXCollections fx:factory="observableArrayList">
<Label text="%download.mojang" />
<Label text="%download.BMCL" />
</FXCollections>
</items>
</JFXComboBox></right></BorderPane>
<BorderPane>
<left>
<Label text="%settings.launcher.language" BorderPane.alignment="CENTER_LEFT" />
</left>
<right>
<JFXComboBox fx:id="cboLanguage" FXUtils.limitWidth="400" />
</right>
</BorderPane>
<ComponentList title="%settings.launcher.proxy"> <!-- proxy -->
<VBox spacing="10">
<JFXCheckBox fx:id="chkDisableProxy" text="%settings.launcher.proxy.disable" />
<VBox fx:id="proxyPane" style="-fx-padding: 0 0 0 30;">
<HBox>
<JFXRadioButton fx:id="chkProxyHttp" text="%settings.launcher.proxy.http" />
<JFXRadioButton fx:id="chkProxySocks" text="%settings.launcher.proxy.socks" />
</HBox>
<GridPane hgap="20" vgap="10" style="-fx-padding: 0 0 0 15;">
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints hgrow="ALWAYS" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
</rowConstraints>
<Label text="%settings.launcher.proxy.host" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.halignment="RIGHT" />
<JFXTextField fx:id="txtProxyHost" styleClass="fit-width" GridPane.rowIndex="1" GridPane.columnIndex="1" />
<Label text="%settings.launcher.proxy.port" GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.halignment="RIGHT" />
<JFXTextField fx:id="txtProxyPort" styleClass="fit-width" GridPane.rowIndex="2" GridPane.columnIndex="1" FXUtils.validateWhileTextChanged="true">
<validators>
<NumberValidator message="%input.number" nullable="false" />
</validators>
</JFXTextField>
</GridPane>
<VBox style="-fx-padding: 20 0 20 5;">
<JFXCheckBox fx:id="chkProxyAuthentication" text="%settings.launcher.proxy.authentication" />
</VBox>
<GridPane fx:id="authPane" hgap="20" vgap="10" style="-fx-padding: 0 0 0 15;">
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints hgrow="ALWAYS" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
</rowConstraints>
<Label fx:id="" text="%settings.launcher.proxy.username" GridPane.rowIndex="0" GridPane.columnIndex="0" />
<JFXTextField fx:id="txtProxyUsername" styleClass="fit-width" GridPane.rowIndex="0" GridPane.columnIndex="1" />
<Label text="%settings.launcher.proxy.password" GridPane.rowIndex="1" GridPane.columnIndex="0" />
<JFXPasswordField fx:id="txtProxyPassword" styleClass="fit-width" GridPane.rowIndex="1" GridPane.columnIndex="1" />
</GridPane>
</VBox>
</VBox>
</ComponentList>
<BorderPane>
<left>
<Label text="%settings.launcher.theme" BorderPane.alignment="CENTER_LEFT" />
</left>
<right>
<StackPane fx:id="themeColorPickerContainer" minHeight="30" />
</right>
</BorderPane>
<VBox spacing="5">
<BorderPane><left><Label text="%settings.launcher.log_font" BorderPane.alignment="CENTER_LEFT" /></left><right><HBox spacing="3"><FontComboBox fontSize="12" enableStyle="false" fx:id="cboFont" /><JFXTextField fx:id="txtFontSize" maxWidth="50" minWidth="50" /></HBox></right></BorderPane>
<Label fx:id="lblDisplay" text="[23:33:33] [Client Thread/INFO] [WaterPower]: Loaded mod WaterPower." />
</VBox>
<StackPane>
<GridPane hgap="20" vgap="10">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="Infinity" minWidth="20" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="-Infinity" valignment="TOP" vgrow="SOMETIMES" />
<RowConstraints minHeight="-Infinity" valignment="TOP" vgrow="SOMETIMES" />
<RowConstraints minHeight="-Infinity" valignment="TOP" vgrow="SOMETIMES" />
<RowConstraints minHeight="-Infinity" valignment="TOP" vgrow="SOMETIMES" />
<RowConstraints minHeight="-Infinity" valignment="TOP" vgrow="SOMETIMES" />
<RowConstraints minHeight="-Infinity" valignment="TOP" vgrow="SOMETIMES" />
</rowConstraints>
<Label text="%about.copyright" GridPane.columnIndex="0" GridPane.rowIndex="0" />
<Label wrapText="true" text="%about.copyright.statement" GridPane.columnIndex="1" GridPane.rowIndex="0" />
<Label text="%about.author" GridPane.columnIndex="0" GridPane.rowIndex="1" />
<Label wrapText="true" text="%about.author.statement" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="%about.thanks_to" GridPane.columnIndex="0" GridPane.rowIndex="2" />
<Label wrapText="true" text="%about.thanks_to.statement" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="%about.dependency" GridPane.columnIndex="0" GridPane.rowIndex="3" />
<Label wrapText="true" text="%about.dependency.statement" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label text="%about.claim" GridPane.columnIndex="0" GridPane.rowIndex="4" />
<Label textAlignment="JUSTIFY" wrapText="true" text="%about.claim.statement" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label text="%about.open_source" GridPane.columnIndex="0" GridPane.rowIndex="5" />
<Label wrapText="true" text="%about.open_source.statement" GridPane.columnIndex="1" GridPane.rowIndex="5" />
</GridPane>
</StackPane>
</ComponentList>
</VBox>
</ScrollPane>
</fx:root>