How can I make two TextArea scroll together in JavaFX - javafx

I tried some methods, but I didn’t work. Basically I tried to do it by creating a new TextArea. But I just want the two scrolls to be tied to each other usersChatArea scroll and myChatArea scroll
Is there any easy way to make it so that if I scroll the one with the scrollbar, the other one will automatically follow?
it is my MainChatController:
package ru.geekbrains.chat.client;
import com.sun.javafx.menu.MenuItemBase;
import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;
import java.util.ResourceBundle;
public class MainChatController {
public TextArea usersChatArea = new TextArea();
public TextArea myChatArea = new TextArea();
public ListView onlineUsers;
public TextField inputField;
public Button btnSendMessage;
public Button btnSendMessageUser;
public Button btnOpenAboutWindow;
public void mockAction(ActionEvent actionEvent) {
System.out.println("MOCK!");
}
public void exit(ActionEvent actionEvent) {
Platform.exit();
}
public void showAbout(ActionEvent actionEvent) {
}
public void showHelp(ActionEvent actionEvent) throws URISyntaxException, IOException {
Desktop desktop = Desktop.getDesktop();
desktop.browse(new URI("https://docs.google.com/document/d/1wr0YEtIc5yZtKFu-KITqYnBtp8KC28v2FEYUANL0YAM/edit?usp=sharing"));
}
public void sendMessage(ActionEvent actionEvent) {
appendTextFromTF();
}
public void sendMessageUser(ActionEvent actionEvent) {
appendTextFromTF2();
}
private void appendTextFromTF() {
int c = 1;
String msg1 = inputField.getText();
myChatArea.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
if (msg1.isEmpty()) return;
for (int i = 0; i < c ; i++) {
usersChatArea.appendText(System.lineSeparator());
}
myChatArea.appendText( msg1 + " :ME " + System.lineSeparator());
c++;
inputField.clear();
}
private void appendTextFromTF2() {
int b = 1;
String msg = inputField.getText();
usersChatArea.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
if (msg.isEmpty()) return;
for (int i = 0; i < b ; i++) {
myChatArea.appendText(System.lineSeparator());
}
b++;
usersChatArea.appendText(" User: " + msg + System.lineSeparator());
inputField.clear();
}
public void btnOpenAboutWindow(ActionEvent actionEvent) {
btnOpenAboutWindow.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/about.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.setAlwaysOnTop(true);
stage.setTitle("About");
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
);
}
}
it is my App:
package ru.geekbrains.chat.client;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/scene.fxml"));
Parent root = loader.load();
MainChatController mainChatController = new MainChatController();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setAlwaysOnTop(true);
stage.setTitle("April Chat");
stage.show();
}
}
it is my FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<VBox prefHeight="500" prefWidth="650" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ru.geekbrains.chat.client.MainChatController">
<children>
<MenuBar>
<Menu text="File">
<MenuItem onAction="#mockAction" text="Item1" />
<MenuItem onAction="#mockAction" text="Item2" />
<MenuItem onAction="#mockAction" text="Item3" />
<MenuItem onAction="#mockAction" text="Item4" />
<MenuItem onAction="#exit" text="Exit" />
</Menu>
<Menu text="Edit">
<MenuItem onAction="#mockAction" text="Item1" />
<MenuItem onAction="#mockAction" text="Item2" />
<MenuItem onAction="#mockAction" text="Item3" />
<MenuItem onAction="#mockAction" text="Item4" />
<MenuItem onAction="#mockAction" text="Item5" />
</Menu>
<Menu text="View">
<MenuItem onAction="#mockAction" text="Item1" />
<MenuItem onAction="#mockAction" text="Item2" />
<MenuItem onAction="#mockAction" text="Item3" />
<MenuItem onAction="#mockAction" text="Item4" />
<MenuItem onAction="#mockAction" text="Item5" />
</Menu>
<Menu text="Help">
<MenuItem onAction="#mockAction" text="Item1" />
<MenuItem onAction="#mockAction" text="Item2" />
<MenuItem onAction="#mockAction" text="Item3" />
<MenuItem onAction="#showHelp" text="Help" />
<MenuItem onAction="#showAbout" text="About" />
</Menu>
</MenuBar>
<Button fx:id="btnOpenAboutWindow" onAction="#btnOpenAboutWindow" prefHeight="20.0" prefWidth="50.0" text="ABOUT">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
<font>
<Font size="10.0" />
</font>
</Button>
<HBox prefHeight="471.0" prefWidth="705.0" VBox.vgrow="ALWAYS">
<TextArea fx:id="usersChatArea" editable="false" nodeOrientation="LEFT_TO_RIGHT" prefHeight="461.0" prefWidth="250.0" style="-fx-border-color: white;" styleClass="usersChatArea" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS">
<HBox.margin>
<Insets left="3.0" />
</HBox.margin>
<padding>
<Insets right="3.0" />
</padding>
<font>
<Font size="18.0" />
</font></TextArea>
<TextArea fx:id="myChatArea" editable="false" nodeOrientation="RIGHT_TO_LEFT" prefHeight="461.0" prefWidth="256.0" style="-fx-border-color: white" styleClass="myChatArea" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS">
<font>
<Font size="18.0" />
</font></TextArea>
<ListView fx:id="onlineUsers" prefHeight="461.0" prefWidth="289.0">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</ListView>
<padding>
<Insets bottom="5.0" top="5.0" />
</padding>
</HBox>
<HBox>
<TextField fx:id="inputField" onAction="#sendMessage" prefHeight="70.0" prefWidth="487.0" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
<font>
<Font size="24.0" />
</font>
</TextField>
<Button fx:id="btnSendMessage" onAction="#sendMessage" prefHeight="70.0" prefWidth="124.0" text="SEND">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Button>
<Button fx:id="btnSendMessageUser" onAction="#sendMessageUser" prefHeight="70.0" prefWidth="127.0" text="SEND USER ">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Button>
<padding>
<Insets bottom="5.0" top="5.0" />
</padding>
</HBox>
</children>
</VBox>
it is my Main
package ru.geekbrains.chat.client;
public class Main {
public static void main(String[] args) {
App.main(args);
}
}

