JavaFX Layout complie time - javafx

I'm trying to achieve this but I'm running into some problems. I got the rough skeleton, but for example when I try to add the output TextArea to my Vbox container, I get an error.
The error is: The method addAll(int, Collection<? extends Node>) in the type List<Node> is not applicable for the arguments (HBox, HBox, HBox, Button, TextArea)
EDIT: I had the wrong import for the TextArea, I had the awt instead of the javafx.scene.control.TextArea;
GridPane g1 = new GridPane();
HBox firstRow = new HBox();
firstRow.setPadding(new Insets(10));
Label name = new Label("Name: ");
TextField nameInput = new TextField();
g1.add(name, 0, 0);
g1.add(nameInput, 1, 0);
firstRow.getChildren().addAll(g1);
GridPane g2 = new GridPane();
HBox secondRow = new HBox();
secondRow.setPadding(new Insets(10));
Label city = new Label("City: ");
TextField cityInput = new TextField();
g2.add(city, 0, 0);
g2.add(cityInput, 1, 0);
secondRow.getChildren().addAll(g2);
HBox thirdRow = new HBox();
thirdRow.setSpacing(20);
thirdRow.setPadding(new Insets(5));
RadioButton radioName = new RadioButton("Name");
RadioButton radioCity = new RadioButton("City");
RadioButton radioZip = new RadioButton("Zip");
ToggleGroup group = new ToggleGroup();
radioName.setToggleGroup(group);
radioCity.setToggleGroup(group);
radioZip.setToggleGroup(group);
thirdRow.getChildren().addAll(radioName, radioCity, radioZip);
Button search = new Button("Search");
HBox fifthRow = new HBox();
TextArea output = new TextArea();
VBox container = new VBox();
container.getChildren().addAll(firstRow, secondRow, thirdRow, search);

Your question wasn't too clear initially because you did not include the error you saw. The problem is because you have imported the wrong TextArea, which import statements are also not included in your question.
You need to change import java.awt.TextArea; into import javafx.scene.control.TextArea;. The former is a control for AWT, while the latter is the control for JavaFX.

As it says, you need to add a child "ouput" which is TextBox element to a container.
container.getChildren().addAll(firstRow, secondRow, thirdRow, search, output);
Aslo I would like to note that you need to arrange elements in proper order, as this code is not pragmatic at all.

Related

How do i access the text of the selected radio button in JavaFX?

