Create multiple exact FXML objects in JavaFX - java

I want to create multiple fxml objects inside the window, using code in fxml once. But they are not appearing more than once.
Here is my controller code:
public class HelloController {
#FXML
private AnchorPane plot = new AnchorPane();
#FXML
void AddPlotBlock(ActionEvent event) {
this.plot.setMinHeight(110.0D);
this.plot.setMinWidth(250.0D);
this.plot.setStyle("-fx-background-color: grey");
}
And FXML:
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS" style="-fx-background-color: #301934;">
<children>
<AnchorPane fx:id="plot"/>
</children>
</AnchorPane>

Okay, I found how to fix it.
To make this you need to change id in FXML main file not in children but in pane (my AnchorPane) and then make AnchorPane with exact name in controller.
Then you can initialyze your blocks or anything inside controller and add it in pane.
Here is my solution.
controller >
plots.getChildren().add(card); // plots is id
upper command is inside button click.
#FXML
private AnchorPane plot = new AnchorPane();
#FXML
public AnchorPane plots;
plot is objects. You can place infinite objects (if you have memory)
plots is id of anchorpane.
FXML anchorpane
<AnchorPane fx:id="plots" maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS" style="-fx-background-color: #301934;" />
So anchorpane have id and you add child arguments (plot) to main pane (plots).
Thanks for commenting, and rules.

Related

JavaFx Pane in Stack not responding to MouseTransparent or PickOnBounds

I have a SplitPane and a Pane together in a stack. The Pane is underneath the SplitPane in the stack, and the middle SplitPane is a transparent AnchorPane. My intention is for an event to fire which draws a circle on the underlying Pane when I click somewhere within the area of the center pane, but I'm unable to get the event to fire by clicking on the pane.
(EDIT:This mouse event should come from the Pane, not from the anchorpane, because I also need the drawn shapes to respond to clicks.)
I have read posts on here about this and most solutions include MouseTransparent and PickOnBounds. I have tried what feels like every combination of those properties on the central AnchorPane, its label child, and the underlying Pane where the circle needs to be drawn to no avail. Any help is welcome! :)
Here are two images of both the physical layout and the hierarchy in scene builder. The blue showing is the underlying Pane. It is visible because the central AnchorPane is transparent.
Update: You can use setMouseTransparent(true/false) for the foreground split pane when entering/exiting the center anchor pane with the mouse like e. g. this:
Controller Class:
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
public class Controller {
#FXML
private Pane
backgroundPane;
#FXML
private SplitPane
foregroundSplitPane;
#FXML
public void handleBackgroundPaneOnMouseClick() {
// Create and add an ellipse:
Ellipse ellipse = new Ellipse();
ellipse.setRadiusX(50);
ellipse.setRadiusY(50);
ellipse.setFill(Color.BLACK);
ellipse.setLayoutX((backgroundPane.getWidth() / 2));
ellipse.setLayoutY((backgroundPane.getHeight() / 2));
backgroundPane.getChildren().add(ellipse);
}
#FXML
public void handleCenterAnchorPaneOnMouseEntered() {
foregroundSplitPane.setMouseTransparent(true);
}
#FXML
public void handleCenterAnchorPaneOnMouseExited() {
foregroundSplitPane.setMouseTransparent(false);
}
}
FXML File:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.StackPane?>
<StackPane prefHeight="150.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Pane fx:id="backgroundPane" onMousePressed="#handleBackgroundPaneOnMouseClick" style="-fx-background-color: blue;" />
<SplitPane fx:id="foregroundSplitPane" dividerPositions="0.1, 0.9" style="-fx-background-color: rgba(255,255,255,0);">
<items>
<AnchorPane style="-fx-background-color: tomato;" />
<AnchorPane onMouseEntered="#handleCenterAnchorPaneOnMouseEntered" onMouseExited="#handleCenterAnchorPaneOnMouseExited" style="-fx-background-color: rgba(255,255,255,0);" />
<AnchorPane style="-fx-background-color: tomato;" />
</items>
</SplitPane>
</children>
</StackPane>
Preview:

