PKT8 - working

This commit is contained in:
Alexander Nozik 2016-09-29 13:52:24 +03:00
parent d3f3483bd1
commit a33457d025
7 changed files with 128 additions and 177 deletions

View File

@ -12,5 +12,13 @@ dependencies {
compile 'de.jensd:shichimifx:1.0.5' compile 'de.jensd:shichimifx:1.0.5'
compile project(':dataforge-control') compile project(':dataforge-control')
compile project(':dataforge-storage') compile project(':dataforge-storage')
compile project(':dataforge-plots') compile project(':dataforge-plots:plots-jfc')
}
task debug(dependsOn: classes, type: JavaExec) {
main mainClass
args "--debug=true"
classpath = sourceSets.main.runtimeClasspath
description "Start application in debug mode with default virtual port"
group "debug"
} }

View File

@ -17,6 +17,7 @@ package inr.numass.cryotemp;
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Level;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.io.MetaFileReader;
import hep.dataforge.storage.commons.StorageManager; import hep.dataforge.storage.commons.StorageManager;
import javafx.application.Application; import javafx.application.Application;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
@ -25,7 +26,9 @@ import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.util.Locale; import java.util.Locale;
/** /**
@ -43,7 +46,7 @@ public class PKT8App extends Application {
} }
@Override @Override
public void start(Stage primaryStage) throws IOException, ControlException { public void start(Stage primaryStage) throws IOException, ControlException, ParseException {
Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой Locale.setDefault(Locale.US);// чтобы отделение десятичных знаков было точкой
ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.INFO); rootLogger.setLevel(Level.INFO);
@ -68,6 +71,12 @@ public class PKT8App extends Application {
// primaryStage.setResizable(false); // primaryStage.setResizable(false);
primaryStage.show(); primaryStage.show();
if(getParameters().getNamed().containsKey("cfgFile")){
controller.setConfig(MetaFileReader.read(new File(getParameters().getNamed().get("cfgFile"))));
} else if (Boolean.parseBoolean(getParameters().getNamed().getOrDefault("debug","false"))){
controller.loadTestConfig();
}
} }
@Override @Override

View File

@ -76,6 +76,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
getLogger().warn("No channels defined in configuration"); getLogger().warn("No channels defined in configuration");
} }
super.init();
//update parameters from meta //update parameters from meta
if (meta().hasValue("pga")) { if (meta().hasValue("pga")) {
getLogger().info("Setting dynamic range to " + meta().getInt("pga")); getLogger().info("Setting dynamic range to " + meta().getInt("pga"));
@ -90,22 +91,27 @@ public class PKT8Device extends PortSensor<PKT8Result> {
setSPS(meta().getInt("sps", 0)); setSPS(meta().getInt("sps", 0));
setBUF(meta().getInt("abuf", 100)); setBUF(meta().getInt("abuf", 100));
super.init(); }
@Override
public void shutdown() throws ControlException {
super.shutdown();
collector.clear();
collector = null;
} }
@Override @Override
protected PortHandler buildHandler(String portName) throws ControlException { protected PortHandler buildHandler(String portName) throws ControlException {
PortHandler handler; PortHandler handler;
//setup connection //setup connection
if (meta().hasNode("debug")) { if ("virtual".equals(portName)) {
handler = new PKT8VirtualPort("PKT8", meta().getNode("debug")); getLogger().info("Starting {} using virtual debug port", getName());
handler = new PKT8VirtualPort("PKT8", meta().getNodeOrEmpty("debug"));
} else { } else {
handler = super.buildHandler(portName); handler = super.buildHandler(portName);
} }
handler.setDelimeter("\n"); handler.setDelimeter("\n");
//clearing PKT queue
handler.send("p");
handler.sendAndWait("p", null, 1000);
return handler; return handler;
} }
@ -115,7 +121,13 @@ public class PKT8Device extends PortSensor<PKT8Result> {
private void setBUF(int buf) throws ControlException { private void setBUF(int buf) throws ControlException {
getLogger().info("Setting avaraging buffer size to " + buf); getLogger().info("Setting avaraging buffer size to " + buf);
String response = getHandler().sendAndWait("b" + buf, null, 400).trim(); String response;
try {
response = getHandler().sendAndWait("b" + buf, null, 400).trim();
} catch (Exception ex) {
response = ex.getMessage();
}
if (response.contains("=")) { if (response.contains("=")) {
updateState(ABUF, Integer.parseInt(response.substring(14))); updateState(ABUF, Integer.parseInt(response.substring(14)));
// getLogger().info("successfully set buffer size to {}", this.abuf); // getLogger().info("successfully set buffer size to {}", this.abuf);
@ -168,11 +180,11 @@ public class PKT8Device extends PortSensor<PKT8Result> {
* '0' : ± 5 В '1' : ± 2,5 В '2' : ± 1,25 В '3' : ± 0,625 В '4' : ± 312.5 мВ * '0' : ± 5 В '1' : ± 2,5 В '2' : ± 1,25 В '3' : ± 0,625 В '4' : ± 312.5 мВ
* '5' : ± 156,25 мВ '6' : ± 78,125 мВ * '5' : ± 156,25 мВ '6' : ± 78,125 мВ
* *
* @param sps * @param pga
* @return * @return
*/ */
private String pgaToStr(int sps) { private String pgaToStr(int pga) {
switch (sps) { switch (pga) {
case 0: case 0:
return "± 5 V"; return "± 5 V";
case 1: case 1:
@ -198,7 +210,12 @@ public class PKT8Device extends PortSensor<PKT8Result> {
private void setSPS(int sps) throws ControlException { private void setSPS(int sps) throws ControlException {
getLogger().info("Setting sampling rate to " + spsToStr(sps)); getLogger().info("Setting sampling rate to " + spsToStr(sps));
String response = getHandler().sendAndWait("v" + sps, null, 400).trim(); String response;
try {
response = getHandler().sendAndWait("v" + sps, null, 400).trim();
} catch (Exception ex) {
response = ex.getMessage();
}
if (response.contains("=")) { if (response.contains("=")) {
updateState(SPS, Integer.parseInt(response.substring(4))); updateState(SPS, Integer.parseInt(response.substring(4)));
// getLogger().info("successfully sampling rate to {}", spsToStr(this.sps)); // getLogger().info("successfully sampling rate to {}", spsToStr(this.sps));
@ -216,7 +233,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
} }
private void setupStorage() { private void setupStorage() {
if (meta().hasNode("storage") && collector != null) { if (meta().hasNode("storage")) {
try { try {
Storage storage = StorageFactory.buildStorage(getContext(), meta().getNode("storage", Meta.empty())); Storage storage = StorageFactory.buildStorage(getContext(), meta().getNode("storage", Meta.empty()));
String suffix = Integer.toString((int) Instant.now().toEpochMilli()); String suffix = Integer.toString((int) Instant.now().toEpochMilli());
@ -253,16 +270,29 @@ public class PKT8Device extends PortSensor<PKT8Result> {
@Override @Override
protected Measurement<PKT8Result> createMeasurement() throws MeasurementException { protected Measurement<PKT8Result> createMeasurement() throws MeasurementException {
try { if (this.getMeasurement() != null) {
return new PKT8Measurement(getHandler()); return this.getMeasurement();
} catch (ControlException e) { } else {
throw new MeasurementException(e); try {
return new PKT8Measurement(getHandler());
} catch (ControlException e) {
throw new MeasurementException(e);
}
} }
} }
@Override @Override
public Measurement<PKT8Result> startMeasurement() throws MeasurementException { public Measurement<PKT8Result> startMeasurement() throws MeasurementException {
setupStorage(); //clearing PKT queue
try {
getHandler().send("p");
getHandler().sendAndWait("p", null, 1000);
} catch (ControlException e) {
// throw new MeasurementException(e);
}
if(collector == null){
setupStorage();
}
return super.startMeasurement(); return super.startMeasurement();
} }
@ -282,7 +312,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
handler.send("s"); handler.send("s");
afterStart(); afterStart();
} catch (PortException ex) { } catch (PortException ex) {
throw new RuntimeException(ex); error("Failed to start measurement", ex);
} }
} }
@ -291,7 +321,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
try { try {
getHandler().send("p"); getHandler().send("p");
if (collector != null) { if (collector != null) {
collector.cancel(); collector.clear();
} }
return true; return true;
} catch (Exception ex) { } catch (Exception ex) {
@ -324,7 +354,7 @@ public class PKT8Device extends PortSensor<PKT8Result> {
} else { } else {
result(new PKT8Result(designation, rawValue, -1)); result(new PKT8Result(designation, rawValue, -1));
} }
setMeasurementState(MeasurementState.OK);
} }
} }
} }
@ -335,40 +365,3 @@ public class PKT8Device extends PortSensor<PKT8Result> {
} }
} }
} }
/*
//setup storage
try {
Storage storage = getPrimaryStorage(measurement);
String suffix = Integer.toString((int) Instant.now().toEpochMilli());
// Building data format
TableFormatBuilder TableFormatBuilder = new TableFormatBuilder()
.addTime("timestamp");
List<String> names = new ArrayList<>();
for (PKT8Channel channel : channels.values()) {
TableFormatBuilder.addNumber(channel.getName());
names.add(channel.getName());
}
this.pointLoader = LoaderFactory.buildPointLoder(storage, "cryotemp_" + suffix, "", "timestamp", TableFormatBuilder.build());
Duration duration = Duration.parse(meta().getString("averagingDuration", "PT30S"));
collector = new RegularPointCollector((dp) -> {
if (pointLoader != null) {
try {
getLogger().debug("Point measurement complete. Pushing...");
pointLoader.push(dp);
} catch (StorageException ex) {
getLogger().error("Error while pushing point to loader", ex);
}
}
}, duration, names);
} catch (StorageException ex) {
getLogger().error("Can't setup storage", ex);
}
*/