A TextArea has these two properties you can use:
DoubleProperty scrollLeftProperty()
The number of pixels by which the
content is horizontally scrolled.
DoubleProperty scrollTopProperty()
The number of pixels by which the
content is vertically scrolled (docs).
Some simple bidirectional bindings as follows may be enough for your needs:
// binding for horizontal scroll bar positions:
textArea1.scrollLeftProperty().bindBidirectional(textArea2.scrollLeftProperty());
// vertical:
textArea1.scrollTopProperty().bindBidirectional(textArea2.scrollTopProperty());

Related

"java.lang.RuntimeException: java.lang.reflect.InvocationTargetException" - unable to figure out where the error is coming from

Getting an error when trying to click the "Add" button in the Parts section of the mainwindow.fxml
Here's the error:
/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=51593:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/lib/tools.jar:/Users/wes/Dropbox/wes-WGU/software-i-c482/javafx/inventory-system-c482-wesley-oneal-2/out/production/InventorySystem-C482-wesley-oneal-2 wesleyoneal.inventoryapp.Main
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 49 more
Caused by: javafx.fxml.LoadException:
/Users/wes/Dropbox/wes-WGU/software-i-c482/javafx/inventory-system-c482-wesley-oneal-2/out/production/InventorySystem-C482-wesley-oneal-2/wesleyoneal/inventoryapp/addpart.fxml:18
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:932)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at wesleyoneal.inventoryapp.mainController.addPartWindow(mainController.java:59)
... 59 more
Caused by: java.lang.InstantiationException: wesleyoneal.inventoryapp.Part
at java.lang.Class.newInstance(Class.java:427)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
... 72 more
Caused by: java.lang.NoSuchMethodException: wesleyoneal.inventoryapp.Part.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 74 more
Process finished with exit code 0
I've looked at line 18 in the addpart.fxml where it says it's having issues, but everything there looks correct from what I can tell
Main.java:
package wesleyoneal.inventoryapp;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("mainwindow.fxml"));
primaryStage.setScene(new Scene(root, 1180, 472));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
mainController:
package wesleyoneal.inventoryapp;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class mainController implements Initializable {
#FXML
private TableView<Part> partsTable;
#FXML
private TableColumn<Part, Integer> partIdColumn;
#FXML
private TableColumn<Part, String> partNameColumn;
#FXML
private TableColumn<Part, Integer> partInvLevel;
#FXML
private TableColumn<Part, Double> partPriceCostColumn;
#Override
public void initialize(URL location, ResourceBundle resources) {
partIdColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
partNameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
partInvLevel.setCellValueFactory(new PropertyValueFactory<>("stock"));
partPriceCostColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
partsTable.setItems(getParts());
}
public ObservableList<Part> getParts() {
ObservableList<Part> partsList = FXCollections.observableArrayList();
partsList.add(new InHousePart(1, "Part A", 1.99, 11, 1, 21, 1111));
partsList.add(new InHousePart(2, "Part B", 2.99, 12, 2, 22, 2222));
partsList.add(new OutsourcedPart(3, "Part C", 3.99, 13, 3, 33,
"Wes' Company"));
partsList.add(new OutsourcedPart(4, "Part D", 4.99, 14, 4, 44,
"Wes' Company"));
return partsList;
}
#FXML
private void addPartWindow(ActionEvent event) throws IOException {
Parent addPartParent = FXMLLoader.load(getClass().getResource("addpart.fxml"));
Scene addPartScene = new Scene(addPartParent);
Stage addPartStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
addPartStage.setScene(addPartScene);
addPartStage.show();
}
}
mainwindow.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<GridPane fx:id="mainGridPane" alignment="center" hgap="10" style="-fx-background-color: lightgrey;" vgap="10.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="wesleyoneal.inventoryapp.mainController">
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints maxWidth="600.0" minWidth="560.0" prefWidth="600.0" />
<ColumnConstraints maxWidth="0.0" minWidth="0.0" prefWidth="0.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
<RowConstraints maxHeight="0.0" minHeight="0.0" prefHeight="0.0" />
</rowConstraints>
<children>
<Label text="Inventory Management System" textFill="#494980">
<font>
<Font name="Helvetica Bold" size="16.0" />
</font>
<GridPane.margin>
<Insets bottom="30.0" left="40.0" top="30.0" />
</GridPane.margin>
</Label>
<Rectangle arcHeight="15.0" arcWidth="15.0" fill="#1f93ff00" height="260.0" stroke="#949494" strokeType="INSIDE" width="520.0" GridPane.rowIndex="1" GridPane.rowSpan="3">
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Rectangle>
<TableView fx:id="partsTable" maxWidth="480.0" prefHeight="140.0" prefWidth="480.0" GridPane.rowIndex="2">
<columns>
<TableColumn fx:id="partIdColumn" maxWidth="120.0" prefWidth="120.0" text="Part ID" />
<TableColumn fx:id="partNameColumn" maxWidth="120.0" prefWidth="120.0" text="Part Name" />
<TableColumn fx:id="partInvLevel" maxWidth="120.0" prefWidth="120.0" text="Inventory Level" />
<TableColumn fx:id="partPriceCostColumn" maxWidth="120.0" prefWidth="120.0" text="Price/Cost per Unit" />
</columns>
<GridPane.margin>
<Insets left="60.0" />
</GridPane.margin>
</TableView>
<ButtonBar maxWidth="480.0" prefHeight="40.0" prefWidth="250.0" GridPane.rowIndex="3">
<buttons>
<Button mnemonicParsing="false" onAction="#addPartWindow" text="Add" />
<Button mnemonicParsing="false" text="Modify" />
<Button mnemonicParsing="false" text="Delete" />
</buttons>
<GridPane.margin>
<Insets bottom="10.0" left="30.0" />
</GridPane.margin>
</ButtonBar>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Parts" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="70.0" top="20.0" />
</GridPane.margin>
<font>
<Font name="Helvetica Bold" size="16.0" />
</font>
</Text>
<Button mnemonicParsing="false" text="Search" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="260.0" top="10.0" />
</GridPane.margin>
</Button>
<TextField maxWidth="200.0" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="340.0" top="11.0" />
</GridPane.margin>
</TextField>
<Rectangle arcHeight="15.0" arcWidth="15.0" fill="#1f93ff00" height="260.0" stroke="#949494" strokeType="INSIDE" width="520.0" GridPane.columnIndex="1" GridPane.rowIndex="1" GridPane.rowSpan="3">
<GridPane.margin>
<Insets left="40.0" />
</GridPane.margin>
</Rectangle>
<TableView fx:id="productsTable" maxWidth="480.0" prefHeight="140.0" prefWidth="480.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<columns>
<TableColumn prefWidth="120.0" text="Part ID" />
<TableColumn prefWidth="120.0" text="Part Name" />
<TableColumn prefWidth="120.0" text="Inventory Level" />
<TableColumn prefWidth="120.0" text="Price per Unit" />
</columns>
<GridPane.margin>
<Insets left="60.0" />
</GridPane.margin>
</TableView>
<ButtonBar maxWidth="480.0" prefHeight="40.0" prefWidth="250.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<buttons>
<Button mnemonicParsing="false" text="Add" />
<Button mnemonicParsing="false" text="Modify" />
<Button mnemonicParsing="false" text="Delete" />
</buttons>
<GridPane.margin>
<Insets bottom="10.0" left="30.0" />
</GridPane.margin>
</ButtonBar>
<Button mnemonicParsing="false" text="Search" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="260.0" top="10.0" />
</GridPane.margin>
</Button>
<TextField maxWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="340.0" top="11.0" />
</GridPane.margin>
</TextField>
<Button mnemonicParsing="false" text="Exit" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="4">
<GridPane.margin>
<Insets right="60.0" top="10.0" />
</GridPane.margin>
</Button>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Products" GridPane.columnIndex="1" GridPane.rowIndex="1">
<font>
<Font name="Helvetica Bold" size="16.0" />
</font>
<GridPane.margin>
<Insets bottom="10.0" left="70.0" top="20.0" />
</GridPane.margin>
</Text>
</children>
</GridPane>
addpart.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Group?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<GridPane fx:id="partGrid" style="-fx-background-color: lightgrey;" xmlns="http://javafx.com/javafx/8.0.171"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="wesleyoneal.inventoryapp.Part">
<columnConstraints>
<ColumnConstraints/>
<ColumnConstraints/>
<ColumnConstraints/>
</columnConstraints>
<rowConstraints>
<RowConstraints/>
<RowConstraints prefHeight="60.0"/>
<RowConstraints prefHeight="60.0"/>
<RowConstraints prefHeight="60.0"/>
<RowConstraints minHeight="10.0" prefHeight="60.0"/>
<RowConstraints minHeight="10.0" prefHeight="60.0"/>
<RowConstraints minHeight="10.0" prefHeight="60.0"/>
<RowConstraints minHeight="10.0"/>
</rowConstraints>
<children>
<Label text="Add Part" textFill="#494980">
<font>
<Font name="Helvetica Bold" size="16.0"/>
</font>
<GridPane.margin>
<Insets bottom="30.0" left="40.0" top="30.0"/>
</GridPane.margin>
</Label>
<Text id="partIdLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="ID" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<Text id="partNameLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Name" GridPane.rowIndex="2">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<Text id="partInvLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Inv" GridPane.rowIndex="3">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<Text id="partPriceCostLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Price/Cost" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<Text id="partMaxLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Max" GridPane.rowIndex="5">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<Text id="partMinLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Min" GridPane.columnIndex="1"
GridPane.columnSpan="2" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="180.0"/>
</GridPane.margin>
</Text>
<Text id="partCompanyNameLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Company Name"
GridPane.rowIndex="6">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<Text id="partMachineIdLabel" strokeType="OUTSIDE" strokeWidth="0.0" text="Machine ID" GridPane.rowIndex="6">
<GridPane.margin>
<Insets bottom="10.0" left="80.0" top="10.0"/>
</GridPane.margin>
</Text>
<ButtonBar prefHeight="40.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.halignment="RIGHT"
GridPane.rowIndex="7">
<buttons>
<Button mnemonicParsing="false" text="Save"/>
<Button mnemonicParsing="false" text="Cancel"/>
</buttons>
<GridPane.margin>
<Insets bottom="20.0" right="30.0"/>
</GridPane.margin>
</ButtonBar>
<Group GridPane.columnIndex="1" GridPane.columnSpan="2">
<children>
<RadioButton fx:id="partInHouseButton" mnemonicParsing="false"
prefWidth="100.0" selected="true" text="In-House">
<toggleGroup>
<ToggleGroup fx:id="addPartToggleGroup"/>
</toggleGroup>
</RadioButton>
<RadioButton fx:id="partOutsourcedButton" layoutX="183.0" mnemonicParsing="false"
prefWidth="100.0" text="Outsourced"
toggleGroup="$addPartToggleGroup"/>
</children>
</Group>
<TextField id="partIdField" editable="false" prefHeight="40.0"
style="-fx-background-color: lightgrey; -fx-border-color: grey;" text="Auto Gen - Disabled"
GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
<TextField id="partNameField" prefHeight="40.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
<TextField id="partInvField" prefHeight="40.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
<TextField id="partPriceCostField" prefHeight="40.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
<TextField id="partMaxField" maxWidth="120.0" prefHeight="40.0" GridPane.columnIndex="1" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
<TextField id="partMinField" maxWidth="120.0" prefHeight="40.0" GridPane.columnIndex="2" GridPane.rowIndex="5">
<GridPane.margin>
<Insets left="40.0" right="40.0"/>
</GridPane.margin>
</TextField>
<TextField id="partCompanyNameField" prefHeight="40.0" GridPane.columnIndex="1" GridPane.rowIndex="6">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
<TextField id="partMachineIdField" prefHeight="40.0" GridPane.columnIndex="1" GridPane.rowIndex="6">
<GridPane.margin>
<Insets left="20.0"/>
</GridPane.margin>
</TextField>
</children>
</GridPane>
Part.java:
package wesleyoneal.inventoryapp;
public abstract class Part {
private int id;
private String name;
private double price;
private int stock;
private int min;
private int max;
public Part(int id, String name, double price, int stock, int min, int max) {
this.id = id;
this.name = name;
this.price = price;
this.stock = stock;
this.min = min;
this.max = max;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
public int getMin() {
return min;
}
public void setMin(int min) {
this.min = min;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
}
InHousePart.java:
package wesleyoneal.inventoryapp;
public class InHousePart extends Part {
private int machineId;
public InHousePart(int id, String name, double price, int stock, int min, int max, int machineId) {
super(id, name, price, stock, min, max);
this.machineId = machineId;
}
public int getMachineId() {
return machineId;
}
public void setMachineId(int machineId) {
this.machineId = machineId;
}
}
Outsourcedpart.java:
package wesleyoneal.inventoryapp;
public class OutsourcedPart extends Part {
private String companyName;
public OutsourcedPart(int id, String name, double price, int stock, int min, int max, String companyName) {
super(id, name, price, stock, min, max);
this.companyName = companyName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
}

JavaFX Complex Neuomorphism Design Causing Lagging of Application

I'm Creating a loading screen for my application which has complex Neumorphism Design using InnerShadow, although CPU and RAM usage is less, the application causes lagging effect for animation like Circular Progress Indicator of Gluon charm-glisten.jar as well as PathTransition animation. In this loading screen you can see a red rectangle moving around the design and the progress indicator in blue color in the innermost layer
Java Code:
package application;
import java.net.URL;
import java.util.*;
import com.gluonhq.charm.glisten.control.ProgressIndicator;
import javafx.animation.*;
import javafx.animation.PathTransition.*;
import javafx.application.*;
import javafx.concurrent.*;
import javafx.event.*;
import javafx.fxml.*;
import javafx.stage.*;
import javafx.util.*;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
public class Main extends Application implements Initializable
{
private double xOffset = 0;
private double yOffset = 0;
#FXML
ProgressIndicator pg1;
static AnchorPane root;
private PathTransition pathTransitionCircle;
public void start(Stage primaryStage)
{
try
{
primaryStage.initStyle(StageStyle.TRANSPARENT);
root = FXMLLoader.load(getClass().getResource("Test1.fxml"));
Scene scene = new Scene(root,600,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
scene.setFill(javafx.scene.paint.Color.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
root.setOnMousePressed(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent e)
{
xOffset = e.getSceneX();
yOffset = e.getSceneY();
}
});
root.setOnMouseDragged(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent e)
{
primaryStage.setX(e.getScreenX() - xOffset);
primaryStage.setY(e.getScreenY() - yOffset);
}
});
Rectangle rect2 = new Rectangle(0, 0, 20, 20);
rect2.setArcHeight(10);
rect2.setArcWidth(10);
rect2.setFill(Color.RED);
root.getChildren().add(rect2);
Path path2 = createEllipsePath(400, 200, 150, 150, 0);
path2.setLayoutX(57);
path2.setLayoutY(10);
root.getChildren().add(path2);
pathTransitionCircle = new PathTransition();
pathTransitionCircle.setDuration(Duration.seconds(6));
pathTransitionCircle.setPath(path2);
pathTransitionCircle.setNode(rect2);
pathTransitionCircle.setOrientation(OrientationType.ORTHOGONAL_TO_TANGENT);
pathTransitionCircle.setCycleCount(PathTransition.INDEFINITE);
pathTransitionCircle.setInterpolator(Interpolator.LINEAR);
pathTransitionCircle.setAutoReverse(false);
pathTransitionCircle.play();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
launch(args);
}
#Override
public void initialize(URL arg0, ResourceBundle arg1)
{
Task<Void> task = new Task<Void>()
{
protected Void call() throws Exception
{
for (int i = 0; i <= 100; i++)
{
updateProgress(i, 100);
Thread.sleep(40);
}
//Platform.runLater(() -> primaryStage.close());
return null;
}
};
pg1.progressProperty().unbind();
pg1.progressProperty().bind(task.progressProperty());
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
task.setOnSucceeded(new EventHandler<WorkerStateEvent>()
{
public void handle(WorkerStateEvent arg0)
{
try
{
/*primaryStage.close();
primaryStage = null;
System.gc();
FXML_Loader f1 = new FXML_Loader();
f1.intermediate();*/
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
private Path createEllipsePath(double centerX, double centerY, double radiusX, double radiusY, double rotate)
{
ArcTo arcTo = new ArcTo();
arcTo.setX(centerX - radiusX + 1); // to simulate a full 360 degree celcius circle.
arcTo.setY(centerY - radiusY);
arcTo.setSweepFlag(false);
arcTo.setLargeArcFlag(true);
arcTo.setRadiusX(radiusX);
arcTo.setRadiusY(radiusY);
arcTo.setXAxisRotation(rotate);
Path path = new Path();
path.getElements().addAll(
new MoveTo(centerX - radiusX, centerY - radiusY),
arcTo,
new ClosePath()); // close 1 px gap.
path.setStroke(Color.BLUE);
path.getStrokeDashArray().setAll(5d, 5d);
return path;
}
}
FXML Code:
<?xml version="1.0" encoding="UTF-8"?>
<?import com.gluonhq.charm.glisten.control.ProgressIndicator?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.effect.InnerShadow?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: transparent;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Main">
<children>
<VBox alignment="CENTER" layoutX="163.5" layoutY="63.5" prefHeight="290.0" prefWidth="290.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;">
<effect>
<InnerShadow color="#00000070" offsetX="-4.0" offsetY="-4.0">
<input>
<InnerShadow color="#a7a7a7bf" offsetX="4.0" offsetY="4.0" />
</input>
</InnerShadow>
</effect>
<children>
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
</VBox.margin>
<effect>
<InnerShadow color="#0000008c" offsetX="4.0" offsetY="4.0">
<input>
<InnerShadow color="#a6a6a65c" offsetX="-4.0" offsetY="-4.0" />
</input>
</InnerShadow>
</effect>
<children>
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
</VBox.margin>
<effect>
<InnerShadow color="#0000008c" offsetX="-4.0" offsetY="-4.0">
<input>
<InnerShadow color="#a6a6a65c" offsetX="4.0" offsetY="4.0" />
</input>
</InnerShadow>
</effect>
<children>
<VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
</VBox.margin>
<effect>
<InnerShadow color="#0000008c" offsetX="4.0" offsetY="4.0">
<input>
<InnerShadow color="#a6a6a65c" />
</input>
</InnerShadow>
</effect>
<children>
<VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
</VBox.margin>
<effect>
<InnerShadow color="#0000008c" offsetX="-4.0" offsetY="-4.0">
<input>
<InnerShadow color="#a6a6a65c" offsetX="4.0" offsetY="4.0" />
</input>
</InnerShadow>
</effect>
<children>
<AnchorPane prefHeight="58.0" prefWidth="141.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
<VBox.margin>
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
</VBox.margin>
<effect>
<InnerShadow color="#0000008c" offsetX="4.0" offsetY="4.0">
<input>
<InnerShadow color="#a6a6a65c" offsetX="-4.0" offsetY="-4.0" />
</input>
</InnerShadow>
</effect>
<children>
<ImageView fitHeight="42.0" fitWidth="50.0" layoutX="49.0" layoutY="40.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#logo/database1.png" />
</image>
</ImageView>
<Label layoutX="57.0" layoutY="81.0" prefHeight="19.0" prefWidth="34.0" text="SQL" textFill="YELLOW">
<font>
<Font name="System Bold Italic" size="14.0" />
</font>
</Label>
<Label layoutX="38.0" layoutY="97.0" prefHeight="20.0" prefWidth="73.0" text="Developer" textFill="YELLOW">
<font>
<Font name="System Bold Italic" size="14.0" />
</font>
</Label>
<ProgressIndicator fx:id="pg1" layoutX="8.0" layoutY="7.0" prefHeight="108.0" prefWidth="122.0" progress="1.0" radius="60.0" />
</children>
</AnchorPane>
</children>
</VBox>
</children>
</VBox>
</children>
</VBox>
</children>
</VBox>
</children>
</VBox>
</children>
</AnchorPane>
Loading Screen Design

textfield not getting resized when used with Tab()

When I am loading TabContent.fxml as root scene, and I am running the application, I see on maximizing the window, the textfield size is regrowing as expected, but when I am creating new tab with Tab() and loading TabContent.fxml, on maximising window textfield size not resizing and it is fixed.
LearnFXML.java
package learnfxml;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class LearnFXML 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();
}
public static void main(String[] args) {
launch(args);
}
}
FXMLDocument.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.input.KeyCodeCombination?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="learnfxml.FXMLDocumentController">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<Menu mnemonicParsing="false" text="New">
<items>
<MenuItem mnemonicParsing="false" text="Generic" />
<MenuItem fx:id="menuItemNewMSDE" onAction="#openNewMSDETab" text="MSDE">
<accelerator>
<KeyCodeCombination alt="UP" code="N" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator>
</MenuItem>
</items>
</Menu>
<MenuItem mnemonicParsing="false" text="Open…" />
<Menu mnemonicParsing="false" text="Open Recent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Close" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Save As…" />
<MenuItem mnemonicParsing="false" text="Revert" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Preferences…" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Quit" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Undo" />
<MenuItem mnemonicParsing="false" text="Redo" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Cut" />
<MenuItem mnemonicParsing="false" text="Copy" />
<MenuItem mnemonicParsing="false" text="Paste" />
<MenuItem mnemonicParsing="false" text="Delete" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Select All" />
<MenuItem mnemonicParsing="false" text="Unselect All" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About MyHelloApp" />
</items>
</Menu>
</menus>
</MenuBar>
<TabPane fx:id="tabPane" prefHeight="377.0" prefWidth="640.0" tabClosingPolicy="ALL_TABS" />
</children>
</VBox>
FXMLDocumentController.java
package learnfxml;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.scene.control.MenuItem;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
public class FXMLDocumentController implements Initializable {
#FXML private MenuItem menuItemNewMSDE;
#FXML private TabPane tabPane ;
final KeyCombination keyShiftTab = new KeyCodeCombination(KeyCode.TAB, KeyCombination.SHIFT_ANY);
#Override
public void initialize(URL url, ResourceBundle rb) {
}
public void openNewMSDETab() throws IOException
{
int numTabs = tabPane.getTabs().size();
Tab tab = new Tab("Tab "+(numTabs+1));
tabPane.getTabs().add(tab);
tab.setContent((Node) FXMLLoader.load(this.getClass().getResource("TabContent.fxml")));
}
public void initialize(ActionEvent event) {
}
}
TabContent.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="429.0" prefWidth="694.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox layoutX="39.0" layoutY="14.0" prefHeight="30.0" prefWidth="584.0" AnchorPane.leftAnchor="39.0" AnchorPane.rightAnchor="71.0">
<children>
<TextField prefHeight="25.0" prefWidth="641.0" />
</children>
</VBox>
<Label layoutX="14.0" layoutY="20.0" text="URL" />
<Button layoutX="628.0" layoutY="11.0" mnemonicParsing="false" prefHeight="30.0" prefWidth="59.0" text="POST" AnchorPane.rightAnchor="7.0" />
</children>
</AnchorPane>
There are 2 issues here:
The VBox does not grow the TabPane vertically. To fix this you need to set the VBox.vgrow property to ALWAYS
<TabPane fx:id="tabPane" VBox.vgrow="ALWAYS" prefHeight="377.0" prefWidth="640.0" tabClosingPolicy="ALL_TABS" />
You restrict your AnchorPane in TabContent.fxml to the preferred size (USE_PREF_SIZE). Set the max sizes to MAX_VALUE to allow the pane to grow:
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="429.0" prefWidth="694.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">

In JavaFX, how to add a TextField in TableView that's inside a TabPane?

I've built this GUI so far using Scene Builder and I want to add empty rows (TextField) to TableView in each TabPane I made. Any help would be appreciated. Or if you can suggest an easier method of doing this task instead of JavaFX.
P.S. I'm new to progamming.
Thanks in advance.
GUI so far
GUI so far (1)
My code so far
Main.java
package sample;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.util.Date;
public class Main extends Application {
Stage window;
Button button;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
window = primaryStage;
window.setTitle("LOPA Software");
window.setScene(new Scene(root, 800, 500));
window.show();
}
}
Controller.java
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ContextMenuEvent;
import java.awt.event.MouseEvent;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
#FXML
TreeView<String> treeView;
#FXML
TableView tableView;
Image icon = new Image(
getClass().getResourceAsStream("/img/icon.png"));
private MouseEvent mouseEvent;
#Override
public void initialize(URL location, ResourceBundle resources) {
TreeItem<String> root = new TreeItem<>("Project", new ImageView(icon));
root.setExpanded(true);
TreeItem<String> compA = new TreeItem<>("Component A", new ImageView(icon));
TreeItem<String> compB = new TreeItem<>("Component B", new ImageView(icon));
TreeItem<String> compC = new TreeItem<>("Component C", new ImageView(icon));
root.getChildren().addAll(compA, compB, compC);
compA.setExpanded(true);
TreeItem<String> compA1 = new TreeItem<>("High", new ImageView(icon));
TreeItem<String> compA2 = new TreeItem<>("Low", new ImageView(icon));
compA.getChildren().addAll(compA1, compA2);
treeView.setRoot(root);
}
public void mouseClick(javafx.scene.input.MouseEvent mouseEvent) {
if (mouseEvent.getClickCount() == 2) {
TreeItem<String> item = treeView.getSelectionModel().getSelectedItem();
System.out.println(item.getValue());
}
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<top>
<VBox BorderPane.alignment="CENTER">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Open" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Copy" />
<MenuItem mnemonicParsing="false" text="Cut" />
<MenuItem mnemonicParsing="false" text="Paste" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<ToolBar>
<items>
<Button mnemonicParsing="false" text="Toolbar" />
</items>
</ToolBar>
</children>
</VBox>
</top>
<left>
<TreeView fx:id="treeView" editable="true" onMouseClicked="#mouseClick" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</left>
<bottom>
<HBox BorderPane.alignment="CENTER">
<children>
<Label text="Label" />
</children>
</HBox>
</bottom>
<center>
<TabPane>
<tabs>
<Tab text="PHA">
<content>
<TableView prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn prefWidth="75.0" text="Cause" />
<TableColumn prefWidth="75.0" text="Consequence" />
<TableColumn prefWidth="75.0" text="Severity" />
<TableColumn prefWidth="75.0" text="Likelihood" />
<TableColumn prefWidth="75.0" text="Risk" />
<TableColumn prefWidth="75.0" text="Safeguard" />
<TableColumn prefWidth="75.0" text="Recommendation" />
<TableColumn prefWidth="75.0" text="LOPA" />
</columns>
</TableView>
</content>
</Tab>
<Tab text="LOPA">
<content>
<TableView prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn prefWidth="75.0" text="Scenario" />
<TableColumn prefWidth="75.0" text="Consequence">
<columns>
<TableColumn prefWidth="75.0" text="Description" />
<TableColumn prefWidth="75.0" text="Severity" />
</columns>
</TableColumn>
<TableColumn prefWidth="75.0" text="Acceptable Risk Tolerance" />
<TableColumn prefWidth="75.0" text="Initiating Events">
<columns>
<TableColumn prefWidth="75.0" text="Description" />
<TableColumn prefWidth="75.0" text="Freq. (per year)" />
</columns>
</TableColumn>
<TableColumn prefWidth="75.0" text="Independent Protection Layers (IPLs)" />
<TableColumn prefWidth="75.0" text="Mitigated Cosequence" />
<TableColumn prefWidth="75.0" text="Recommendation" />
</columns>
</TableView>
</content>
</Tab>
</tabs>
</TabPane>
</center>
</BorderPane>

JavaFX colspan not working for Text in GridPane

I am trying to center a label spanning two columns of a GridPane. However, it does not seem to work.
Application class:
public class GUIMainFXML extends Application {
#Override
public void start(Stage primaryStage) {
try {
GridPane p = (GridPane) FXMLLoader.load(getClass().getResource(
"FirstGUIexample.fxml"));
Scene scene = new Scene(p);
scene.getStylesheets().add(
getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("Welcome (FXML CODE)");
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}}
fxml file:
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
hgap="5" vgap="5">
<padding>
<Insets top="10" right="10" bottom="10" left="10" />
</padding>
<children>
<Text text="Welcome" GridPane.columnSpan="2" GridPane.halignment="CENTER"
GridPane.rowIndex="0" />
<Button text="Press me" GridPane.halignment="CENTER"
GridPane.rowIndex="1" GridPane.columnSpan="2" />
<CheckBox text="Don't touch me" GridPane.rowIndex="2"
GridPane.halignment="CENTER" GridPane.columnSpan="2" />
<Label text="Type me: " GridPane.halignment="CENTER"
GridPane.columnIndex="1" GridPane.rowIndex="3" />
<TextField GridPane.rowIndex="3" GridPane.columnIndex="2"
GridPane.halignment="CENTER" />
</children>
</GridPane>
application.css
Text {
-fx-font-size: 15pt;
-fx-font-family: Tahoma;
-fx-font-weight: bold;
}
I would like to set it either in the css or in the fxml, I am just testing.
You haven't provided the columnIndex for Text and Button, which you want to align in the center.
<Text text="Welcome" GridPane.columnSpan="2" GridPane.halignment="CENTER"
GridPane.columnIndex="1" GridPane.rowIndex="0" id="argh" />
<Button text="Press me" GridPane.halignment="CENTER" GridPane.columnIndex="1"
GridPane.rowIndex="1" GridPane.columnSpan="2" />

Resources