JavaFX Controller not linking to JavaFX fxml file

I am attempting to create a method in my main screen controller to set a new scene in my program. When attempting to do so, I get the following error:
Error resolving onAction='#partAddButtonPushed', either the event handler is not in the Namespace or there is an error in the script.
The relevant fxml code is:
<AnchorPane id="AnchorPane" prefHeight="420.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="john.Doe.View_Controller.MainController">
<children>
<Button id="addPartsButton" fx:id="partAdd" layoutX="190.0" layoutY="340.0" maxWidth="70.0" minWidth="70.0" mnemonicParsing="false" onAction="#partAddButtonPushed" prefWidth="70.0" text="Add">
and the relevant code in the controller is:
public class MainController implements Initializable {
#FXML
private Button partAdd;
#FXML
private void partAddButtonPushed(ActionEvent event) throws IOException {
Parent partAddParent = FXMLLoader.load(getClass().getResource("/View/AddPart.fxml"));
Scene AddPartScene = new Scene (partAddParent);
Stage window = (Stage)((Node)event.getSource()).getScene().getWindow();
window.setScene(AddPartScene);
window.show();
}
Would anyone happen to know why they are not linking up?

How do I make my VBox and Label resize according to texts in label in JavaFx?

As you can see, my texts are constrained by labels. How do I make the label resize to exactly fit the text and also to resize the VBox and GridPane accordingly. I only want to resize vertically.
My FXML:
<VBox fx:id="body"
alignment="TOP_CENTER"
prefHeight="150"
GridPane.vgrow="SOMETIMES"
prefWidth="300"
GridPane.columnIndex="0"
GridPane.rowIndex="1" spacing="5">
<Label alignment="CENTER" textAlignment="JUSTIFY" fx:id="word" maxWidth="268"/>
<Pane prefHeight="10" VBox.vgrow="NEVER"/>
<Label alignment="CENTER" textAlignment="JUSTIFY" wrapText="true" fx:id="meaning" maxWidth="268" />
<Label alignment="CENTER" textAlignment="JUSTIFY" wrapText="true" fx:id="sentence" maxWidth="268" />
</VBox>
This VBox is inside the GridPane:
<GridPane fx:id="base"
alignment="CENTER"
prefHeight="210.0"
maxWidth="310.0"
stylesheets="#style.css"
vgap="0" xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller">
...
Minimal, Complete, and Verifiable example as requested by #James_D
Main Class:
public class Main extends Application {
private Stage stage;
private StackPane stackPane;
#Override
public void start(Stage primaryStage) throws Exception{
stage = primaryStage;
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = (Parent) loader.load();
stackPane = new StackPane(root);
Scene scene = new Scene(stackPane);
scene.setFill(Color.WHITE);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller Class:
public class Controller implements Initializable{
#FXML private Label label1;
#FXML private Button changeLabel;
private StringProperty labelString = new SimpleStringProperty();
#Override
public void initialize(URL location, ResourceBundle resources) {
labelString.setValue("aasdasd sad asdasd asdasda");
label1.textProperty().bind(labelString);
}
#FXML
public void clicked(MouseEvent e){
labelString.setValue("asdsadasd asdasdasd sfdgsfwoef fgtrhfgbdrgdf dfgdfivbjkfd gdfgidfjvdf gdfgjldkvbdf gjdilgjdfv dfgojdflkgdf ");
}
}
sample.fxml:
<GridPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10" maxHeight="Infinity">
<children>
<VBox fx:id="body"
alignment="CENTER"
maxHeight="Infinity"
GridPane.vgrow="SOMETIMES"
prefWidth="300"
GridPane.columnIndex="0"
GridPane.rowIndex="1" spacing="5">
<Label alignment="CENTER" VBox.vgrow="ALWAYS" wrapText="true" textAlignment="CENTER" fx:id="label1" maxWidth="268"/>
<Button fx:id="changeLabel" text="Change" minWidth="50" onMouseClicked="#clicked" maxWidth="Infinity" />
</VBox>
</children>
Expectation:
When I press 'Change' button, Everything should resize to just give enough space for text to be shown.
Problem:
When I press 'Change' button, UI remains same not showing the full text.
Assuming you want the text to wrap, the labels will need to be able to grow vertically. Add the attribute
maxHeight="Infinity"
to each label. You are also constraining the overall height of the VBox with prefHeight="150"; remove that attribute and let the VBox figure out its own height. Similarly, you probably want to remove the prefHeight attribute from the GridPane.

JAVAFX Scene builder multiple controllers

I tortured google with multiple questions but still cant get a point.
I want to build app with 2 FXML scenes populated by SceneBuilder. Each have it's own controller.
I use ControlledScreen to swap Scenes and this works.
But then i cant change anything on scene.
For example: i have label in Scene Controller:
public class ControllerForm implements ControlledScreen, Initializable {
ScreensController myController;
GraphicsContext GC;
#FXML
private Label fitnessLabel;
public void updateFitnessLabel(double data) {
fitnessLabel.setText(String.valueOf(data));
}
public void initialize(URL location, ResourceBundle resources) {
this.GC = neuroCanvas.getGraphicsContext2D();
}
It's defined in FXML file as:
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="684.0" prefWidth="918.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="general.ControllerForm">
<left>
<VBox prefHeight="400.0" prefWidth="189.0" BorderPane.alignment="CENTER">
<children>
<Label fx:id="fitnessLabel" text="Label">
<graphic>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Fitness:" />
</graphic>
</Label>
And function to update label is updateFitnessLabel.
In initialize method i use GC cuz i have canvas on this scene and want to draw on it.
I have method that is calling for this fucntion as:
public class Net {
private ControllerForm controller;
public void drawStart() throws IOException {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
Main.ScreenFile
)
);
BorderPane cv = loader.load();
// load actual screen
ControllerForm controller =
loader.<ControllerForm>getController();
controller.updateFitnessLabel(12);}
But no effect. Label wont be updated.
What am i missing ?
I tried to use Timeline, but still no effect.
How to actuall draw something on this scene ?
Ok, i found solution.
loader.load returns Object. But i need initial Object not a new one.
Used this answer - FXMLLoader getController returns NULL?
This is not optimal, but i have no idea how to get initial object.

JavaFx #FXML Pagination injected to my controller class can't be modified

I have designed my fxml using scene builder. Pagination comes with 10 pages as default and in page number buttons. I want to change those default stuffs according to my scenario.
Here is what I have done in my controller:
#FXML
private Pagination pagination;
...
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
pagination = new Pagination(7, 0);
pagination.setPageFactory((Integer pageIndex)->createUserInfo(pageIndex));
pagination.getStyleClass().add(Pagination.STYLE_CLASS_BULLET);
}
...
private VBox createUserInfo(int pageIndex) {
VBox box = new VBox();
ImageView iv = new ImageView(images[pageIndex]);
box.setAlignment(Pos.CENTER);
Label desc = new Label("PAGE Number");
box.getChildren().addAll(iv, desc);
return box;
}
Here is my FXML :
<StackPane fx:id="stackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="538.0" prefWidth="747.0" style="-fx-background-color: #e8eaf6;" stylesheets="#../styles/inventory_fxml.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.inventory.controller.UserMange_fxmlController">
<children>
<Group nodeOrientation="LEFT_TO_RIGHT">
<children>
<VBox fx:id="vbox" prefHeight="483.0" prefWidth="685.0">
<children>
<Pagination fx:id="pagination" prefHeight="352.0" prefWidth="685.0" stylesheets="#../styles/inventory_fxml.css" />
....
But Still I get default configurations as I run the app. Is there anything wrong with my code ?? Thanks in advance....
You are creating a new Pagination and then configuring it, instead of configuring the one you defined in the FXML (i.e. the one that is displayed in the UI).
The bottom line is that you should never assign a new object to a #FXML-annotated reference.
Instead of
pagination = new Pagination(7, 0);
do
pagination.setPageCount(7);
pagination.setCurrentPageIndex(0);

Categories

Resources