View File

@ -15,31 +15,28 @@
*/ */
package inr.numass.cryotemp; package inr.numass.cryotemp;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import de.jensd.shichimifx.utils.SplitPaneDividerSlider;
import hep.dataforge.context.GlobalContext; import hep.dataforge.context.GlobalContext;
import hep.dataforge.control.devices.Device; import hep.dataforge.control.devices.Device;
import hep.dataforge.control.devices.DeviceListener; import hep.dataforge.control.devices.DeviceListener;
import hep.dataforge.control.measurements.Measurement; import hep.dataforge.control.measurements.Measurement;
import hep.dataforge.control.measurements.MeasurementListener; import hep.dataforge.control.measurements.MeasurementListener;
import hep.dataforge.exceptions.ControlException; import hep.dataforge.exceptions.ControlException;
import hep.dataforge.fx.ConsoleFragment;
import hep.dataforge.io.MetaFileReader; import hep.dataforge.io.MetaFileReader;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.meta.MetaUtils; import hep.dataforge.meta.MetaUtils;
import hep.dataforge.plots.PlotUtils;
import hep.dataforge.plots.data.TimePlottable; import hep.dataforge.plots.data.TimePlottable;
import hep.dataforge.plots.data.TimePlottableGroup; import hep.dataforge.plots.data.TimePlottableGroup;
import hep.dataforge.plots.data.XYPlottable;
import hep.dataforge.plots.fx.FXPlotFrame;
import hep.dataforge.plots.fx.PlotContainer;
import hep.dataforge.plots.jfreechart.JFreeChartFrame; import hep.dataforge.plots.jfreechart.JFreeChartFrame;
import hep.dataforge.values.Value; import hep.dataforge.values.Value;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
@ -62,28 +59,24 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
public static final String DEFAULT_CONFIG_LOCATION = "devices.xml"; public static final String DEFAULT_CONFIG_LOCATION = "devices.xml";
private PKT8Device device; private PKT8Device device;
private JFreeChartFrame plotFrame; private FXPlotFrame<XYPlottable> plotFrame;
private TimePlottableGroup plottables; private TimePlottableGroup plottables;
private Meta currentPlotConfig; private Meta currentPlotConfig;
ConsoleFragment consoleFragment;
@FXML @FXML
private Button loadConfigButton; private Button loadConfigButton;
@FXML @FXML
private SplitPane consoleSplitPane;
@FXML
private TextArea logArea;
@FXML
private ToggleButton startStopButton; private ToggleButton startStopButton;
@FXML @FXML
private AnchorPane plotArea; private AnchorPane plotArea;
@FXML @FXML
private ToggleButton consoleButton; private ToggleButton consoleButton;
@Override @Override
public void close() throws Exception { public void close() throws Exception {
if (device != null) { if (device != null) {
device.stopMeasurement(true);
device.shutdown(); device.shutdown();
} }
} }
@ -94,11 +87,8 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
setupPlotFrame(null); setupPlotFrame(null);
SplitPaneDividerSlider slider = new SplitPaneDividerSlider(consoleSplitPane, 0, SplitPaneDividerSlider.Direction.DOWN); this.consoleFragment = new ConsoleFragment();
consoleButton.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> { consoleFragment.bindTo(consoleButton);
slider.setAimContentVisible(newValue);
});
slider.setAimContentVisible(false);
} }
@FXML @FXML
@ -117,7 +107,7 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
} }
} }
private void loadTestConfig() throws ControlException { public void loadTestConfig() throws ControlException {
try { try {
Meta testConfig = MetaFileReader Meta testConfig = MetaFileReader
.read(new File(getClass().getResource("/config/defaultConfig.xml").toURI())); .read(new File(getClass().getResource("/config/defaultConfig.xml").toURI()));
@ -157,16 +147,10 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
private void setupPlotFrame(Meta plotFrameMeta) { private void setupPlotFrame(Meta plotFrameMeta) {
plottables = new TimePlottableGroup(); plottables = new TimePlottableGroup();
plotArea.getChildren().clear(); plotArea.getChildren().clear();
Meta plotConfig; plotFrame = new JFreeChartFrame(plotFrameMeta);
if (plotFrameMeta != null) { PlotUtils.setXAxis(plotFrame, "timestamp", null, "time");
plotConfig = new MetaBuilder(plotFrameMeta) PlotContainer container = PlotContainer.anchorTo(plotArea);
.setValue("xAxis.timeAxis", true); container.setPlot(plotFrame);
} else {
plotConfig = new MetaBuilder("plotFrame")
.setValue("xAxis.timeAxis", true);
}
plotFrame = new JFreeChartFrame(plotConfig);
plotFrame.display(plotArea);
} }
public void setupDevice(Meta deviceMeta) throws ControlException { public void setupDevice(Meta deviceMeta) throws ControlException {
@ -175,27 +159,12 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
device.shutdown(); device.shutdown();
} }
this.device = new PKT8Device("PKT8", GlobalContext.instance(), deviceMeta); this.device = new PKT8Device(deviceMeta.getString("port", "virtual"));
device.configure(deviceMeta);
device.addDeviceListener(this); device.addDeviceListener(this);
device.addMeasurementListener(this); consoleFragment.addLogHandler(device.getLogger());
logArea.appendText("Starting log...\n");
Appender<ILoggingEvent> appender = new AppenderBase<ILoggingEvent>() {
// private final DateTimeFormatter formatter = DateTimeFormatter.ISO_TIME;
@Override
protected void append(ILoggingEvent e) {
logArea.appendText(String.format("%s > (%s) [%s] %s%n",
e.getLoggerName(),
Instant.now().toString(),
e.getLevel(),
e.getFormattedMessage()));
}
};
appender.start();
device.getLogger().addAppender(appender);
device.init(); device.init();
} }
@ -203,18 +172,22 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
@Override @Override
public void notifyDeviceInitialized(Device device) { public void notifyDeviceInitialized(Device device) {
Collection<PKT8Channel> channels = this.device.getChanels(); Collection<PKT8Channel> channels = this.device.getChanels();
for (PKT8Channel channel : channels) {
if (!plottables.hasPlottable(channel.getName())) {
//plot config from device configuration //plot config from device configuration
Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta()); //Do not use view config here, it is applyed separately
channels.stream()
.filter(channel -> !plottables.hasPlottable(channel.getName()))
.forEach(channel -> {
//Do not use view config here, it is applyed separately //plot config from device configuration
TimePlottable plottable = new TimePlottable(channel.getName(), deviceLineMeta); Meta deviceLineMeta = channel.meta().getNode("plot", channel.meta());
plottables.addPlottable(plottable);
plotFrame.add(plottable); //Do not use view config here, it is applyed separately
} TimePlottable plottable = new TimePlottable(channel.getName());
} plottable.configure(deviceLineMeta);
plottables.addPlottable(plottable);
plotFrame.add(plottable);
});
startStopButton.setDisable(false); startStopButton.setDisable(false);
if (currentPlotConfig != null) { if (currentPlotConfig != null) {
@ -259,16 +232,19 @@ public class PKT8MainViewController implements Initializable, DeviceListener, Me
} }
@FXML @FXML
private void onStartStopClick(ActionEvent event) { private void onStartStopClick(ActionEvent event) {
if (device != null) { if (device != null) {
try { try {
if (startStopButton.isSelected()) { if (startStopButton.isSelected()) {
device.startMeasurement(); device.startMeasurement()
.addListener(this);
} else { } else {
//in case device started //in case device started
device.stopMeasurement(false); if (device.isMeasuring()) {
device.getMeasurement().removeListener(this);
device.stopMeasurement(false);
}
} }
} catch (ControlException ex) { } catch (ControlException ex) {

View File

@ -6,7 +6,6 @@
package inr.numass.cryotemp; package inr.numass.cryotemp;
import hep.dataforge.control.ports.VirtualPort; import hep.dataforge.control.ports.VirtualPort;
import hep.dataforge.exceptions.PortException;
import hep.dataforge.meta.Annotated; import hep.dataforge.meta.Annotated;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.meta.MetaUtils; import hep.dataforge.meta.MetaUtils;
@ -21,18 +20,10 @@ import java.util.Random;
*/ */
public class PKT8VirtualPort extends VirtualPort implements Annotated { public class PKT8VirtualPort extends VirtualPort implements Annotated {
private final Meta meta;
private final Random generator = new Random(); private final Random generator = new Random();
private final String id;
public PKT8VirtualPort(String portName, Meta meta) { public PKT8VirtualPort(String portName, Meta meta) {
id = portName; super.configure(meta).configureValue("id", portName);
this.meta = meta;
}
@Override
public Meta meta() {
return meta;
} }
@Override @Override
@ -70,24 +61,10 @@ public class PKT8VirtualPort extends VirtualPort implements Annotated {
} }
} }
@Override
public void open() throws PortException {
}
@Override
public boolean isOpen() {
return true;
}
@Override
public String getPortId() {
return id;
}
@Override @Override
public void close() throws Exception { public void close() throws Exception {
cancelByTag("measurement"); cancelByTag("measurement");
super.close();
} }
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<device> <device>
<storage path="D:\\temp\\cryo"/> <storage path="D:\\temp\\cryo"/>
<connection ip="192.168.111.137" port="4001"/> <!--<connection ip="192.168.111.137" port="4001"/>-->
<abuf>120</abuf> <abuf>120</abuf>
<channel designation="a" name="a-channel" r0="1000" transformationType="hyperbolic" coefs="[1.0,1.0]" <channel designation="a" name="a-channel" r0="1000" transformationType="hyperbolic" coefs="[1.0,1.0]"
color="black"/> color="black"/>

View File

@ -16,34 +16,22 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" prefHeight="400.0" prefWidth="600.0" <?import javafx.scene.layout.BorderPane?>
xmlns="http://javafx.com/javafx/8" fx:controller="inr.numass.cryotemp.PKT8MainViewController"> <BorderPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inr.numass.cryotemp.PKT8MainViewController">
<children> <center>
<SplitPane fx:id="consoleSplitPane" dividerPositions="0.8" layoutX="184.0" layoutY="62.0" orientation="VERTICAL" <AnchorPane fx:id="plotArea" />
prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" </center>
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0"> <top>
<ToolBar BorderPane.alignment="CENTER">
<items> <items>
<AnchorPane fx:id="plotArea" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0"/> <ToggleButton fx:id="startStopButton" disable="true" mnemonicParsing="false" onAction="#onStartStopClick" prefWidth="50.0" text="Start" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="94.0" prefWidth="598.0"> <Separator orientation="VERTICAL" />
<children> <Button fx:id="loadConfigButton" mnemonicParsing="false" onAction="#onLoadConfigClick" text="Load config" />
<TextArea fx:id="logArea" editable="false" layoutX="38.0" layoutY="-75.0" prefHeight="200.0" <ToggleButton fx:id="consoleButton" contentDisplay="CENTER" mnemonicParsing="false" text="Console" />
prefWidth="200.0" wrapText="true" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
</children>
</AnchorPane>
</items>
</SplitPane>
<ToolBar prefHeight="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<ToggleButton fx:id="startStopButton" disable="true" mnemonicParsing="false"
onAction="#onStartStopClick" prefWidth="50.0" text="Start"/>
<Separator orientation="VERTICAL"/>
<Button fx:id="loadConfigButton" mnemonicParsing="false" onAction="#onLoadConfigClick"
text="Load config"/>
<ToggleButton fx:id="consoleButton" contentDisplay="CENTER" mnemonicParsing="false" text="Console"/>
</items> </items>
</ToolBar> </ToolBar>
</children> </top>
</AnchorPane> </BorderPane>