SceneBuilder 2.0 Dynamic shape generation - java

I have an FXML file that does some certain animations with some right now static(so to speak) shapes that are hard-coded into the fxml. What I am trying to do is dynamically create shapes from Java Objects that have certain properties such as color which these objects will be pulling from a database and populate the fxml with these object based shapes, I am not sure how to go about doing this. Below is the code for the main class, I know why the error is happening but not sure how to do it any other way.
public class TestConveyorView extends GuiceApplication {
#Inject
private GuiceFXMLLoader fxmlLoader;
public Injector createInjector() {
return Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
}
});
}
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void init(List<Module> modules) throws Exception {
}
#Override
public void start(Stage stage) throws Exception {
//GridPane root = new GridPane();
Parent root = fxmlLoader.load(getClass().getClassLoader().getResource("fxml/TestConveyorView.fxml")).getRoot();
Box box = new Box(1, red);
Rectangle rectangle = new Rectangle(50,50,box.getColor());
// Can't seem to add it to the scene, problem occurs here.
root.getChildren().add(rectangle);
Scene scene = new Scene(root);
// BackgroundImage background = new BackgroundImage(null, BackgroundRepeat.REPEAT, BackgroundRepeat.REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT);
stage.setScene(scene);
stage.show();
}
}

Ok I fixed the problem by changing
Parent root = ...
To
AnchorPane root = ...
Simple fix that I overlooked I guess.

Related

Change a binded string property throught non java application thread

Im trying to bind a label to some property that is modified outside the java application Thread and it throws not an fx application thread. I read the javafx concurrency documentation but Im honestly having a hard time of understanding it or how to implement it in my situation.
public class testApplication extends Application {
private final StringProperty someString = new SimpleStringProperty("inicial value");
#Override
public void start(Stage stage) throws IOException {
Label testLabel = new Label("");
VBox testBox = new VBox(testLabel);
Scene scene = new Scene(testBox);
testLabel.textProperty().bind(someStringProperty());
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
Executors.newSingleThreadExecutor().submit(new Runnable() {
#Override
public void run() {
setSomeString("new value");
}
});
}
// getters and setters
}

How to use JavaFX in Main