I am creating a project for my new understanding of JavaFX GUI. I am just having trouble getting the file to write "Small Cake", "Medium Cake", or "Large Cake" depending on which radio button has been selected. I know most of my logic is working and it has come down to the
writer.write(cakeSize.getSelectedToggle().selectedProperty().getValue().toString());
No matter the documentation I look at or what . selector I choose I can only seem to access the Boolean stating if is it 'true' for selected or not and if not that then it returns the name value as 'selected'
It does not need to use setText(value) I can get rid of those setters if needed I was just trying to find where I went wrong. Without those it just returns in an object the "Small" "Medium" or "Large" based on selection. Those being written on their own to the file I am fine with as well.
Thanks!
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.io.*;
public class BakeryApplication extends Application {
#Override
public void start(Stage stage) {
//Create a pane
//the pane is the layout container that contains other JavaFX components
GridPane gridPane = new GridPane();
//Create a label and pass it through the pane layout
Label orderTitle = new Label("Place your Cake Order Below");
Label nameTitle = new Label("First and Last Name");
Label numberTitle = new Label("Please enter your phone number:");
//Create a text field area
TextField name = new TextField();
TextField number = new TextField();
Label cakeSizeTtl = new Label("Please select your Cake Size:");
RadioButton cakeSm = new RadioButton("Small");
cakeSm.setText("Small Cake");
RadioButton cakeMd = new RadioButton("Medium");
cakeMd.setText("Medium Cake");
RadioButton cakeLg = new RadioButton("Large");
cakeLg.setText("Large Cake");
ToggleGroup cakeSize = new ToggleGroup();
cakeSm.setToggleGroup(cakeSize);
cakeMd.setToggleGroup(cakeSize);
cakeLg.setToggleGroup(cakeSize);
Label cakeTypeTtl = new Label("Please select your Cake Type:");
//Combo Box
ComboBox<String> cakeSelection = new ComboBox<>();
cakeSelection.getItems().addAll("Apple","Carrot", "Cheesecake","Chocolate", "Coffee", "Opera", "Tiramisu");
cakeSelection.setValue("Cake Type");
//create a save and quit button
Button saveBtn = new Button("Save");
Button quitBtn = new Button("Quit");
//Events for buttons
saveBtn.setOnAction(e -> {
try {
BufferedWriter writer = new BufferedWriter( new FileWriter("Order.txt"));
writer.write(number.getText());
writer.newLine();
writer.write(name.getText());
writer.newLine();
//add cakeType selection
// writer.write(cakeSize.getSelectedToggle().selectedProperty().toString());
writer.write(cakeSize.getSelectedToggle().selectedProperty().getValue().toString());
writer.newLine();
writer.write(cakeSelection.getValue());
//add cakeSize selection
writer.close();
} catch (IOException err) {
err.printStackTrace();
}
});
//handles click event on quit button to exit program
quitBtn.setOnAction(e ->{
Platform.exit();
});
//add an HBox to hold the buttons and arrange them horizontally
HBox buttonBox = new HBox(10, saveBtn, quitBtn);
gridPane.setHgap(10);
gridPane.setVgap(10);
//node, column, row
gridPane.setConstraints(orderTitle,2,0);
gridPane.setConstraints(nameTitle,2,1);
gridPane.setConstraints(name, 2, 2);
gridPane.setConstraints(numberTitle,2,3);
gridPane.setConstraints(number, 2, 4);
gridPane.setConstraints(cakeSizeTtl, 3, 5);
gridPane.setConstraints(cakeSm, 3, 6);
gridPane.setConstraints(cakeMd, 3, 7);
gridPane.setConstraints(cakeLg, 3, 8);
gridPane.setConstraints(cakeTypeTtl, 2, 5);
gridPane.setConstraints(cakeSelection, 2, 6);
gridPane.setConstraints(buttonBox, 3, 11);
gridPane.setPadding(new Insets(20));
//use getChildren and add method to place the label node in the pane layout
gridPane.getChildren().addAll(buttonBox, orderTitle, name, number, nameTitle, numberTitle, cakeSm, cakeMd, cakeLg, cakeSizeTtl, cakeSelection, cakeTypeTtl);
//Use BorderPane to aid in layout
//controls are typically inserted into a different
//type of layout and then added into the BorderPane accordingly
//like how our buttons and title are in a GridPane right now
BorderPane mainPain = new BorderPane();
mainPain.setCenter(gridPane);
//add the pane to the scene
Scene scene = new Scene(mainPain, 500, 500);
stage.setTitle("Assignment2 Order Your Cake!");
//Placing the Scene in the stage
stage.setScene(scene);
//Displays the Stage
stage.show();
}
public static void main(String[] args) {
//launches the Stage
launch();
}
}
You can ask the ToggleGroup for the currently selected Toggle using the getSelectedToggle() or selectedToggleProperty() method, as you are already doing.
However Toggle is an interface that doesn't define a text property. The Toggle interface has many implementations, one of which is RadioButton.
Now, since you know that your ToggleGroup only contains RadioButton toggles you can safely cast it and ask for its text.
Briefly:
RadioButton selectedToggle = (RadioButton) cakeSize.getSelectedToggle();
if (selectedToggle != null) // it can be null if nothing is selected
String selectedText = selectedToggle.getText();

Javafx Button size, EmptyBorder, and Read txt File into TextArea

