What i would like is to create two arrays of Buttons like this picture.
What i have done so far :
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
GridPane grid = new GridPane();
Scene scene = new Scene(grid2, 1000, 1000);
grid.setPadding(new Insets(10, 10, 10, 10));
for(int i=0;i<9;i++) {
for(int j=0;j<9;j++) {
grid.add(new Button(), i,j);
}
public static void main(String[] args) {
launch(args);
}
}
This creates the first desired array starting from the top left corner.However i can't seem to be able to place the second one.Adding a button in a location like (40,40) puts it in a different place.How could this be done?
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.
I am building an JavaFX application and am want to access values passed as an argument within the JavaFX UI. For some reason, I am unable to access these values in all the methods except the base method launchForm. Here is what my code looks like.
public class FormBuilder extends Application {
/*
* (non-Javadoc)
* #see javafx.application.Application#start(javafx.stage.Stage)
* Scene scene
* Group root
* BorderPane borderPane
* TabPane tabPane
* Tab stocksTab
* BorderPane stockTabBorderPane
* GridPane gridPane
*
*/
private Stocks stockData = new Stocks();
private int size;
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Stock Manager");
Group root = new Group();
Scene scene = new Scene(root, 1024, 800, Color.WHITE);
TabPane tabPane = new TabPane();
BorderPane borderPane = new BorderPane();
BorderPane stockTabBorderPane = new BorderPane();
Tab stocksTab = new Tab("Stocks");
stockTabBorderPane.setTop(this.addHBox());
stockTabBorderPane.setCenter(this.createGridPane());
stocksTab.setContent(stockTabBorderPane);
tabPane.getTabs().add(stocksTab);
borderPane.setCenter(tabPane);
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
root.getChildren().add(borderPane);
stage.setScene(scene);
stage.show();
}
private HBox addHBox() {
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10);
hbox.setStyle("-fx-background-color: #336699;");
Button buttonCurrent = new Button("Current");
buttonCurrent.setPrefSize(100, 20);
Button buttonProjected = new Button("Projected");
buttonProjected.setPrefSize(100, 20);
hbox.getChildren().addAll(buttonCurrent, buttonProjected);
return hbox;
}
private GridPane createGridPane() {
GridPane gridPane = new GridPane();
gridPane.setLayoutX(39);
gridPane.setLayoutY(131.0);
gridPane.setAlignment(Pos.TOP_CENTER);
gridPane.setVgap(5.0);
gridPane.setHgap(10.0);
gridPane.add(new Label("Active"), 1,1);
gridPane.add(new Label("Stock"), 2, 1);
gridPane.add(new Label("Symbol"), 3, 1);
gridPane.add(new Label("LPP"), 4, 1);
gridPane.add(new Label("LPP"), 5, 1);
gridPane.add(new Label("HPP"), 6, 1);
gridPane.add(new Label("LTP"), 7, 1);
System.out.println(this.size);
for(int v=2;v < this.stockData.getStocks().size()+2; v++) {
gridPane.add(new CheckBox(), 1, v);
gridPane.add(new Label("Amazon"), 2, v);
gridPane.add(new TextField (), 3,v);
gridPane.add(new TextField (), 4,v);
gridPane.add(new TextField (), 5,v);
gridPane.add(new TextField (), 6,v);
gridPane.add(new TextField (), 7,v);
}
return gridPane;
}
public void launchForm(Stocks stockData) {
this.stockData = stockData;
this.size = stockData.getStocks().size();
System.out.println(stockData.getStocks().size());
System.out.println(stockData.getStocks().get(0).getSector());
launch();
}
}
Now the issue is that when I try and access any value under the stockData object within the createGridPane method, the values are not available.
Examples are
this.stockData.getStocks().size() gives the value of 0 in the createGridPane method. But it gives a value of 2 in the launchForm method.
Again there are other values like
this.stockData.getStocks().get(0).getSector()
which returns the value "Retail" in the launchForm method. But when I try to access the same in a different method in the same class, I get an exception.
Can someone please help me here?
You're invoking Application.launch in the launchForm instance method and expect it to use the instance this method is invoked for as application class.
The JavaFX launch does not work this way however.
If Application.launch is called, a new instance of the class the method is invoked from is created by the launch method itself and it is this new instance that is used with init and start.
The easiest way to fix this would be, if you could create the Stocks in the init or start (possibly passing some Strings as parameters to launch).
Otherwise you need some other way to communicate with the newly created instance of the Application subclass, e.g. static members...
In JavaFX you should basically consider the Application subclass, and in particular its start() method, to be the entry point of the application. The application lifecycle is described in the Application Javadocs, but in brief the JavaFX launch process is initiated either by calling one of the static Application.launch(...) methods, or (using the Oracle JDK) by launching the JVM and specifying an Application subclass as the main class (even if it doesn't have a main method).
The launch process then:
starts the JavaFX toolkit
creates a new instance of the Application subclass
invokes init() on the Application subclass (the default implementation is a no-op)
starts the FX Application Thread
invokes start() on the Application subclass, executing it on the FX Application Thread.
Despite being invoked on different threads, start() is guaranteed not to be invoked until init() has completed.
From the code you posted, it must be the case that you are instantiating your FormBuilder class somewhere else, and calling launchForm(...) on that instance. When you call launch() from there, that creates a second instance and invokes start() on it, as described above. So of course the fields that you set on the instance on which launchForm(...) is called will not be set on the instance on which start(...) is called.
You should refactor your code so that either FormBuilder is the entry point to the application, or make FormBuilder not be an Application subclass and create a new entry point that instantiates and uses it. It appears you have some background work which loads data: this should be a separate class which should not be the entry point. So the first refactoring would look like:
// class that reads data and encapsulates it as a Stocks object
public class StockDataAccessor {
// ...
public Stocks getStocks() {
// ...
}
}
Then FormBuilder looks like:
public class FormBuilder extends Application {
/*
* (non-Javadoc)
* #see javafx.application.Application#start(javafx.stage.Stage)
* Scene scene
* Group root
* BorderPane borderPane
* TabPane tabPane
* Tab stocksTab
* BorderPane stockTabBorderPane
* GridPane gridPane
*
*/
private Stocks stockData ;
private int size;
#Override
public void start(Stage stage) throws Exception {
StockDataAccessor stockDataAccessor = new StockDataAccessor();
stockData = stockDataAccessor.getStocks();
stage.setTitle("Stock Manager");
Group root = new Group();
Scene scene = new Scene(root, 1024, 800, Color.WHITE);
TabPane tabPane = new TabPane();
BorderPane borderPane = new BorderPane();
BorderPane stockTabBorderPane = new BorderPane();
Tab stocksTab = new Tab("Stocks");
stockTabBorderPane.setTop(this.addHBox());
stockTabBorderPane.setCenter(this.createGridPane());
stocksTab.setContent(stockTabBorderPane);
tabPane.getTabs().add(stocksTab);
borderPane.setCenter(tabPane);
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
root.getChildren().add(borderPane);
stage.setScene(scene);
stage.show();
}
private HBox addHBox() {
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10);
hbox.setStyle("-fx-background-color: #336699;");
Button buttonCurrent = new Button("Current");
buttonCurrent.setPrefSize(100, 20);
Button buttonProjected = new Button("Projected");
buttonProjected.setPrefSize(100, 20);
hbox.getChildren().addAll(buttonCurrent, buttonProjected);
return hbox;
}
private GridPane createGridPane() {
GridPane gridPane = new GridPane();
gridPane.setLayoutX(39);
gridPane.setLayoutY(131.0);
gridPane.setAlignment(Pos.TOP_CENTER);
gridPane.setVgap(5.0);
gridPane.setHgap(10.0);
gridPane.add(new Label("Active"), 1,1);
gridPane.add(new Label("Stock"), 2, 1);
gridPane.add(new Label("Symbol"), 3, 1);
gridPane.add(new Label("LPP"), 4, 1);
gridPane.add(new Label("LPP"), 5, 1);
gridPane.add(new Label("HPP"), 6, 1);
gridPane.add(new Label("LTP"), 7, 1);
System.out.println(this.size);
for(int v=2;v < this.stockData.getStocks().size()+2; v++) {
gridPane.add(new CheckBox(), 1, v);
gridPane.add(new Label("Amazon"), 2, v);
gridPane.add(new TextField (), 3,v);
gridPane.add(new TextField (), 4,v);
gridPane.add(new TextField (), 5,v);
gridPane.add(new TextField (), 6,v);
gridPane.add(new TextField (), 7,v);
}
return gridPane;
}
// for non-JavaFX aware environments (like your IDE...)
public static void main(String[] args) {
launch(args);
}
}
Then launching FormBuilder as your main class will do what you need.
If you want to factor the application entry point out of the FormBuilder class entirely, the alternative refactoring (which is pretty similar) looks like:
public class FormBuilder {
/*
* (non-Javadoc)
* #see javafx.application.Application#start(javafx.stage.Stage)
* Scene scene
* Group root
* BorderPane borderPane
* TabPane tabPane
* Tab stocksTab
* BorderPane stockTabBorderPane
* GridPane gridPane
*
*/
private Stocks stockData ;
private int size;
private Group root ;
public FormBuilder() {
StockDataAccessor stockDataAccessor = new StockDataAccessor();
stockData = stockDataAccessor.getStocks();
root = new Group();
TabPane tabPane = new TabPane();
BorderPane borderPane = new BorderPane();
BorderPane stockTabBorderPane = new BorderPane();
Tab stocksTab = new Tab("Stocks");
stockTabBorderPane.setTop(this.addHBox());
stockTabBorderPane.setCenter(this.createGridPane());
stocksTab.setContent(stockTabBorderPane);
tabPane.getTabs().add(stocksTab);
borderPane.setCenter(tabPane);
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
root.getChildren().add(borderPane);
}
public Parent getView() {
return root ;
}
private HBox addHBox() {
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10);
hbox.setStyle("-fx-background-color: #336699;");
Button buttonCurrent = new Button("Current");
buttonCurrent.setPrefSize(100, 20);
Button buttonProjected = new Button("Projected");
buttonProjected.setPrefSize(100, 20);
hbox.getChildren().addAll(buttonCurrent, buttonProjected);
return hbox;
}
private GridPane createGridPane() {
GridPane gridPane = new GridPane();
gridPane.setLayoutX(39);
gridPane.setLayoutY(131.0);
gridPane.setAlignment(Pos.TOP_CENTER);
gridPane.setVgap(5.0);
gridPane.setHgap(10.0);
gridPane.add(new Label("Active"), 1,1);
gridPane.add(new Label("Stock"), 2, 1);
gridPane.add(new Label("Symbol"), 3, 1);
gridPane.add(new Label("LPP"), 4, 1);
gridPane.add(new Label("LPP"), 5, 1);
gridPane.add(new Label("HPP"), 6, 1);
gridPane.add(new Label("LTP"), 7, 1);
System.out.println(this.size);
for(int v=2;v < this.stockData.getStocks().size()+2; v++) {
gridPane.add(new CheckBox(), 1, v);
gridPane.add(new Label("Amazon"), 2, v);
gridPane.add(new TextField (), 3,v);
gridPane.add(new TextField (), 4,v);
gridPane.add(new TextField (), 5,v);
gridPane.add(new TextField (), 6,v);
gridPane.add(new TextField (), 7,v);
}
return gridPane;
}
}
and then create an entry point:
public class StockApp extends Application {
#Override
public void start(Stage stage) {
FormBuilder formBuilder = new FormBuilder();
Scene scene = new Scene(formBuilder.getView(), 1024, 800, Color.WHITE);
stage.setTitle("Stock Manager");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I'm trying to show a String on the screen, which is implemented in the Label named vraagLabel. I have placed the String in a Javafx.Gridpane and placed the GridPane within a Javafx.Borderpane.
The issue I'm having is that when the String is too big, since my screen has to have a set height and width, it will not continue on the next line but will only show ... How can I make it scale, so that the entire String will be shown on the screen, so when the String reaches the limit of the screen it will continue on the next line.
public class VraagView extends BorderPane {
javafx.scene.image.Image afbeeldingVraag = new javafx.scene.image.Image("be/kdg/TrivialPursuit/afbeeldingen/Vraag_Kaart.jpg");
private javafx.scene.control.Label vraagLabel;
private TextField antwoordField;
private Button btncheck;
private GridPane grid;
public VraagView( ) {
initialiseNodes();
layoutNodes();
}
private void initialiseNodes( ) {
vraagLabel = new Label();
antwoordField = new TextField();
btncheck = new Button("Antwoord");
grid = new GridPane();
}
private void layoutNodes() {
setBackground(new Background(new BackgroundImage(afbeeldingVraag, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT)));
grid.setVgap(5);
grid.setHgap(5);
grid.add(vraagLabel, 0, 5);
grid.add(antwoordField, 1, 1);
grid.add(btncheck, 2, 2);
setCenter(grid);
grid.setGridLinesVisible(true);
}
Instead of a TextField you could use a TextArea and set its wrapText attribute to true.
I have an application that uses the javafx GridPane layout manager, with one button affixed to it. Currently when I click on the button, I have it call a function and write to command line the result.
What I'm wondering is instead of writing to command line, how could I instead send the result of my function call to the grid itself, displaying it in say a text field or what have you? Currently this is the code that creates the UI
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(0, 25, 0, 25));
Button btn = new Button();
btn.setText("Get Button");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
String result = staticClass.getData(1, "A");
System.out.println(result );
}
});
grid.add(btn, 0, 0;
Found that to perform what I was after, you need to use the setText method, which I believe is what Uluk Biy was alluding too in his comments. For those that run into the same issue as I did down the road, here's a code sample to help illustrate.
final Label textDisplayLabel = new Label();
#Override
public void handle(ActionEvent event) {
textDisplayLabel.setText(calcTime.getTimestampDiff(new DateTime(1976, 9, 11, 10, 59, 0, 0), new DateTime(2012, 11, 11, 10, 59, 0, 0)));
}
});
then just place textDisplayLabel to where you want it on the UI and viola.