I am completly lost atm. I have been working with scenebuilder and javaFX in the past but I am stuck like 5 hours now and I didnt get a step further. Let me explain:
I have a working java Eclipse Project, using maven dependencies
The Main is where I want to use JavaFX or load a fxml into
The programm takes many many VCC Files and extracts the data to put it all together in an excel
The programm works but I cant load a FXML file into the main or even show a pane in there
Now does my Java Main class has to extend Application? I tried both ways - doenst work.
Some example code:
public void start(Stage primaryStage) {
try {
bpmain = new BorderPane(FXMLLoader.load(new File("src\\fxml\\UserInterface.fxml").toURI().toURL()));
primaryStage.setScene(new Scene(bpmain));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
or this (from original Docs)
public void start(Stage stage) {
Circle circ = new Circle(40, 40, 30);
Group root = new Group(circ);
Scene scene = new Scene(root, 400, 300);
stage.setTitle("My JavaFX Application");
stage.setScene(scene);
stage.show();
}
but this start method is just not getting called... where do I put that?
What my Programm should look like is pretty simple actually. I want a small UI Windows that lets you pick a Folder where the VCC data lives in and a OK Button that basically should run the Main method.
So a TextField that when its picked a Path in the Main gets replaced (filepath) and just a simple OK Button that says: yeah run the main - because the main works perfectly it is just that I cant show that ui and I dont know how to really connect it to the Main.java
Any help is appreciated - Ty
Option 1
public class Launch extends Application {
public static Stage stage = null;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
this.stage = stage;
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Option 2:
public class SidebarController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void btnHome_OnMouseClicked(MouseEvent event) throws IOException {
BorderPane borderPane = (BorderPane) ((Node) event.getSource()).getScene().getRoot();
Parent sidebar = FXMLLoader.load(getClass().getResource("/fxml/ContentArea.fxml"));
borderPane.setCenter(sidebar);
}
}

JavaFX change stage size from outside the constructor

I have something like
public class MyClass extends Application {
public void start(Stage stage) {
MyModel model = new MyModel();
MyController controller = new MyController(model);
MyView view = new MyView(model, controller);
Scene scene = new Scene(view);
stage.setTitle("MyTitle");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
view.requestFocus();
}
public void changeStageSize(int width, int height) {
...
}
public static void main(String[] args) {
launch(args);
}
}
What do I have to write into my changeStageSize void to change my stage size?
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Resize");
btn.setOnAction((ActionEvent event) -> {
changeStageSize(primaryStage, 800, 500);
primaryStage.centerOnScreen();
});
StackPane root = new StackPane(btn);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public void changeStageSize(Window stage, int width, int height) {
stage.setWidth(width);
stage.setHeight(height);
}
Just set the width and height of the Window. You could use a field instead of passing the stage parameter. If you don't do this IMHO the method should be made static, since no instance members of your application class are accessed.
Since the MyView instance is the root of the scene, from within MyView you can just do
Window win = getScene().getWindow();
win.setWidth(...);
win.setHeight(...);
There is no need to delegate this method back to the Application subclass (and you really don't want MyView to have a dependency on that anyway.

How can I change the GUI of JavaFX outside start()?

I am crazy about the feature of JavaFX, in Swing, I could do,
#Override
public void onPluginRegistered(final GamePlugin plugin) {
JRadioButtonMenuItem gameMenuItem = new JRadioButtonMenuItem(plugin.getGameName());
gameMenuItem.setSelected(false);
gameMenuItem.addActionListener(event -> {
if (core.getPlayers().isEmpty()) {
// Can't start a game with no players.
showErrorDialog(frame, ERROR_NO_PLAYERS_TITLE, ERROR_NO_PLAYERS_MSG);
gameGroup.clearSelection();
} else {
core.startNewGame(plugin);
}
});
gameGroup.add(gameMenuItem);
newGameMenu.add(gameMenuItem);
}
if I want to add a radio item whenever a plugin has registered.
However in JavaFX, it seems, you can't declare any global item of JavaFX, because once the start() is called, it starts a new constructor and everything you've done before is nothing (there is no variable share to me).
Here is my Javafx code.
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 500, 500);
scene.getStylesheets().add("./Buttons.css");
Region spacer = new Region();
spacer.setMinWidth(10);
primaryStage.setScene(scene);
primaryStage.show();
TabPane tabPane = new TabPane();
Tab tabData = new Tab("Get your data");
tabPane.getTabs().add(tabData);
Tab tabDisplay = new Tab("Visualize your data");
tabPane.getTabs().add(tabDisplay);
pluginGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle old_toggle, Toggle new_toggle) {
if (pluginGroup.getSelectedToggle() != null) {
RadioButton chk = (RadioButton) new_toggle.getToggleGroup().getSelectedToggle();
chk.getText();
}
}
});
root.setCenter(tabPane);
FlowPane inputPanel = new FlowPane();
TextField source = new TextField ();
Button confirmButton = new Button("Get Your Resource!");
confirmButton.getStyleClass().add("GREEN");
inputPanel.getChildren().addAll(new Label("Input your source:"),
spacer, source, confirmButton);
root.setBottom(inputPanel);
RadioButton defaultBtn = new RadioButton("No data plugin are registered");
FlowPane pane = new FlowPane();
pane.getChildren().addAll(new Label("Select your data source"), spacer);
if (radioButtonBox != null) {
pane.getChildren().add(radioButtonBox);
}
tabData.setContent(pane);
}
#Override
public void onPluginRegistered(DataPlugin plugin) {
RadioButton button = new RadioButton(plugin.getName());
button.setToggleGroup(pluginGroup);
radioButtonBox.getChildren().add(button);
}
public void caller(String[] args) {
launch(args);
}
I want to initialize the javafx program from,
public static void main(String[] args) throws Exception {
DataFramework core = new ConcreteDataFramework();
GuiFramework gui = new GuiFramework(core);
core.addGuiListener(gui);
gui.caller(args);
core.registerPlugin(new CsvData());
}
It is weird that I can't add any radio button to the existing radioButtonBox every time I call onPluginRegistered(DataPlugin plugin) (The new radiobutton does not show up)
You should consider the start() method as the replacement for the main method. If your application needs access to some kind of service or model, create it in the start() (or init()) method. I would actually recommend making the Application subclass (which is inherently not reusable) as minimal as possible - it should just do the startup work - and factoring the remaining GUI code into a separate class. (If you use FXML, the FXML file can define the UI, and the Application subclass is then already pretty minimal: it just loads and displays the FXML.)
You haven't really provided enough context to make it clear what's going on here, but I'm guessing GuiFramework is the Application subclass you've shown part of, and DataFramework is an interface of some kind. I also assume GuiFramework is implementing some interface that defines the onPluginRegistered method.
So I would do:
public class GuiFramework implements PluginAware {
private final BorderPane root ;
private final DataFramework dataFramework ;
public GuiFramework(DataFramework dataFramework) {
this.dataframework = dataFramework ;
this.root = new BorderPane();
TabPane tabPane = new TabPane();
Tab tabData = new Tab("Get your data");
tabPane.getTabs().add(tabData);
// etc etc (remaining code from your start() method)
}
public Parent getView() {
return root ;
}
#Override
public void onPluginRegistered(DataPlugin plugin) {
RadioButton button = new RadioButton(plugin.getName());
button.setToggleGroup(pluginGroup);
radioButtonBox.getChildren().add(button);
}
}
and define a Main class for starting the application:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
DataFramework core = new ConcreteDataFramework();
GuiFramework gui = new GuiFramework(core);
core.addGuiListener(gui);
Scene scene = new Scene(gui.getView(), 500, 500);
scene.getStylesheets().add("./Buttons.css");
primaryStage.setScene(scene);
primaryStage.show();
core.registerPlugin(new CsvData());
}
// for environments not supporting JavaFX launch automatically:
public static void main(String[] args) {
launch(args);
}
}

