Code refactoring
Updating checks functionality changes: avoid new version pop-ups for special builds (versions that have -DEV postfixes)
This commit is contained in:
Dmitry Isaenko 2019-04-10 13:07:28 +03:00
parent 5d31e807dc
commit 2b5956d4f2
8 changed files with 204 additions and 147 deletions

View file

@ -0,0 +1,122 @@
package nsusbloader.Controllers;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import nsusbloader.AppPreferences;
import java.net.URL;
import java.util.ResourceBundle;
public class FrontController implements Initializable {
@FXML
private Pane specialPane;
@FXML
private ChoiceBox<String> choiceProtocol, choiceNetUsb;
@FXML
private Label nsIpLbl;
@FXML
private TextField nsIpTextField;
@FXML
private Button switchThemeBtn;
@FXML
public NSTableViewController tableFilesListController; // Accessible from Mediator
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
specialPane.getStyleClass().add("special-pane-as-border"); // UI hacks
ObservableList<String> choiceProtocolList = FXCollections.observableArrayList("TinFoil", "GoldLeaf");
choiceProtocol.setItems(choiceProtocolList);
choiceProtocol.getSelectionModel().select(AppPreferences.getInstance().getProtocol());
choiceProtocol.setOnAction(e-> {
tableFilesListController.setNewProtocol(choiceProtocol.getSelectionModel().getSelectedItem());
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("GoldLeaf")) {
choiceNetUsb.setDisable(true);
choiceNetUsb.getSelectionModel().select("USB");
nsIpLbl.setVisible(false);
nsIpTextField.setVisible(false);
}
else {
choiceNetUsb.setDisable(false);
if (choiceNetUsb.getSelectionModel().getSelectedItem().equals("NET")) {
nsIpLbl.setVisible(true);
nsIpTextField.setVisible(true);
}
}
}); // Add listener to notify tableView controller
tableFilesListController.setNewProtocol(choiceProtocol.getSelectionModel().getSelectedItem()); // Notify tableView controller
ObservableList<String> choiceNetUsbList = FXCollections.observableArrayList("USB", "NET");
choiceNetUsb.setItems(choiceNetUsbList);
choiceNetUsb.getSelectionModel().select(AppPreferences.getInstance().getNetUsb());
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("GoldLeaf")) {
choiceNetUsb.setDisable(true);
choiceNetUsb.getSelectionModel().select("USB");
}
choiceNetUsb.setOnAction(e->{
if (choiceNetUsb.getSelectionModel().getSelectedItem().equals("NET")){
nsIpLbl.setVisible(true);
nsIpTextField.setVisible(true);
}
else{
nsIpLbl.setVisible(false);
nsIpTextField.setVisible(false);
}
});
// Set and configure NS IP field behavior
nsIpTextField.setText(AppPreferences.getInstance().getNsIp());
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("TinFoil") && choiceNetUsb.getSelectionModel().getSelectedItem().equals("NET")){
nsIpLbl.setVisible(true);
nsIpTextField.setVisible(true);
}
nsIpTextField.setTextFormatter(new TextFormatter<>(change -> {
if (change.getControlNewText().contains(" ") | change.getControlNewText().contains("\t"))
return null;
else
return change;
}));
// Set and configure switch theme button
Region btnSwitchImage = new Region();
btnSwitchImage.getStyleClass().add("regionLamp");
switchThemeBtn.setGraphic(btnSwitchImage);
this.switchThemeBtn.setOnAction(e->switchTheme());
}
/**
* Changes UI theme on the go
* */
private void switchTheme(){
if (switchThemeBtn.getScene().getStylesheets().get(0).equals("/res/app_dark.css")) {
switchThemeBtn.getScene().getStylesheets().remove("/res/app_dark.css");
switchThemeBtn.getScene().getStylesheets().add("/res/app_light.css");
}
else {
switchThemeBtn.getScene().getStylesheets().remove("/res/app_light.css");
switchThemeBtn.getScene().getStylesheets().add("/res/app_dark.css");
}
AppPreferences.getInstance().setTheme(switchThemeBtn.getScene().getStylesheets().get(0));
}
/**
* Get selected protocol (GL/TF)
* */
String getSelectedProtocol(){
return choiceProtocol.getSelectionModel().getSelectedItem();
}
/**
* Get selected protocol (USB/NET)
* */
String getSelectedNetUsb(){
return choiceNetUsb.getSelectionModel().getSelectedItem();
}
/**
* Get NS IP address
* */
String getNsIp(){
return nsIpTextField.getText();
}
}

View file