I am trying to switch to javafx instead of swing but it has been a bit bumpy trying to find methods that do the exact tasks.
I am trying to get the buttons width to fill the entire scene and adjusts accordingly when you adjust the scene size.
Get a small empty border around text area and buttons.
Getting a method that reads a plain text file and replaces the current Text Area (not append).
package gui;
mport javafx.application.Application;
mport javafx.scene.Scene;
mport javafx.scene.control.Button;
mport javafx.stage.Stage;
mport javafx.scene.layout.*;
mport javafx.scene.control.TextArea;
public class Main extends Application{
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("TextArea Experiment 1");
TextArea textArea = new TextArea();
// Which TextArea method would I call to set a plain
// text file into the text area ?
BorderPane border = new BorderPane();
border.setCenter(textArea);
//border.setBorder(new EmptyBorder(10,10,10,10));
// Is there a method like this in JavaFx ?
GridPane grid = new GridPane();
border.setBottom(grid);
double screensize = border.getMaxWidth();
Button option1 = new Button("Button 1");
Button option2 = new Button("Button 2");
Button option3 = new Button("Button 3");
// how can I get the buttons to be max scene size and
//adjust dynamically to scene dimensions ?
option1.setMaxSize(Double.MAX_VALUE,Double.MAX_VALUE);
//option1.setPrefWidth(Double.MAX_VALUE);
System.out.println(screensize);
grid.add(option1, 0,1);
grid.add(option2,0,2);
grid.add(option3,0,3);
Scene scene = new Scene(border, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
first of all I suggest that to take a look at this tutorial: http://code.makery.ch/library/javafx-8-tutorial/
If you want to build a well structured javafx application you have to make an .fxml file, a Controller class and (some) model class(es).
But for those points here are the answers.
If you want to set a Region's size you have to use .setPrefSize(double,double) method, if you want to set dynamic you have to use for example myButton.prefSizeProperty().bind(anyRegionYouWantToBindTo.widthProprty())
I don't really understand what you want, I think you would like to use some styling, then you can write a .css file then arr it to textArea's styleClass.
After you get the text from the file instead of using textArea.appendText(String) you have to user textArea.setText(String)
I think these are the sollutions for your problems but I strongly recommend to read a tutorial about javafx. So have fun :)
Rewrite your question and only ask the question for this answer. You can then ask the other questions on their own thread.
GridPane grid = new GridPane();
grid.setMaxWidth(Double.MAX_VALUE);//Make sure the GridPane MaxWidth is set to MAX_VALUE. you can use grid.gridLinesVisibleProperty().set(true); to get an idea of the GRIDPANES current borders
border.setBottom(grid);
grid.gridLinesVisibleProperty().set(true);
Button option1 = new Button("Button 1");
option1.setMaxWidth(Double.MAX_VALUE);//Set button one MaxWidth to MAX_VALUE
Button option2 = new Button("Button 2");
option2.setMaxWidth(Double.MAX_VALUE);//Set button two MaxWidth to MAX_VALUE
Button option3 = new Button("Button 3");
option3.setMaxWidth(Double.MAX_VALUE);//Set button three MaxWidth to MAX_VALUE
//Add ColumnConstraints and set the width to 100%.
ColumnConstraints columnConstraint = new ColumnConstraints();
columnConstraint.setPercentWidth(100);
grid.getColumnConstraints().add(0, columnConstraint);
grid.add(option1, 0, 1);
grid.add(option2, 0, 2);
grid.add(option3, 0, 3);

Java FX out of the window screen

I wanna it will be okay when the number variables is changed, but when the are increased the button goes out from the window. How to fix it? Also how to put the bar down to the level of "10$", so they will be in the same row?
Before :
After :
Here is my code :
VBox vboxBottom = new VBox();
HBox hboxBottomElements = new HBox(15);
HBox hboxBottomMain = new HBox(0);
Region region = new Region();
region.setPrefWidth(500);
hboxBottomElements.getChildren().addAll(visaLabel, separator2, adLabel, separator3, governRelationStatus, separator4, region, next);
hboxBottomElements.setPadding(new Insets(5));
vboxBottom.getChildren().addAll(separator1, new Group(hboxBottomElements));
vboxBottom.setPadding(new Insets(3));
hboxBottomMain.getChildren().addAll(new Group(moneyBox), vboxBottom);
hboxBottomMain.setPadding(new Insets(3));
layout.setBottom(hboxBottomMain);
By using a Group here
vboxBottom.getChildren().addAll(separator1, new Group(hboxBottomElements));
you're creating a layout structure that resizes hboxBottomElements to it's prefered size independent of the space available.
HBox simply moves elements out the right side of it's bounds, if the space available does not suffice. This means if the Group containing moneyBox grows, the Button is moved out of the HBox...
The following simpler example demonstrates the behavior:
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Do something");
HBox.setHgrow(btn, Priority.NEVER);
btn.setMinWidth(Region.USE_PREF_SIZE);
Region filler = new Region();
filler.setPrefWidth(100);
HBox.setHgrow(filler, Priority.ALWAYS);
Rectangle rect = new Rectangle(200, 50);
HBox hBox = new HBox(rect, filler, btn);
Scene scene = new Scene(hBox);
primaryStage.setScene(scene);
primaryStage.show();
}
This will resize filler to make the HBox fit the window.
Now replace
Scene scene = new Scene(hBox);
with
Scene scene = new Scene(new Group(hBox));
and the Button will be moved out of the window...

