Thank you for your help. I've been trying to create a ribbon responsive layout like the one in Word, where the items resize one after another, and so far I haven't had much luck with it.
custom_control.fxml
<fx:root type="javafx.scene.layout.VBox" fx:id="dis" minHeight="-1.0" minWidth="-1.0" prefWidth="350.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<GridPane fx:id="grid">
<children>
<Button text="Button" GridPane.columnIndex="0" GridPane.rowIndex="0" />
<RadioButton text="RadioButton" GridPane.columnIndex="1" GridPane.rowIndex="0" />
<Button onAction="#doSomething" text="Click Me" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<ComboBox GridPane.columnIndex="0" GridPane.rowIndex="1" />
<Slider GridPane.columnIndex="0" GridPane.rowIndex="2" />
<CheckBox text="CheckBox" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="textField" prefWidth="200.0" GridPane.columnIndex="0" GridPane.rowIndex="3" />
<MenuButton fx:id="mb" mnemonicParsing="false" text="" GridPane.columnIndex="1" GridPane.rowIndex="3">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
<MenuItem mnemonicParsing="false" text="Action 2" />
</items>
</MenuButton>
</children>
<columnConstraints>
<ColumnConstraints hgrow="NEVER" maxWidth="+Infinity" minWidth="10.0" percentWidth="60.0" prefWidth="100.0" />
<ColumnConstraints hgrow="NEVER" maxWidth="+Infinity" minWidth="10.0" percentWidth="40.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</fx:root>
CustomController.java
public class CustomController extends VBox {
/**
* Initializes the controller class.
*/
#FXML private TextField textField;
#FXML private VBox dis;
#FXML private GridPane grid;
//dis.prefWidthProperty().bind(grid.widthProperty());
public CustomController() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("custom_control.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public String getText() {
return textProperty().get();
}
public void setText(String value) {
textProperty().set(value);
}
public StringProperty textProperty() {
return textField.textProperty();
}
public void adaptWidth(double width) {
/*textField.textProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("textfield changed from " + oldValue + " to " + newValue);
});*/
}
#FXML
protected void doSomething() {
System.out.println("The button was clicked!");
}
}
**RibbonJavaFX.java**
public class RibbonJavaFX extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
HBox start = new HBox();
CustomController rib1= new CustomController();
rib1.setText("Ribbon 1");
CustomController rib2 = new CustomController();
rib2.setText("Ribbon 2");
CustomController rib3 = new CustomController();
rib3.setText("Ribbon 3");
start.getChildren().add(rib1);
start.getChildren().add(rib2);
start.getChildren().add(rib3);
rib3.prefWidthProperty().bind(rib2.widthProperty());
rib2.prefWidthProperty().bind(rib1.widthProperty());
Scene scene = new Scene(start,1800,400);
stage.setScene(scene);
//scene.getStylesheets().add(getClass().getResource("custom_control.css").toExternalForm());
stage.setTitle("Custom Control");
stage.setWidth(300);
stage.setHeight(200);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
So this is how my work looks so far. I've been trying to bind the 3 controllers together, but since it has to be made dynamic and for future use, because all controllers are the same, so they have to adapt to each other. My goal is to make them resize one after another, like the Word toolbar. Can somebody please help me with this? I don't expect a full answer, a hint is maybe all I need.
Updated answer!
This answer uses a SplitPane and an HBox to accomplish the task. It grows the approapitate StackPane depending the position of the SplitPane's divider and the direction the divider is moving. You should be able to make a custom control using these ideas.
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author blj0011
*/
public class JavaFXApplication232 extends Application
{
#Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}
Controller
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicBoolean;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
/**
*
* #author blj0011
*/
public class FXMLDocumentController implements Initializable
{
#FXML
HBox hBox;
#FXML
SplitPane splitPane;
#FXML
AnchorPane anchorPane2;
#FXML
StackPane sp1, sp2, sp3, sp4;
double orgX, orgY;
double PANE_MIN_WIDTH = 0;
double PANE_STARTING_WIDTH = 200;
double PANES_TOTAL_WIDTH = 800;
AtomicBoolean initialMove = new AtomicBoolean(true);
#Override
public void initialize(URL url, ResourceBundle rb)
{
SplitPane.Divider divider = splitPane.getDividers().get(0);
divider.positionProperty().addListener((obs, oldValue, newValue) -> {
//System.out.println("oldValue: " + oldValue.doubleValue() + " newValue: " + newValue);
//System.out.println(anchorPane2.getWidth() + " :: " + (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH));
if (newValue.doubleValue() > oldValue.doubleValue() && !initialMove.get()) {
if (anchorPane2.getWidth() <= PANES_TOTAL_WIDTH && anchorPane2.getWidth() > PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH) {
sp1.setMinWidth(PANE_MIN_WIDTH);
sp1.setMaxWidth(anchorPane2.getWidth() - (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH));
}
else if (anchorPane2.getWidth() <= (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH) && anchorPane2.getWidth() > (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH)) {
sp2.setMinWidth(PANE_MIN_WIDTH);
sp2.setMaxWidth(anchorPane2.getWidth() - (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH));
}
else if (anchorPane2.getWidth() <= (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH) && anchorPane2.getWidth() > (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH)) {
sp3.setMinWidth(PANE_MIN_WIDTH);
sp3.setMaxWidth(anchorPane2.getWidth() - (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH));
}
}
else if (newValue.doubleValue() < oldValue.doubleValue()) {
if (anchorPane2.getWidth() < (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH)) {
sp4.setMaxWidth(PANE_STARTING_WIDTH);
sp4.setMinWidth(anchorPane2.getWidth());
}
else if (anchorPane2.getWidth() < (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH) && anchorPane2.getWidth() >= (PANES_TOTAL_WIDTH - 3 * PANE_STARTING_WIDTH)) {
sp3.setMaxWidth(PANE_STARTING_WIDTH);
sp3.setMinWidth(anchorPane2.getWidth() - PANE_STARTING_WIDTH);
}
else if (anchorPane2.getWidth() < (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH) && anchorPane2.getWidth() >= (PANES_TOTAL_WIDTH - 2 * PANE_STARTING_WIDTH)) {
sp2.setMaxWidth(PANE_STARTING_WIDTH);
sp2.setMinWidth(anchorPane2.getWidth() - 2 * PANE_STARTING_WIDTH);
}
else if (anchorPane2.getWidth() <= PANES_TOTAL_WIDTH && anchorPane2.getWidth() >= (PANES_TOTAL_WIDTH - PANE_STARTING_WIDTH)) {
sp1.setMaxWidth(PANE_STARTING_WIDTH);
sp1.setMinWidth(anchorPane2.getWidth() - 3 * PANE_STARTING_WIDTH);
}
}
initialMove.set(false);//Used becase of the first pass, the AnchorPane's width = 0
});
}
}
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<SplitPane fx:id="splitPane" dividerPositions="0.0" prefHeight="160.0" prefWidth="808.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication232.FXMLDocumentController">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" />
<AnchorPane fx:id="anchorPane2" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="800.0">
<children>
<HBox fx:id="hBox" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="203.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<StackPane fx:id="sp1" maxWidth="200.0" minWidth="0.0" prefWidth="200.0" style="-fx-background-color: green;" />
<StackPane fx:id="sp2" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" style="-fx-background-color: blue;" />
<StackPane fx:id="sp3" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" style="-fx-background-color: yellow;" />
<StackPane fx:id="sp4" maxWidth="200.0" minWidth="200.0" prefWidth="200.0" style="-fx-background-color: brown;" />
</children>
</HBox>
</children>
</AnchorPane>
</items>
</SplitPane>
Related
I'm new in Java. I am writing a JavaFXML application in Netbeans IDE 8.2 that includes a class for connecting to a Derby database (DatabaseHandler.java) that first create a database for me. But when i run the program, this database is not created in my project. Does any code is required to added or modified? Here is my codes. Please help me.
my program has 2 packages: -library.assistant.database -library.assistant.ui.addbook
Codes for FXMLDocumentCntroller.java
package library.assistant.ui.addbook;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import library.assistant.database.DatabaseHandler;
/**
* FXML Controller class
*
* #author pc
*/
public class FXMLDocumentController implements Initializable {
#FXML
private JFXTextField title;
#FXML
private JFXTextField id;
#FXML
private JFXTextField author;
#FXML
private JFXTextField publisher;
#FXML
private JFXButton saveButton;
#FXML
private JFXButton cancelButton;
DatabaseHandler databaseHandler;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
databaseHandler = new DatabaseHandler();
}
#FXML
private void addBook(ActionEvent event) {
}
#FXML
private void cancel(ActionEvent event) {
}
}
Codes for DatabaseHandler.java
package library.assistant.database;
private static DatabaseHandler handler;
private static final String DB_URL = "jdbc:derby:database;create=true";
private static Connection conn = null;
private static Statement stmt = null;
public DatabaseHandler() {
createConnection();
setupBookTable();
}
void createConnection() {
try {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
conn = DriverManager.getConnection(DB_URL);
} catch (Exception e) {
e.printStackTrace();
}
}
void setupBookTable() {
String Table_Name = "Book";
try {
stmt = conn.createStatement();
DatabaseMetaData dbm = conn.getMetaData();
ResultSet tables = dbm.getTables(null, null, Table_Name.toUpperCase(), null);
if (tables.next()) {
System.out.println("table" + Table_Name + "already exists. Ready for go!");
} else {
stmt.execute("CREATE TABLE " + Table_Name + "("
+ " id varchar(200) primary key,\n"
+ " title varchar(200),\n"
+ " author varchar(200),\n"
+ " publisher varchar(100),\n"
+ " isAvailable boolaen default true"
+ " )");
}
} catch (SQLException e) {
System.err.println(e.getMessage() + " ... setupDatabase");
} finally {
}
}
}
Codes for LibraryAssistant.java
package library.assistant.ui.addbook;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author pc
*/
public class LibraryAssistant extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Here is my fxml file
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane id="AnchorPane" prefHeight="255.0" prefWidth="368.0"
xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="library.assistant.ui.addbook.FXMLDocumentController">
<children>
<VBox prefHeight="363.0" prefWidth="368.0" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<children>
<JFXTextField fx:id="title" labelFloat="true" promptText="Book Title">
<VBox.margin>
<Insets left="10.0" right="10.0" top="20.0" />
</VBox.margin>
</JFXTextField>
<JFXTextField fx:id="id" labelFloat="true" layoutX="20.0"
layoutY="30.0" promptText="Book ID">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0" />
</VBox.margin>
</JFXTextField>
<JFXTextField fx:id="author" labelFloat="true" layoutX="20.0"
layoutY="30.0" promptText="Book Author">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</JFXTextField>
<JFXTextField fx:id="publisher" labelFloat="true" layoutX="10.0"
layoutY="55.0" promptText="Publisher">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</JFXTextField>
<HBox prefHeight="58.0" prefWidth="368.0">
<children>
<JFXButton fx:id="saveButton" onAction="#addBook"
prefHeight="58.0" prefWidth="200.0" stylesheets="#addbook.css" text="Save"
/>
<JFXButton fx:id="cancelButton" layoutX="10.0" layoutY="10.0"
onAction="#cancel" prefHeight="58.0" prefWidth="200.0"
stylesheets="#addbook.css" text="Cancel" />
</children>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
I have this fxml layout. When I click on take photo it opens a screen for me to take a picture using web cam
Dialog layout to take pic from web cam
I want the picture captured on the web cam to replace the dummy image on the fxml layout beside take photo button.Here are my files:
FXML layout containing dummy image and take photo button
<HBox prefHeight="79.0" prefWidth="232.0" spacing="30.0">
<children>
<VBox prefHeight="100.0" prefWidth="100.0">
<children>
<ImageView fx:id="profilePic" fitHeight="99.0" fitWidth="118.0" nodeOrientation="INHERIT" pickOnBounds="true">
<image>
<Image url="#../images/profile_photo.png" />
</image>
</ImageView>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Button mnemonicParsing="false" onAction="#takePhoto" text="Take Photo">
<font>
<Font size="13.0" />
</font>
<VBox.margin>
<Insets bottom="20.0" top="10.0" />
</VBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#pickPhoto" prefHeight="31.0" prefWidth="85.0" text="Upload
">
<font>
<Font size="13.0" />
</font>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin></Button>
</children>
</VBox>
</children>
</HBox>
Controller for the FXML Layout
public class AddParentController implements Initializable {
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void doAll(){
ImageSelection.getImageSelectionInstance().imageProperty()
.addListener((obs, oldImage, newImage) -> profilePic.setImage(newImage));
}
public void takePhoto(){
try {
Stage dialogStage = new Stage(StageStyle.UNDECORATED);
BorderPane root = FXMLLoader.load(getClass().getResource("../views/WebCamPreview.fxml"));
Scene scene = new Scene(root, 850, 390);
dialogStage.setUserData("fromAddParent");
dialogStage.initModality(Modality.APPLICATION_MODAL);
dialogStage.setScene(scene);
dialogStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Dialog Layout containing WebCam Preview
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<BorderPane prefHeight="390.0" prefWidth="850.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.controllers.WebCamPreviewController">
<!-- TODO Add Nodes -->
<bottom>
<FlowPane fx:id="fpBottomPane" alignment="CENTER" columnHalignment="CENTER" hgap="50.0" prefHeight="80.0" prefWidth="200.0" style="-fx-background-color:#ccc;">
<children>
<Button fx:id="btnStartCamera" focusTraversable="false" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#stopCamera" prefHeight="40.0" prefWidth="120.0" text="Capture">
<font>
<Font name="Segoe UI" size="18.0" fx:id="x1" />
</font>
</Button>
<Button fx:id="btnProceedCamera" focusTraversable="false" font="$x1" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#proceed" prefHeight="40.0" prefWidth="120.0" text="Proceed" />
<Button fx:id="btnResetCamera" focusTraversable="false" font="$x1" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#startCamera" prefHeight="40.0" prefWidth="120.0" text="Reset" />
<Button fx:id="btnDisposeCamera" focusTraversable="false" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#disposeCamera" prefHeight="40.0" prefWidth="120.0" text="Close">
<font>
<Font name="Segoe UI" size="18.0" fx:id="x11" />
</font>
</Button>
</children>
</FlowPane>
</bottom>
<center>
<BorderPane fx:id="bpWebCamPaneHolder" prefHeight="200.0" prefWidth="200.0">
<center>
<ImageView fx:id="imgWebCamCapturedImage" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
</center></BorderPane>
</center>
<top>
<GridPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="80.0" style="-fx-background-color:#ccc;
">
<children>
<Label text="Webcam Image Capture" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" GridPane.rowSpan="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<font>
<Font name="Segoe UI" size="34.0" />
</font>
<GridPane.margin>
<Insets top="10.0" />
</GridPane.margin>
</Label>
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="795.0" minWidth="10.0" prefWidth="418.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="502.0" minWidth="10.0" prefWidth="482.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</top>
</BorderPane>
WebCam Preview Controller
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import com.github.sarxos.webcam.WebcamPanel;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import com.github.sarxos.webcam.Webcam;
import javafx.stage.Stage;
public class WebCamPreviewController implements Initializable {
#FXML Button btnStartCamera;
#FXML Button btnProceedCamera;
#FXML Button btnDisposeCamera,btnResetCamera;
#FXML BorderPane bpWebCamPaneHolder;
#FXML FlowPane fpBottomPane;
#FXML ImageView imgWebCamCapturedImage;
private BufferedImage grabbedImage;
private WebcamPanel selWebCamPanel = null;
private Webcam selWebCam = null;
private boolean stopCamera = false;
private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<Image>();
Image mainiamge;
private String userData;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
fpBottomPane.setDisable(true);
try{
initializeWebCam(0);
}catch(Exception e){
e.printStackTrace();
}
Platform.runLater(() -> {
userData = (String) fpBottomPane.getScene().getWindow().getUserData();
setImageViewSize();
});
}
protected void setImageViewSize() {
double height = bpWebCamPaneHolder.getHeight();
double width = bpWebCamPaneHolder.getWidth();
imgWebCamCapturedImage.setFitHeight(height);
imgWebCamCapturedImage.setFitWidth(width);
imgWebCamCapturedImage.prefHeight(height);
imgWebCamCapturedImage.prefWidth(width);
imgWebCamCapturedImage.setPreserveRatio(true);
}
protected void initializeWebCam(final int webCamIndex) {
Task<Void> webCamIntilizer = new Task<Void>() {
#Override
protected Void call() throws Exception {
if(selWebCam == null)
{
selWebCam = Webcam.getWebcams().get(webCamIndex);
selWebCam.open();
}else
{
closeCamera();
selWebCam = Webcam.getWebcams().get(webCamIndex);
selWebCam.open();
}
startWebCamStream();
return null;
}
};
new Thread(webCamIntilizer).start();
fpBottomPane.setDisable(false);
btnProceedCamera.setDisable(true);
btnResetCamera.setDisable(true);
}
protected void startWebCamStream() {
stopCamera = false;
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
while (!stopCamera) {
try {
if ((grabbedImage = selWebCam.getImage()) != null) {
Platform.runLater(new Runnable() {
#Override
public void run() {
mainiamge = SwingFXUtils
.toFXImage(grabbedImage, null);
imageProperty.set(mainiamge);
}
});
grabbedImage.flush();
}
} catch (Exception e) {
} finally {
}
}
return null;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
imgWebCamCapturedImage.imageProperty().bind(imageProperty);
}
private void closeStage() {
((Stage) fpBottomPane.getScene().getWindow()).close();
}
private void closeCamera()
{
if(selWebCam != null)
{
selWebCam.close();
}
}
public void proceed(){
ImageSelection.getImageSelectionInstance().setImage(imgWebCamCapturedImage.getImage());
AddParentController apc = new AddParentController();
apc.doAll();
closeStage();
}
public void proceedToAddPartner(){
}
public void stopCamera(ActionEvent event)
{
stopCamera = true;
btnStartCamera.setDisable(true);
btnResetCamera.setDisable(false);
btnProceedCamera.setDisable(false);
}
public void startCamera(ActionEvent event)
{
stopCamera = false;
startWebCamStream();
btnStartCamera.setDisable(false);
btnResetCamera.setDisable(true);
btnProceedCamera.setDisable(true);
}
public void disposeCamera(ActionEvent event)
{
//stopCamera = true;
//closeCamera();
//Webcam.shutdown();
//btnStopCamera.setDisable(true);
//btnStartCamera.setDisable(true);
closeStage();
}
}
Image Model
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.image.Image;
public class ImageSelection {
private final ObjectProperty<Image> image = new SimpleObjectProperty<>();
private static ImageSelection imageSelectionInstance= new ImageSelection();
private ImageSelection(){}
public static ImageSelection getImageSelectionInstance() {
return imageSelectionInstance;
}
public ObjectProperty<Image> imageProperty() {
return image ;
}
public final void setImage(Image image) {
imageProperty().set(image);
}
public final Image getImage()
{
return imageProperty().get();
}
}
The challenge is to make the Image captured by the web cam to display in profilPic ImageView on the AddParent FXML Layout.
I've just recently dipped into UI based applications and I'm having trouble getting the generated GridPane to not expand with the window. Ideally, I'd like to be able to hit the small button, have it generate a static grid, and then resize the root stage/scene to compensate for different dungeon sizes. The code below only implements the small button and then draws the grid under it.
This is a screenshot after I hit the small button.(and after I manually resized the window)
Controller Class
package Window;
import Data.Area;
import Model.Grid;
import Model.TileSet;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class Controller {
public GridPane gridmane;
public void genSmall(ActionEvent actionEvent) throws IOException {
Grid grid = new Grid(new Area(40, 40));
grid.getPathfinder().shufflePartitions();
grid.getPathfinder().fillPartitions();
grid.getPathfinder().generateHallways();
importGrid(gridmane, grid);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setOpacity(1);
stage.setTitle("My New Stage Title");
stage.setScene(new Scene(gridmane, 340, 400));
stage.show();
}
private void importGrid(GridPane gridPane, Grid grid) {
for (int i = 0; i < grid.getSize().height; i++) {
for (int j = 0; j < grid.getSize().width; j++) {
if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
changeSquare(gridPane, i, j, Color.WHITE);
} else {
changeSquare(gridPane, i, j, Color.GRAY);
}
}
}
}
private void changeSquare(GridPane gridPane, int xCoordinate, int yCoordinate, Color color) {
Rectangle rect = new Rectangle();
rect.setStroke(Color.BLACK);
rect.setFill(color);
rect.setWidth(10);
rect.setHeight(10);
gridPane.add(rect, xCoordinate, yCoordinate);
}
}
Main Class
package Window;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
Stage stage = new Stage();
int val = 40;
#Override
public void start(Stage primaryStage) throws Exception {
this.stage = primaryStage;
setVal(val);
}
public static void main(String[] args) {
launch(args);
}
public void setVal(int i) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("/view.fxml"));
stage.setTitle("Dungeon Generator");
stage.setScene(new Scene(root, 450, 450));
//primaryStage.setResizable(false);
stage.sizeToScene();
stage.show();
}
}
FXML File
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="332.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Window.Controller">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Button alignment="CENTER" mnemonicParsing="false" onAction="#genSmall" prefHeight="27.0" prefWidth="64.0" text="Small" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</Button>
<Button alignment="CENTER" mnemonicParsing="false" text="Medium" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</Button>
<Button alignment="CENTER" mnemonicParsing="false" prefHeight="27.0" prefWidth="66.0" text="Large" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
</Button>
</children>
</HBox>
<GridPane fx:id="gridmane" VBox.vgrow="NEVER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</children>
</VBox>
You need to get rid of those constraints of your GridPane rows/columns. For centering you could wrap the grid in a StackPane and prevent it's size from growing by using Region.USE_PREF_SIZE (=-Infinity) as max size constraints.
<StackPane VBox.vgrow="ALWAYS" >
<children>
<GridPane fx:id="gridmane" VBox.vgrow="NEVER" maxWidth="-Infinity" maxHeight="-Infinity" />
</children>
</StackPane>
public void genSmall(ActionEvent actionEvent) throws IOException {
Grid grid = new Grid(new Area(40, 40));
grid.getPathfinder().shufflePartitions();
grid.getPathfinder().fillPartitions();
grid.getPathfinder().generateHallways();
importGrid(gridmane, grid);
gridmane.getScene().getWindow().sizeToScene(); // resize window
}
private void importGrid(GridPane gridPane, Grid grid) {
gridPane.getChildren().clear(); // remove old children
for (int i = 0; i < grid.getSize().height; i++) {
for (int j = 0; j < grid.getSize().width; j++) {
if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
changeSquare(gridPane, i, j, Color.WHITE);
} else {
changeSquare(gridPane, i, j, Color.GRAY);
}
}
}
}
I'm building a DialogPane in FXML and I'm trying to figure out how to respond to button presses on the dialog since onAction is not a valid parameter for ButtonType. I've attached my FXML and Controller Class. There is very little documentation about DialogPane and even less about doing it in FXML so I'm not sure how to proceed.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ButtonType?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<DialogPane fx:id="loginPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="LoginController">
<content>
<GridPane hgap="5.0" vgap="5.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="300.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Driver Name" />
<TextField fx:id="driverTxt" GridPane.columnIndex="1" />
<Label text="URL" GridPane.rowIndex="1" />
<TextField fx:id="urlTxt" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Username" GridPane.rowIndex="2" />
<TextField fx:id="userTxt" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="Password" GridPane.rowIndex="3" />
<TextField fx:id="passTxt" GridPane.columnIndex="1" GridPane.rowIndex="3" />
</children>
</GridPane>
</content>
<buttonTypes>
<ButtonType fx:id="loginButton" text="Login" />
<ButtonType fx:id="cancelBtn" text="Cancel" />
</buttonTypes>
</DialogPane>
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.DialogPane;
import javafx.scene.control.TextField;
public class LoginController {
#FXML
DialogPane loginPane;
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
#FXML
ButtonType loginButton;
#FXML
private void loginButtonAction(){
// How do I do something here
}
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
}
Typically you wouldn't need to do this. You would usually show a DialogPane in a Dialog<ButtonType> calling its showAndWait() method, which returns an Optional<ButtonType> representing the button pressed (if any). So normal usage would be something like
public class LoginController {
public static final ButtonType LOGIN = new ButtonType("Login");
#FXML
DialogPane loginPane;
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
public String getDriver() {
return driverTxt.getText();
}
public String getUrl() {
return urlTxt.getText();
}
public String getUser() {
return userTxt.getText();
}
public String getPass() {
return pass.getText();
}
}
and make the following changes to your FXML file:
<buttonTypes>
<LoginController fx:constant="LOGIN" />
<ButtonType fx:constant="CANCEL" />
</buttonTypes>
Then you would use this with:
Dialog<ButtonType> dialog = new Dialog<>();
FXMLLoader dialogLoader = new FXMLLoader(getClass().getResource("Login.fxml"));
dialog.setDialogPane(dialogLoader.load());
LoginController controller = dialogLoader.getController();
dialog.showAndWait().filter(LoginController.LOGIN::equals)
.ifPresent(button -> {
String driver = controller.getDriver();
// etc etc
// process login...
});
As an alternative to exposing the text from the text fields, you could define a processLogin() method in the controller itself that read the text fields and did whatever you need to do:
public class LoginController {
public static final ButtonType LOGIN = new ButtonType("Login");
#FXML
DialogPane loginPane;
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
public void processLogin() {
String driver = driverTxt.getText();
// etc...
// process login...
}
}
then just do
// ...
dialog.showAndWait().filter(LoginController.LOGIN::equals)
.ifPresent(button -> controller.processLogin());
If you really need to register an onAction handler with the login button, do it in the initialize() method in the controller:
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
Button login = (Button) loginPane.lookupButton(loginButton);
login.setOnAction(e -> { /* ... */ });
}
but this is really against the intended use of the dialog pane API.
One final alternative would be to override the createButton method in DialogPane. To do this, you'd need a subclass of DialogPane, which would mean using the FXML custom component pattern.
So this would look something like:
public class LoginPane extends DialogPane {
public static final ButtonType LOGIN = new ButtonType("Login");
#FXML
TextField driverTxt;
#FXML
TextField urlTxt;
#FXML
TextField userTxt;
#FXML
TextField passTxt;
public LoginPane() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("LoginPane.fxml"));
loader.setRoot(this);
loader.setController(this);
loader.load();
} catch (IOException exc) {
// bad if you get here...
throw new UncheckedIOException(exc);
}
}
#Override
public Node createButton(ButtonType buttonType) {
Node button = super.createButton(buttonType);
if (buttonType == LOGIN) {
((Button) button).setOnAction(e -> processLogin());
}
return button ;
}
public void initialize() {
driverTxt.setText("org.postgresql.Driver");
urlTxt.setText("jdbc:postgresql://localhost/postgres");
userTxt.setText("postgres");
passTxt.setText("postgres");
}
public void processLogin() {
String driver = driverTxt.getText();
// etc...
// process login...
}
}
and the FXML would then look like
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ButtonType?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<fx:root type="DialogPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<content>
<GridPane hgap="5.0" vgap="5.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="300.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Driver Name" />
<TextField fx:id="driverTxt" GridPane.columnIndex="1" />
<Label text="URL" GridPane.rowIndex="1" />
<TextField fx:id="urlTxt" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Label text="Username" GridPane.rowIndex="2" />
<TextField fx:id="userTxt" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Label text="Password" GridPane.rowIndex="3" />
<TextField fx:id="passTxt" GridPane.columnIndex="1" GridPane.rowIndex="3" />
</children>
</GridPane>
</content>
<buttonTypes>
<LoginPane fx:constant="LOGIN" />
<ButtonType fx:constant="CANCEL" />
</buttonTypes>
</fx:root>
You would use this version with
Dialog dialog = new Dialog();
dialog.setDialogPane(new LoginPane());
dialog.showAndWait();
so if you are looking to encapsulate as much as possible into the login pane and fxml, this is probably the cleanest option.
Note that the usage of DialogPane is fairly completely documented in the API docs for Dialog and DialogPane.
I am attempting to create a GUI for the front end of a program that will be used in my office. I have been tasked to use Scene Builder 8 to help create said GUI. This is my first project using JavaFX and Scene Builder so I've had to learn everything from scratch. My problem is that the while the code isn't throwing me any errors, I cannot see the sample data that I've put into the program. It's making me question the program as a whole.
If some of the following code looks superfluous to you, it may be because development for the backend part of the program is happening at the same time by a different person.
Here is the Mainapp:
package simit.gui;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import simit.gui.launch.model.LocalLaunch;
import simit.gui.launch.model.TextAreaOutputStream;
import simit.gui.launch.view.CompleteList;
import simit.gui.launch.view.LocalLaunchController;
import simit.gui.launch.view.MonitorController;
public class Main extends Application {
//Hold onto the main state
Stage primaryStage;
private ObservableList<simit.gui.launch.view.CompleteList> listData = FXCollections.observableArrayList();
public Main(){
listData.add(new CompleteList("sample1"));
listData.add(new CompleteList("sample2"));
}
public ObservableList<CompleteList> getListData(){
return listData;
}
//Run simulation
public void runSimulation(File inputDeck, int procs, int mem){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("launch/view/Monitor.fxml"));
AnchorPane rootLayout = (AnchorPane) loader.load();
//Get the controller
MonitorController controller = loader.getController();
//Setup the view
List<TextAreaOutputStream> textAreas = controller.SetUpTextAreas(procs);
//Try to launch the code
LocalLaunch launch = new LocalLaunch(inputDeck, procs, mem, textAreas);
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
// try {
// BorderPane root = new BorderPane();
// Scene scene = new Scene(root,400,400);
// scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
// primaryStage.setScene(scene);
// primaryStage.show();
// } catch(Exception e) {
// e.printStackTrace();
// }
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("launch/view/LocalLaunch.fxml"));
AnchorPane rootLayout = (AnchorPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
//Load up the LocalLaunch Controller
LocalLaunchController controller = loader.getController();
controller.SetMain(this);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Here is the FXML Controller:
package simit.gui.launch.view;
import java.io.File;
import org.controlsfx.control.CheckListView;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.TextField;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import simit.gui.Main;
import simit.gui.launch.model.LocalLaunch;
public class LocalLaunchController {
//Hold onto the required text fields
#FXML
private TextField path;
#FXML
private TextField procs;
#FXML
private TextField mem;
final ObservableList<CompleteList> items = FXCollections.observableArrayList();
#FXML
final public CheckListView<CompleteList> listItems = new CheckListView<CompleteList>();
private Main mainProgram;
public void SetMain(Main mainProgram){
this.mainProgram = mainProgram;
items.addAll(mainProgram.getListData());
listItems.setItems(items);
}
#FXML
private void handleSelect() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("SMT File", "*"+LocalLaunch.PaserExt),
new ExtensionFilter("Resume File", "*"+LocalLaunch.RsmExp),
new ExtensionFilter("All Files", "*.*"));
File selectedFile = fileChooser.showOpenDialog(null);
if (selectedFile != null) {
path.setText(selectedFile.getAbsolutePath());
}
}
#FXML
private void handleRun() {
//Make sure input is valid
if(!isInputValid())
return;
//Get the data
File tmpFile = new File(path.getText());
int proc = Integer.parseInt(procs.getText());
int mem = Integer.parseInt(this.mem.getText());
mainProgram.runSimulation(tmpFile, proc, mem);
}
/**
* Validates the user input in the text fields.
*
* #return true if the input is valid
*/
private boolean isInputValid() {
String errorMessage = "";
if(path.getText().isEmpty()){
errorMessage += "The input deck cannot be empty!\n";
}
//Create a test file
File testFile = new File(path.getText());
if(!testFile.exists())
errorMessage += "The input deck must exisit!\n";
if (procs.getText() == null || procs.getText().length() == 0) {
errorMessage += "No valid procs specified!\n";
} else {
// try to parse the postal code into an int.
try {
int p =Integer.parseInt(procs.getText());
if(p <= 0)
throw new NumberFormatException();
} catch (NumberFormatException e) {
errorMessage += "No valid procs specified (must be a positive integer)!\n";
}
}
if (mem.getText() == null || mem.getText().length() == 0) {
errorMessage += "No valid mem specified!\n";
} else {
// try to parse the postal code into an int.
try {
int p =Integer.parseInt(mem.getText());
if(p <= 0)
throw new NumberFormatException();
} catch (NumberFormatException e) {
errorMessage += "No valid mem specified (must be a positive integer)!\n";
}
}
if (errorMessage.length() == 0) {
return true;
} else {
// Show the error message.
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Invalid Fields");
alert.setHeaderText("Please correct invalid fields");
alert.setContentText(errorMessage);
alert.showAndWait();
return false;
}
}
#FXML
private void initialize() {
}
}
Here is a class I've made for the input variable:
package simit.gui.launch.view;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class CompleteList {
private final StringProperty listDetails;
public CompleteList(){
this(null);
}
public CompleteList(String listDetails){
this.listDetails = new SimpleStringProperty(listDetails);
}
public String getListDetails() {
return listDetails.get();
}
public void setListDetails(String listDetails) {
this.listDetails.set(listDetails);
}
public StringProperty listDetailsProperty(){
return listDetails;
}
}
And finally here is the FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import org.controlsfx.control.*?>
<AnchorPane prefHeight="600.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="simit.gui.launch.view.LocalLaunchController">
<children>
<SplitPane dividerPositions="0.5" layoutX="120.0" layoutY="41.0" orientation="VERTICAL" prefHeight="600.0" prefWidth="400.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<ImageView fitWidth="600.0" pickOnBounds="true" preserveRatio="true" smooth="false">
<image>
<Image url="#../../resources/SIMITBlastLogo.png" />
</image>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</ImageView>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<GridPane layoutX="50.0" layoutY="58.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES" minWidth="10.0" prefWidth="20.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints fillWidth="false" hgrow="SOMETIMES" minWidth="10.0" prefWidth="0.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Input Deck">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<Label text="Processors" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<TextField fx:id="procs" text="1" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="path" editable="false" GridPane.columnIndex="1" />
<Button alignment="CENTER_RIGHT" mnemonicParsing="false" onAction="#handleSelect" text="Select" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets />
</GridPane.margin>
</Button>
<Label text="Mem/Proc" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<Label text="GB" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<TextField fx:id="mem" promptText="1" text="1" GridPane.columnIndex="1" GridPane.rowIndex="2" />
</children>
</GridPane>
<ButtonBar layoutX="129.0" layoutY="248.0" prefHeight="40.0" prefWidth="200.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0">
<buttons>
<Button defaultButton="true" mnemonicParsing="false" onAction="#handleRun" text="Run Simulation" />
</buttons>
</ButtonBar>
<CheckListView fx:id="listItems" layoutX="200.0" layoutY="117.0" prefHeight="200.0" prefWidth="200.0" />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
Here is what I'm seeing when I run the program (minus the image on top, I've gotten rid of it for a little anonymity):
Image of the program when ran.
What I need to see is list items populating that white square in the middle.
Any help anyone can give me at all would be greatly appreciated.