@ -1,15 +1,12 @@
package nsusbloader.Controllers; package nsusbloader.Controllers;
import javafx.application.HostServices; import javafx.application.HostServices;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.DragEvent; import javafx.scene.input.DragEvent;
import javafx.scene.input.TransferMode; import javafx.scene.input.TransferMode;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import nsusbloader.*; import nsusbloader.*;
@ -36,22 +33,11 @@ public class NSLMainController implements Initializable {
private Region btnUpStopImage; private Region btnUpStopImage;
@FXML @FXML
public ProgressBar progressBar; // Accessible from Mediator public ProgressBar progressBar; // Accessible from Mediator
@FXML
private ChoiceBox<String> choiceProtocol, choiceNetUsb;
@FXML
private Button switchThemeBtn;
@FXML
private Pane specialPane;
@FXML
public NSTableViewController tableFilesListController; // Accessible from Mediator
@FXML @FXML
private SettingsController SettingsTabController; private SettingsController SettingsTabController;
@FXML @FXML
private TextField nsIpTextField; public FrontController FrontTabController; // Accessible from Mediator | todo: incapsulate
@FXML
private Label nsIpLbl;
private Task<Void> usbNetCommunications; private Task<Void> usbNetCommunications;
private Thread workThread; private Thread workThread;
@ -70,8 +56,6 @@ public class NSLMainController implements Initializable {
MediatorControl.getInstance().setController(this); MediatorControl.getInstance().setController(this);
specialPane.getStyleClass().add("special-pane-as-border"); // UI hacks
uploadStopBtn.setDisable(true); uploadStopBtn.setDisable(true);
selectNspBtn.setOnAction(e->{ selectFilesBtnAction(); }); selectNspBtn.setOnAction(e->{ selectFilesBtnAction(); });
uploadStopBtn.setOnAction(e->{ uploadBtnAction(); }); uploadStopBtn.setOnAction(e->{ uploadBtnAction(); });
@ -80,67 +64,11 @@ public class NSLMainController implements Initializable {
this.btnUpStopImage = new Region(); this.btnUpStopImage = new Region();
btnUpStopImage.getStyleClass().add("regionUpload"); btnUpStopImage.getStyleClass().add("regionUpload");
//uploadStopBtn.getStyleClass().remove("button");
uploadStopBtn.getStyleClass().add("buttonUp"); uploadStopBtn.getStyleClass().add("buttonUp");
uploadStopBtn.setGraphic(btnUpStopImage); uploadStopBtn.setGraphic(btnUpStopImage);
ObservableList<String> choiceProtocolList = FXCollections.observableArrayList("TinFoil", "GoldLeaf"); this.previouslyOpenedPath = AppPreferences.getInstance().getRecent();
choiceProtocol.setItems(choiceProtocolList);
choiceProtocol.getSelectionModel().select(AppPreferences.getInstance().getProtocol());
choiceProtocol.setOnAction(e-> {
tableFilesListController.setNewProtocol(choiceProtocol.getSelectionModel().getSelectedItem());
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("GoldLeaf")) {
choiceNetUsb.setDisable(true);
choiceNetUsb.getSelectionModel().select("USB");
nsIpLbl.setVisible(false);
nsIpTextField.setVisible(false);
}
else {
choiceNetUsb.setDisable(false);
if (choiceNetUsb.getSelectionModel().getSelectedItem().equals("NET")) {
nsIpLbl.setVisible(true);
nsIpTextField.setVisible(true);
}
}
}); // Add listener to notify tableView controller
tableFilesListController.setNewProtocol(choiceProtocol.getSelectionModel().getSelectedItem()); // Notify tableView controller
ObservableList<String> choiceNetUsbList = FXCollections.observableArrayList("USB", "NET");
choiceNetUsb.setItems(choiceNetUsbList);
choiceNetUsb.getSelectionModel().select(AppPreferences.getInstance().getNetUsb());
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("GoldLeaf")) {
choiceNetUsb.setDisable(true);
choiceNetUsb.getSelectionModel().select("USB");
}
choiceNetUsb.setOnAction(e->{
if (choiceNetUsb.getSelectionModel().getSelectedItem().equals("NET")){
nsIpLbl.setVisible(true);
nsIpTextField.setVisible(true);
}
else{
nsIpLbl.setVisible(false);
nsIpTextField.setVisible(false);
}
});
nsIpTextField.setText(AppPreferences.getInstance().getNsIp());
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("TinFoil") && choiceNetUsb.getSelectionModel().getSelectedItem().equals("NET")){
nsIpLbl.setVisible(true);
nsIpTextField.setVisible(true);
}
nsIpTextField.setTextFormatter(new TextFormatter<>(change -> {
if (change.getControlNewText().contains(" ") | change.getControlNewText().contains("\t"))
return null;
else
return change;
}));
this.previouslyOpenedPath = null;
Region btnSwitchImage = new Region();
btnSwitchImage.getStyleClass().add("regionLamp");
switchThemeBtn.setGraphic(btnSwitchImage);
this.switchThemeBtn.setOnAction(e->switchTheme());
previouslyOpenedPath = AppPreferences.getInstance().getRecent();
if (AppPreferences.getInstance().getAutoCheckUpdates()){ if (AppPreferences.getInstance().getAutoCheckUpdates()){
Task<List<String>> updTask = new UpdatesChecker(); Task<List<String>> updTask = new UpdatesChecker();
@ -164,20 +92,7 @@ public class NSLMainController implements Initializable {
* Provide hostServices to Settings tab * Provide hostServices to Settings tab
* */ * */
public void setHostServices(HostServices hs ){ SettingsTabController.registerHostServices(hs);} public void setHostServices(HostServices hs ){ SettingsTabController.registerHostServices(hs);}
/**
* Changes UI theme on the go
* */
private void switchTheme(){
if (switchThemeBtn.getScene().getStylesheets().get(0).equals("/res/app_dark.css")) {
switchThemeBtn.getScene().getStylesheets().remove("/res/app_dark.css");
switchThemeBtn.getScene().getStylesheets().add("/res/app_light.css");
}
else {
switchThemeBtn.getScene().getStylesheets().remove("/res/app_light.css");
switchThemeBtn.getScene().getStylesheets().add("/res/app_dark.css");
}
AppPreferences.getInstance().setTheme(switchThemeBtn.getScene().getStylesheets().get(0));
}
/** /**
* Functionality for selecting NSP button. * Functionality for selecting NSP button.
* Uses setReady and setNotReady to simplify code readability. * Uses setReady and setNotReady to simplify code readability.
@ -189,15 +104,15 @@ public class NSLMainController implements Initializable {
File validator = new File(previouslyOpenedPath); File validator = new File(previouslyOpenedPath);
if (validator.exists()) if (validator.exists())
fileChooser.setInitialDirectory(validator); // TODO: read from prefs fileChooser.setInitialDirectory(validator);
else else
fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: read from prefs fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP ROM", "*.nsp")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP ROM", "*.nsp"));
filesList = fileChooser.showOpenMultipleDialog(logArea.getScene().getWindow()); filesList = fileChooser.showOpenMultipleDialog(logArea.getScene().getWindow());
if (filesList != null && !filesList.isEmpty()) { if (filesList != null && !filesList.isEmpty()) {
tableFilesListController.setFiles(filesList); FrontTabController.tableFilesListController.setFiles(filesList);
uploadStopBtn.setDisable(false); uploadStopBtn.setDisable(false);
previouslyOpenedPath = filesList.get(0).getParent(); previouslyOpenedPath = filesList.get(0).getParent();
} }
@ -209,7 +124,7 @@ public class NSLMainController implements Initializable {
if ((workThread == null || !workThread.isAlive())){ if ((workThread == null || !workThread.isAlive())){
// Collect files // Collect files
List<File> nspToUpload; List<File> nspToUpload;
if ((nspToUpload = tableFilesListController.getFilesForUpload()) == null) { if ((nspToUpload = FrontTabController.tableFilesListController.getFilesForUpload()) == null) {
logArea.setText(resourceBundle.getString("logsNoFolderFileSelected")); logArea.setText(resourceBundle.getString("logsNoFolderFileSelected"));
return; return;
} }
@ -219,23 +134,23 @@ public class NSLMainController implements Initializable {
logArea.appendText(" "+item.getAbsolutePath()+"\n"); logArea.appendText(" "+item.getAbsolutePath()+"\n");
} }
// If USB selected // If USB selected
if (choiceProtocol.getSelectionModel().getSelectedItem().equals("GoldLeaf") || if (FrontTabController.getSelectedProtocol().equals("GoldLeaf") ||
( (
choiceProtocol.getSelectionModel().getSelectedItem().equals("TinFoil") FrontTabController.getSelectedProtocol().equals("TinFoil")
&& choiceNetUsb.getSelectionModel().getSelectedItem().equals("USB") && FrontTabController.getSelectedNetUsb().equals("USB")
) )
){ ){
usbNetCommunications = new UsbCommunications(nspToUpload, choiceProtocol.getSelectionModel().getSelectedItem()); usbNetCommunications = new UsbCommunications(nspToUpload, FrontTabController.getSelectedProtocol());
workThread = new Thread(usbNetCommunications); workThread = new Thread(usbNetCommunications);
workThread.setDaemon(true); workThread.setDaemon(true);
workThread.start(); workThread.start();
} }
else { // NET INSTALL OVER TINFOIL else { // NET INSTALL OVER TINFOIL
if (SettingsTabController.isNsIpValidate() && !nsIpTextField.getText().matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$")) if (SettingsTabController.isNsIpValidate() && ! FrontTabController.getNsIp().matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"))
if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"),resourceBundle.getString("windowBodyBadIp"))) if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"),resourceBundle.getString("windowBodyBadIp")))
return; return;
String nsIP = nsIpTextField.getText(); String nsIP = FrontTabController.getNsIp();
if (!SettingsTabController.getExpertModeSelected()) if (!SettingsTabController.getExpertModeSelected())
usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", ""); usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", "");
@ -261,7 +176,7 @@ public class NSLMainController implements Initializable {
* */ * */
private void stopBtnAction(){ private void stopBtnAction(){
if (workThread != null && workThread.isAlive()){ if (workThread != null && workThread.isAlive()){
usbNetCommunications.cancel(false); // TODO: add something abstract to use also for network usbNetCommunications.cancel(false);
} }
} }
/** /**
@ -332,19 +247,19 @@ public class NSLMainController implements Initializable {
se.printStackTrace(); se.printStackTrace();
} }
if (!filesDropped.isEmpty()) if (!filesDropped.isEmpty())
tableFilesListController.setFiles(filesDropped); FrontTabController.tableFilesListController.setFiles(filesDropped);
event.setDropCompleted(true); event.setDropCompleted(true);
} }
/** /**
* Save preferences before exit * Save preferences before exit
* */ * */
public void exit(){ // TODO: add method to set all in AppPreferences public void exit(){
AppPreferences.getInstance().setAll( AppPreferences.getInstance().setAll(
choiceProtocol.getSelectionModel().getSelectedItem(), FrontTabController.getSelectedProtocol(),
previouslyOpenedPath, previouslyOpenedPath,
choiceNetUsb.getSelectionModel().getSelectedItem(), FrontTabController.getSelectedNetUsb(),
nsIpTextField.getText().trim(), FrontTabController.getNsIp(),
SettingsTabController.isNsIpValidate(), SettingsTabController.isNsIpValidate(),
SettingsTabController.getExpertModeSelected(), SettingsTabController.getExpertModeSelected(),
SettingsTabController.getAutoIpSelected(), SettingsTabController.getAutoIpSelected(),

View file

@ -33,7 +33,7 @@ public class MessagesConsumer extends AnimationTimer {
this.progressBar = MediatorControl.getInstance().getContoller().progressBar; this.progressBar = MediatorControl.getInstance().getContoller().progressBar;
this.statusMap = statusMap; this.statusMap = statusMap;
this.tableViewController = MediatorControl.getInstance().getContoller().tableFilesListController; this.tableViewController = MediatorControl.getInstance().getContoller().FrontTabController.tableFilesListController;
progressBar.setProgress(0.0); progressBar.setProgress(0.0);

View file

@ -50,8 +50,14 @@ public class UpdatesChecker extends Task<List<String>> {
return null; return null;
} }
String currentVersion;
if (NSLMain.appVersion.matches("^v(([0-9])+?\\.)+[0-9]+(-.+)$")) // if current version have postfix like v0.1-Experimental
currentVersion = NSLMain.appVersion.replaceAll("(-.*$)", ""); // cut postfix
else
currentVersion = NSLMain.appVersion;
List<String> returningValue = new ArrayList<>(); List<String> returningValue = new ArrayList<>();
if (!newVersion.equals(NSLMain.appVersion)) { // if latest noted version in GitHub is different to this version if (!newVersion.equals(currentVersion)) { // if latest noted version in GitHub is different to this version
returningValue.add(newVersion); returningValue.add(newVersion);
returningValue.add(changeLog); returningValue.add(changeLog);
return returningValue; return returningValue;

View file

@ -12,7 +12,7 @@ import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class NSLMain extends Application { public class NSLMain extends Application {
public static final String appVersion = "v0.4"; public static final String appVersion = "v0.4.1";
@Override @Override
public void start(Stage primaryStage) throws Exception{ public void start(Stage primaryStage) throws Exception{

View file

@ -456,7 +456,7 @@ public class UsbCommunications extends Task<Void> {
* GoldLeaf processing * GoldLeaf processing
* */ * */
private class GoldLeaf{ private class GoldLeaf{
// CMD G L U C ID 0 0 0 // CMD G L U C
private final byte[] CMD_GLUC = new byte[]{0x47, 0x4c, 0x55, 0x43}; private final byte[] CMD_GLUC = new byte[]{0x47, 0x4c, 0x55, 0x43};
private final byte[] CMD_ConnectionRequest = new byte[]{0x00, 0x00, 0x00, 0x00}; // Write-only command private final byte[] CMD_ConnectionRequest = new byte[]{0x00, 0x00, 0x00, 0x00}; // Write-only command
private final byte[] CMD_NSPName = new byte[]{0x02, 0x00, 0x00, 0x00}; // Write-only command private final byte[] CMD_NSPName = new byte[]{0x02, 0x00, 0x00, 0x00}; // Write-only command

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.FrontController">
<children>
<VBox layoutX="10.0" layoutY="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<ToolBar>
<items>
<ChoiceBox fx:id="choiceProtocol" prefWidth="120.0" />
<ChoiceBox fx:id="choiceNetUsb" prefWidth="75.0" />
<Label fx:id="nsIpLbl" text="%NSIPlable" visible="false" />
<TextField fx:id="nsIpTextField" prefWidth="135.0" promptText="XXX.XXX.XXX.XXX" visible="false" />
<Pane HBox.hgrow="ALWAYS" />
<Button fx:id="switchThemeBtn" mnemonicParsing="false" />
</items>
</ToolBar>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="90.0" />
<ColumnConstraints hgrow="SOMETIMES" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane fx:id="specialPane" GridPane.columnIndex="1" />
</children>
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
</GridPane>
<fx:include fx:id="tableFilesList" source="TableView.fxml" />
</children>
</VBox>
</children>
</AnchorPane>

View file

@ -2,20 +2,13 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?> <?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.Tab?> <?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?> <?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.TextArea?> <?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?> <?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.SVGPath?> <?import javafx.scene.shape.SVGPath?>
@ -27,37 +20,7 @@
<tabs> <tabs>
<Tab closable="false"> <Tab closable="false">
<content> <content>
<VBox prefHeight="200.0" prefWidth="100.0"> <fx:include fx:id="FrontTab" source="FrontTab.fxml" VBox.vgrow="ALWAYS" />
<children>
<ToolBar>
<items>
<ChoiceBox fx:id="choiceProtocol" prefWidth="120.0" />
<ChoiceBox fx:id="choiceNetUsb" prefWidth="75.0" />
<Label fx:id="nsIpLbl" text="%NSIPlable" visible="false" />
<TextField fx:id="nsIpTextField" prefWidth="135.0" promptText="XXX.XXX.XXX.XXX" visible="false" />
<Pane HBox.hgrow="ALWAYS" />
<Button fx:id="switchThemeBtn" mnemonicParsing="false" />
</items>
</ToolBar>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="90.0" />
<ColumnConstraints hgrow="SOMETIMES" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane fx:id="specialPane" GridPane.columnIndex="1" />
</children>
<VBox.margin>
<Insets bottom="2.0" />
</VBox.margin>
</GridPane>
<fx:include fx:id="tableFilesList" source="TableView.fxml" VBox.vgrow="ALWAYS" />
</children>
</VBox>
</content> </content>
<graphic> <graphic>
<SVGPath content="M21,19V17H8V19H21M21,13V11H8V13H21M8,7H21V5H8V7M4,5V7H6V5H4M3,5A1,1 0 0,1 4,4H6A1,1 0 0,1 7,5V7A1,1 0 0,1 6,8H4A1,1 0 0,1 3,7V5M4,11V13H6V11H4M3,11A1,1 0 0,1 4,10H6A1,1 0 0,1 7,11V13A1,1 0 0,1 6,14H4A1,1 0 0,1 3,13V11M4,17V19H6V17H4M3,17A1,1 0 0,1 4,16H6A1,1 0 0,1 7,17V19A1,1 0 0,1 6,20H4A1,1 0 0,1 3,19V17Z" /> <SVGPath content="M21,19V17H8V19H21M21,13V11H8V13H21M8,7H21V5H8V7M4,5V7H6V5H4M3,5A1,1 0 0,1 4,4H6A1,1 0 0,1 7,5V7A1,1 0 0,1 6,8H4A1,1 0 0,1 3,7V5M4,11V13H6V11H4M3,11A1,1 0 0,1 4,10H6A1,1 0 0,1 7,11V13A1,1 0 0,1 6,14H4A1,1 0 0,1 3,13V11M4,17V19H6V17H4M3,17A1,1 0 0,1 4,16H6A1,1 0 0,1 7,17V19A1,1 0 0,1 6,20H4A1,1 0 0,1 3,19V17Z" />