JavaFX Node will not grow in height despite constraints when buried within several panes

I've been struggling with this issue for a couple hours and managed to reproduce the problem with the sample below. The actual program changes what is set in main.add(node, 0, 1) as the content based on what button is pressed in menu. I tried several different things such as AnchorPanes, changing setMaxHeight, and setVgrow for many different nodes in the each pane but have not been very successful. How would I make the ListView in the example fill the rest of the window height where it is located?
public class Main extends Application {
public void start(Stage stage) throws Exception {
// I've tried with this as a VBox, no effect.
GridPane main = new GridPane();
main.setGridLinesVisible(true);
main.setHgap(5);
main.setVgap(10);
// Meant to change what content is displayed in the actual program.
HBox menu = new HBox();
menu.setMaxWidth(Double.MAX_VALUE);
menu.setAlignment(Pos.CENTER);
main.add(menu, 0, 0);
GridPane.setHgrow(menu, Priority.ALWAYS);
menu.getChildren().addAll(new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Label("Hello world!"));
// Changes often.
GridPane content = new GridPane();
main.add(content, 0, 1);
// Options for the displayed content, changes the StackPane displayed below in my actual program.
HBox submenu = new HBox();
submenu.setMaxWidth(Double.MAX_VALUE);
submenu.setAlignment(Pos.CENTER);
content.add(submenu, 0, 0);
GridPane.setHgrow(submenu, Priority.ALWAYS);
submenu.getChildren().addAll(new Button("Button A"), new Button("Button B"), new Button("Button C"), new Label("Hello world!"));
// This is a custom class extended by StackPane in my actual program. Is often over overlayed with another transparent StackPane (not relevant to the problem).
StackPane subcontent = new StackPane();
subcontent.setMaxHeight(Double.MAX_VALUE);
subcontent.setMaxWidth(Double.MAX_VALUE);
content.add(subcontent, 0, 1);
// This was meant to be a TabPane in my actual program but this has the same outcome that won't fill the rest of the window height.
ListView<String> list = new ListView<>();
list.setMaxHeight(Double.MAX_VALUE);
list.setMaxWidth(Double.MAX_VALUE);
ObservableList<String> items = FXCollections.observableArrayList();
list.setItems(items);
subcontent.getChildren().add(list);
for(int i=0; i<100; i++) {
items.add("# "+i);
}
Scene scene = new Scene(main, 900, 550);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You need both
GridPane.setVgrow(content, Priority.ALWAYS);
and
GridPane.setVgrow(subcontent, Priority.ALWAYS);
The grid panes are going to size things to their preferred heights with the default vgrow: the preferred height of content is determined by the preferred height(s) of its child nodes, and the preferred height of a ListView is a fixed (arbitrary) size (I believe 400 pixels). So if you don't instruct subcontent to grow, it will by the preferred size of the list view, and forcing content to grow will just add extra (blank) space to content: if you don't force content to grow, it will take its preferred size, which is the preferred size of subcontent plus the preferred size of submenu.
Setting the max height doesn't do anything in this example, as you just need to allow the various nodes to grow beyond their preferred size:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
public void start(Stage stage) throws Exception {
// I've tried with this as a VBox, no effect.
GridPane main = new GridPane();
main.setGridLinesVisible(true);
main.setHgap(5);
main.setVgap(10);
// Meant to change what content is displayed in the actual program.
HBox menu = new HBox();
// menu.setMaxWidth(Double.MAX_VALUE);
menu.setAlignment(Pos.CENTER);
main.add(menu, 0, 0);
GridPane.setHgrow(menu, Priority.ALWAYS);
menu.getChildren().addAll(new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Label("Hello world!"));
// Changes often.
GridPane content = new GridPane();
main.add(content, 0, 1);
// Options for the displayed content, changes the StackPane displayed below in my actual program.
HBox submenu = new HBox();
// submenu.setMaxWidth(Double.MAX_VALUE);
submenu.setAlignment(Pos.CENTER);
content.add(submenu, 0, 0);
GridPane.setHgrow(submenu, Priority.ALWAYS);
submenu.getChildren().addAll(new Button("Button A"), new Button("Button B"), new Button("Button C"), new Label("Hello world!"));
// This is a custom class extended by StackPane in my actual program. Is often over overlayed with another transparent StackPane (not relevant to the problem).
StackPane subcontent = new StackPane();
// subcontent.setMaxHeight(Double.MAX_VALUE);
// subcontent.setMaxWidth(Double.MAX_VALUE);
content.add(subcontent, 0, 1);
// This was meant to be a TabPane in my actual program but this has the same outcome that won't fill the rest of the window height.
ListView<String> list = new ListView<>();
// list.setMaxHeight(Double.MAX_VALUE);
// list.setMaxWidth(Double.MAX_VALUE);
ObservableList<String> items = FXCollections.observableArrayList();
list.setItems(items);
subcontent.getChildren().add(list);
for(int i=0; i<100; i++) {
items.add("# "+i);
}
GridPane.setVgrow(content, Priority.ALWAYS);
GridPane.setVgrow(subcontent, Priority.ALWAYS);
Scene scene = new Scene(main, 900, 550);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

How to display number of lines textarea javafx

I´m trying to create a list with the number of lines of a textarea like in a text editor. I have done it with a VBox item and adding TextField ListCell but when I scroll in the textarea, the VBox doesn´t it . How can I do it?. This is part of code:
TextArea areaNueva = new TextArea();
areas.add(numeroTab, areaNueva);
areas.get(numeroTab).setStyle("-fx-font:15pt \"Times New Roman\";" + "-fx-focus-color: transparent;");
BorderPane bor = new BorderPane();
ObservableList<TextFieldListCell> tf = FXCollections.observableArrayList();
TextFieldListCell cell = new TextFieldListCell();
VBox b = new VBox();
cell.setPrefSize(20,1);
cell.setFont(Font.font("Times New Roman",11.35));
cell.setText("1");
tf.add(0,cell);
b.getChildren().addAll(tf);
b.setSpacing(-2);
b.setPadding(new Insets(3,0,0,0));
bor.setLeft(b);
bor.setCenter(areaNueva);
Tab tabNuevo = new Tab("Sin Titulo");
tabs.add(numeroTab, tabNuevo);
tabs.get(numeroTab).setClosable(true);
tabs.get(numeroTab).setContent(bor);
An with this I add new number of lines:
private ArrayList<ObservableList<TextFieldListCell>> lineas = new ArrayList<ObservableList<TextFieldListCell>>();
String parte = null;
int i = 1;
while ((parte = br.readLine()) != null) {
areaAUtilizar.appendText(parte + "\n");
if(i!=1){
TextFieldListCell c = new TextFieldListCell();
c.setText(Integer.toString(i));
c.setFont(Font.font("Times New Roman",11.35));
c.setPrefSize(20, 13);
lineas.get(a).add(i-1,c);
boxes.get(a).getChildren().setAll(lineas.get(a));
}
i++;
}
I solved it by removing the scroll of the textarea and the listview and put its opacity to 0, and putting both in a borderpane. After I put a scrollbar and the borderpane in a scrollpane. And for it to appear the scrollbar of the scrollpane I increased the height of the textarea and the listview when the lines of the textarea are more great than the prefheight.

Resources