How to pass a JavaFx primary stage

I'm trying to find a way to access the Stage in my main JavaFx class from another class so I can perform some actions on it but I can't since it is passed as a parameter like so:
#Override
public void start(final Stage primaryStage) {
The WakiliProject Class in full:
public class WakiliProject extends Application {
#Override
public void start(final Stage primaryStage) {
Group root = new Group();
StageDraggable.stageDraggable(root, primaryStage);
root.getChildren().addAll(mainContainer);
Scene scene = new Scene(root, 900, 654);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setTitle("Wakili");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
How can I catch the above Stage primaryStage from another Class and do some actions like I do below after initializing the Stage `public Stage newTryEMail;':
public class TryEMailController implements Initializable {
// Initializes the controller class.
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public Stage newTryEMail;
public void newTryEMailStage() throws IOException {
newTryEMail = new Stage();
newTryEMail.initModality(Modality.WINDOW_MODAL);
newTryEMail.initOwner(AddNewEmailController.newComposeNewEmail);
Parent newTryEMailRoot = FXMLLoader.load(getClass().getResource("/wakiliproject/Forms/AddNew/NewEmail/TryEMailController.fxml"));
StageDraggable.stageDraggable(newTryEMailRoot, newTryEMail);
Scene newComposeNewEmailScene = new Scene(newTryEMailRoot, 590, 670);
newTryEMail.setScene(newComposeNewEmailScene);
newTryEMail.show();
}
}
from another class called TryEMailController?
Thank you all in advance.
Try it like this:
public void newTryEMailStage(Stage primaryStage) throws IOException {
newTryEMail = primaryStage;
And in the start method:
newTryEMailStage(primaryStage);
You pass the primaryStage reference from the start() method to the class that you want to have access to it. Then you store a reference to the primaryStage object in the class that you want to have access to it. If you are trying to "catch" the reference to the primaryStage object prior to the start() method running, there is no way I know of to do that. So organize your code accordingly.

Categories

Resources