JavaFX: Add textField and Labels to scene - java

I'm trying to get two tabs, each with their own little form that contain labels and textfields/textareas. I thought my making a "Master" VBox that should display everything but nothing other than the tabs are showing and neither am i getting any errors.
How do I add them to the scene?
// Label and Button variables
private Label fname,lname, appt, AppointmentInfo;
protected String input;
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Person Appointments");
primaryStage.setWidth(500);
primaryStage.setHeight(500);
//Create and set Tab Names
Tab InfoTab = new Tab();
Tab ApptTab = new Tab();
InfoTab.setText("PersonInfo");
ApptTab.setText("Appointments");
// VBoxes
VBox personInfoBox = new VBox();
VBox FirstBox = new VBox();
VBox appointmentBox = new VBox();
// Setup labels and fields
fname = new Label();
lname = new Label();
appt = new Label();
AppointmentInfo = new Label();
fname.setText("First Name");
lname.setText("Last Name");
appt.setText("Appt Count");
AppointmentInfo.setText("Appt Info");
// Text Fields
TextField firstNameText = new TextField();
TextField lastNameText = new TextField();
TextField appointmentText = new TextField();
TextArea apptInfo = new TextArea();
firstNameText.setText("First Name Here");
lastNameText.setText("Last Name Here");
appointmentText.setText("Appointment Here");
personInfoBox.getChildren().add(fname);
personInfoBox.getChildren().addAll(firstNameText);
personInfoBox.getChildren().add(lname);
personInfoBox.getChildren().addAll(lastNameText);
appointmentBox.getChildren().add(AppointmentInfo);
appointmentBox.getChildren().addAll(apptInfo);
// Grid for Tabs
GridPane grid = new GridPane();
GridPane grid2 = new GridPane();
grid.add(fname, 0, 0);
grid.add(firstNameText, 0, 1);
grid.add(lname, 1, 0);
grid.add(lastNameText, 1, 1);
grid.add(appt, 2, 0);
grid.add(appointmentText, 2, 1);
grid2.add(AppointmentInfo, 0, 0);
grid2.add(apptInfo, 0, 1);
InfoTab.setContent(grid);
ApptTab.setContent(grid2);
// TabPane
TabPane tabPane = new TabPane();
tabPane.getTabs().add(InfoTab);
tabPane.getTabs().add(ApptTab);
InfoTab.setClosable(false);
ApptTab.setClosable(false);
InfoTab.setContent(personInfoBox);
ApptTab.setContent(appointmentBox);
VBox one = new VBox(tabPane, personInfoBox);
Scene scene = new Scene(one, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();`

You can't assign a Node more than once to the SceneGraph:
A node may occur at most once anywhere in the scene graph. Specifically, a node must appear no more than once in all of the following: as the root node of a Scene, the children ObservableList of a Parent, or as the clip of a Node.
http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html
You assigned e.g. lname to personInfoBox AND grid. So finally lname will be assigned to grid only. Then you set grid as content for a Tab and after that you set personInfoBox as content, which is now empty

Related

Add a top menu to JavaFX centered Grid Pane

I'm very new to JavaFX. I am using a grid pane to keep my items centered on the page regardless of how the window is resized. I want to add a menu that runs along the top. I quickly found out grid.setTop(menuBar) is not a member function of grid pane. Is there a way to this?
Can I create two different types of panes in one scene? IE, a GridPane to center items and a BorderPane to get the menu up top? Or should I use CSS styling to get the menubar at the top?
Here is some code I'm using:
public void start(Stage primaryStage) {
try {
primaryStage.setTitle("Bapu Inventory");
BorderPane root = new BorderPane();
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Text scenetitle = new Text("Welcome");
grid.add(scenetitle, 0, 0, 1, 1);
MenuBar menuBar = new MenuBar();
menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
//This is the line I can't figure out. How do I get this to position at top left?
grid.setTop(menuBar);
Any help would be greatly appreciated here. I looked through the documentation Oracle provides but didn't find this feature listed anywhere.
Check if this is what you want:
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
//Create your menu
final Menu menu1 = new Menu("File");
final Menu menu2 = new Menu("Options");
final Menu menu3 = new Menu("Help");
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(menu1, menu2, menu3);
//Your GridPane
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Text scenetitle = new Text("Welcome");
grid.add(scenetitle, 0, 0, 1, 1);
//Add them to root (BorderPane)
root.setTop(menuBar);
root.setCenter(grid);
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}

JavaFX ScrollPane setVvalue() not working properly

I am testing the JavaFX ScrollPane class and realized that it is not working as I expect, I don't know why. I have the following code:
public class Client3 extends Application {
int indexMsg = 0;
Button send;
GridPane root;
ScrollPane msgPane;
GridPane msgPaneContent;
FlowPane writePane;
TextField writeMsg;
Scene scene;
#Override
public void start(Stage primaryStage) {
root = new GridPane();
root.setAlignment(Pos.CENTER);
root.setVgap(10);
root.setPadding(new Insets(10, 10, 10, 10));
msgPane = new ScrollPane();
msgPane.setPrefSize(280, 280);
msgPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
msgPaneContent = new GridPane();
msgPaneContent.setPrefWidth(270);
msgPaneContent.setVgap(10);
writePane = new FlowPane(10, 10);
writePane.setAlignment(Pos.CENTER);
writePane.setPrefWidth(280);
writeMsg = new TextField();
writeMsg.setPrefWidth(150);
writeMsg.setPromptText("Write your message");
writePane.getChildren().add(writeMsg);
GridPane.setConstraints(msgPane, 0, 0);
GridPane.setConstraints(writePane, 0, 1);
msgPane.setContent(msgPaneContent);
root.getChildren().addAll(msgPane, writePane);
writeMsg.setOnAction((ev) -> {
if (!writeMsg.getText().isEmpty()) {
TextArea msg = new TextArea(writeMsg.getText());
msg.setMaxWidth(135);
msg.setPrefRowCount(msg.getLength() / 21 + 1);
msg.setWrapText(true);
GridPane.setConstraints(msg, 0, indexMsg);
indexMsg++;
writeMsg.deleteText(0, writeMsg.getText().length());
msgPaneContent.getChildren().add(msg);
msgPane.setVvalue(1.0);
}
});
scene = new Scene(root, 300, 300);
primaryStage.setTitle("Chat App");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Basically, I have a GridPane as the root with a ScrollPane and a GridPane as its children. The ScrollPane has a children GridPane. There is a TextField with an EventHandler which generates a TextArea inside the GridPane (the ScrollPane's children). Each TextArea object is created in the vertical direction, downwards. I want to set the scrollbar always at its maximum value (setVvalue(1.0)) each time a new TextArea is added. The thing is that it doesn't seem to work as it should because the vertical value is never set to the maximum after handling the event, but it seems to be set to the maximum value that it had before handling it (the bottom of the previous TextArea added).
Any solution for this? Thanks in advance.

Aligning Nodes to the right side of a Vbox in javafx

I'm trying to make a chatBox with javafx, and I want the messages from the client to be aligned to right and the rest to left.
I'm using a Vbox, wrapped in a Scrollpane and in that Vbox, each message is wrapped in another Vbox.
But aligning the inner Vbox doesn't work.
Here is my code:
private VBox addMsg(String senderName, String text, String time) {
Label snderName = new Label(senderName + ":");
snderName.setId("senderName");
snderName.setMaxWidth(400);
snderName.setAlignment(Pos.BASELINE_LEFT);
Label msgText = new Label(text);
msgText.setId("msgText");
msgText.setWrapText(true);
msgText.setMaxWidth(400);
Label msgTime = new Label(time);
msgTime.setId("msgTime");
msgTime.setMaxWidth(400);
msgTime.setAlignment(Pos.BASELINE_RIGHT);
VBox msg = new VBox(snderName, msgText, msgTime);
msg.setBackground(new Background(new BackgroundFill(Color.AQUA, new CornerRadii(3d), Insets.EMPTY)));
msg.setPadding(new Insets(5));
msg.setMaxWidth(400);
msg.setEffect(new DropShadow(2, Color.DARKBLUE));
return msg;
}
public void buildChatBox() {
Button backToPublicChat = new Button("<");
backToPublicChat.setId("backToPublicChat");
backToPublicChat.setVisible(false);
Text chatWindowInfo = new Text("public chat room");
chatWindowInfo.setId("chatWindowInfo");
VBox chatHistory = new VBox();
chatHistory.setId("chatHistory");
chatHistory.setPrefWidth(CHAT_BOX_WIDTH);
chatHistory.setPrefHeight(GAME_HEIGHT - 50);//badsmell
TextField messageField = new TextField("type your message...");
messageField.setId("messageField");
messageField.setPrefHeight(30);
messageField.setPrefWidth(CHAT_BOX_WIDTH - 40);
Button sendButton = new Button("send");
sendButton.setId("sendButton");
sendButton.setPrefHeight(30);
sendButton.setOnMouseClicked(event -> {
VBox vBox = addMsg(
"Aran",
"hi, i'm aran",
"5:19");
vBox.setAlignment(Pos.TOP_LEFT);
chatHistory.getChildren().add(vBox);
VBox vBox2 = addMsg(
"Farnam",
"oh, I love you!",
"5:19");
vBox2.setAlignment(Pos.TOP_RIGHT);
chatHistory.getChildren().add(vBox2);
});
ScrollPane scrlPane = new ScrollPane(chatHistory);
scrlPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrlPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
scrlPane.setId("scrolPane");
chatBox = new VBox(new HBox(backToPublicChat, chatWindowInfo), scrlPane, new HBox(messageField, sendButton));
chatBox.setId("chatBox");
chatBox.getStylesheets().add("TowDef/GUI//chatBoxCSS.css");
}
Also I just need to set the HPos but i don't know how to, so I used the Pos.TOP_RIGHT.
does anyone know how to achieve this?
any advice on how to make the chatbox in a better way will be well appreciated:)
You can achieve that using HBox,
For Right Aligning.
Label label=new Label("guru ");
label.getStylesheets().add("sample/styles/send.css");
label.setId("receive");
HBox hBox=new HBox();
hBox.getChildren().add(label);
hBox.setAlignment(Pos.BASELINE_RIGHT);
vBox.getChildren().add(hBox);
vBox.setSpacing(10);
For Left Aligning
Label label=new Label(msg);
label.getStylesheets().add("sample/styles/send.css");
label.setId("send");
HBox hBox=new HBox();
hBox.getChildren().add(label);
hBox.setAlignment(Pos.BASELINE_LEFT);
vBox.getChildren().add(hBox);
vBox.setSpacing(10);

A java.lang.NoSuchMethodException error (layouts)

I want to display another layout in another window, but whenever I add a new layout to start method
BorderPane sch = new BorderPane();
sch.setCenter(addVBox2(primaryStage));
scene1 = new Scene(sch, 800, 500);
I get this error
Exception in Application start method
Exception in thread "main" **java.lang.NoSuchMethodException**: sample.Main.main([Ljava.lang.String;)
at java.lang.Class.getMethod(Class.java:1786)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:119)
Where might the problem in the code be? Thank you for any help in advance.
public void start(Stage primaryStage) throws IOException {
stage = primaryStage;
BorderPane border = new BorderPane();
border.setLeft(addVBox(primaryStage));
border.setCenter(addGridPane(primaryStage));
border.setRight(addDatePicker(primaryStage));
HBox hbox = addHBox();
border.setBottom(hbox);
scene = new Scene(border, 800, 500);
BorderPane sch = new BorderPane();
sch.setCenter(addVBox2(primaryStage));
scene1 = new Scene(sch, 800, 500);
stage.setScene(scene);
stage.setTitle("Booking Form");
stage.show();
}
private VBox addVBox2(Stage stage) {
javafx.scene.control.Label label = new javafx.scene.control.Label("Choose rooms' schedule");
label.setFont(javafx.scene.text.Font.font("Tahoma", FontWeight.BOLD, 16));
room1 = new RadioButton("Room 1 of type 1");
room1.setSelected(true);
room2 = new RadioButton("Room 2 of type 1");
room3 = new RadioButton("Room 1 of type 2");
room4 = new RadioButton("Room 2 of type 2");
room5 = new RadioButton("Room 1 of type 3");
room6 = new RadioButton("Room 2 of type 3");
VBox buttons2 = new VBox(20, label, roomtype1, roomtype2);
buttons2.setAlignment(Pos.CENTER);
buttons2.setMaxWidth(225);
stackPane.getChildren().add(buttons2);
ToggleGroup toggleGroup = new ToggleGroup();
toggleGroup.getToggles().addAll(roomtype1, roomtype2);
Scene scene = new Scene(stackPane, 400, 200);
stage.setTitle("RadioButton control");
stage.setScene(scene);
stage.show();
return buttons2;
}
private HBox addHBox() {
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10); // Gap between nodes
hbox.setStyle("-fx-background-color: #336699;");
hbox.setAlignment(Pos.CENTER);
final Text actionTarget = new Text();
Button schedule = new Button("Schedule");
schedule.setPrefSize(100, 20);
schedule.setOnAction(e -> stage.setScene(scene1));
...}
Exception in thread "main" java.lang.NoSuchMethodException: Main.main([Ljava.lang.String;)
This error means your main class is not found. When you have this kind of error, most of the time it means you moved your main class from a file to another without changing your run configuration.
Edit your run configuration in intellij IDE. Your run configuration is pointing to wrong class it seems. edit run configuration

LayoutY of GridPane not affected by ScrollBar Listener

I have a GridPane that i fill dynamically, then I display it, the problem is: if the rows are so many, then the rows in the bottom don't get displayed, what i want is to add a scrollbar so that I can display all of the rows, here is the code but it's not working:
BudgetManager bManager = new BudgetManager();
List<Debt> debts = bManager.getDebts();
GridPane topLevel = new GridPane();
topLevel.setAlignment(Pos.TOP_CENTER);
int row = 0;
double totatB = 0, totalS = 0;
for (Debt d : debts) {
//fill GridPane
}
ScrollBar sc = new ScrollBar();
sc.setMin(0);
sc.setMax(350);
sc.setVisibleAmount(20);
sc.setOrientation(Orientation.VERTICAL);
sc.setUnitIncrement(10);
sc.setBlockIncrement(50);
sc.setPrefWidth(20);
sc.valueProperty().addListener((ObservableValue<? extends Number> ov, Number old_val, Number new_val) -> {
topLevel.setLayoutY(-new_val.doubleValue());
}
});
HBox box = new HBox();
box.getChildren().addAll(topLevel, sc);
HBox.setHgrow(topLevel, Priority.ALWAYS);
Scene scene = new Scene(box, 1200, 600);
stage.setScene(scene);
stage.show();
SOLVED
here is the solution, thanks to keuleJ, using ScrollPane instead of ScrollBar:
ScrollPane scroll = new ScrollPane();
GridPane topLevel = new GridPane();
scroll.setContent(topLevel);
scroll.setHbarPolicy(ScrollBarPolicy.ALWAYS);
scroll.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
scroll.setFitToWidth(true);
scroll.setFitToHeight(true);
Scene scene = new Scene(scroll, 1200, 600); // Manage scene size
Use fitToWidth or fitToHeight properties.
See the docs:
https://docs.oracle.com/javafx/2/api/javafx/scene/control/ScrollPane.html

Categories