My code:
Main class:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
Scene scene = new Scene(fxmlLoader.load());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Base.java
#DefaultProperty("children")
public class Base extends HBox {
public final ObservableList<Node> children;
public final VBox foundation;
public Base() {
foundation = new VBox();
children = foundation.getChildren();
super.getChildren().add(foundation);
}
public final ObservableList<Node> getChildren() {
return children;
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import sample.Base?>
<?import javafx.scene.control.Button?>
<Base xmlns:fx="gui" fx:controller="sample.Controller">
<children>
<Button text="test"/>
</children>
</Base>
The Scene object in the Main class is not null. Controller.java is empty.
Why doesn't my button show up? Any ideas?
BTW. The stage (window) is being sized like there IS some button, but it is not visible (maybe it's under some node? but how come?)
I'm using OpenJDK & OpenJFX (14.0.1)
Related
Somehow, I cannot add items to my ComboBox variable from another class as it always says either the value of variable is null or the return value of its getter is null.
I use Scene Builder to build Sample.fxml, with controller as Controller class, luanch the whole thing form UserInterface class
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<center>
<ComboBox fx:id="myBox" prefWidth="150.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
Controller
public class Controller {
#FXML
private ComboBox<String> myBox;
public ComboBox<String> getMyBox() {
return myBox;
}
public void initialize() {
ObservableList<String> defaultTicker = FXCollections.observableArrayList("Something");
myBox.getItems().addAll(defaultTicker);
}
}
UserInterface
public class UserInterface extends Application {
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Sample.fxml"));
Parent root = loader.load();
Controller controller = new Controller();
primaryStage.setTitle("Title");
primaryStage.setScene(new Scene(root));
primaryStage.show();
List<String> addStuff = new ArrayList<String>();
addStuff.add("a");
addStuff.add("b");
addStuff.add("c");
controller.getMyBox().getItems().addAll(addStuff);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
After running, the interface appears, with only the option "Something" in it. So I guess it initialize fine?
The interface after launch
What did I do wrong? I couldn't seem to find any solutions so far.
Thanks in advance.
I have a root screen which generates a popup and in popup I have a listview with button on it and I want to update the texfield in root screen and close the popupwindow when a button is clicked in popup. Code for popup and its controller.
POPUP
public void display() throws IOException {
Stage window =new Stage();
FXMLLoader loader=new FXMLLoader();
Parent root = loader.load(getClass().getResource("/ProfilePopup.fxml"));
window.setTitle("Your profile");
window.setScene(new Scene(root, 400, 500));
window.show();
}
PopUPController
public void initialize() {
listView.setEditable(true);
listView.setVisible(true);
listView.setItems(walletModel.myWallets);
listView.setCellFactory(param -> {
try {
return new EditableCell();
} catch (IOException e) {
e.printStackTrace();
}
return null;
});
listView.layout();
addWalletButton.setOnMouseClicked(event -> {
walletModel.createWallet();
listView.getFixedCellSize();
size.setText("Total Wallets: " + walletModel.walletSize());
});
if (walletModel.myWallets.size() == 0) {
walletModel.initializeWalletData();
walletModel.myWallets.add(walletModel.initializeWalletData());
}
size.setText("Wallet Size " + walletModel.walletSize());
}
static class EditableCell extends ListCell<WalletModel.WalletData> {
private final WalletCellController controller;
EditableCell() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/selectButton.fxml"));
Node graphic = loader.load();
controller = loader.getController();
setGraphic(graphic);
}
#Override
protected void updateItem(WalletModel.WalletData item, boolean empty) {
if (empty) {
controller.rootView.setVisible(false);
} else {
controller.textField.setText(item.getName());
controller.rootView.setVisible(true);
}
}
}
}
I want the button on listview to update the root screen when its clicked and plus close the popup as well. Each listview is getting graphics from walletcellcontroller code below.
Here is how I am calling from the root screen.
Creating instance in root screen and then calling
(Popup popup=new Popup();)
public void popupOpen() throws IOException {
popup.display();
}
here is the code for listview item
public class WalletCellController implements OnClick {
public Button select;
public TextField textField;
public AnchorPane rootView;
public void initialize(){
onMouseClicked();
}
public void onMouseClicked() {
select.setOnAction(closeEvent -> {
Node source = (Node) closeEvent.getSource();
Stage stage = (Stage) source.getScene().getWindow();
stage.close();
});
}}
Can you tell me how to use the callbacks for actionevents here. I think I need call back from POPUP Controller to POPup and then from POPup to root screen.
I am new in java so I not sure about the implementation of it.
interface Callable {
public void callBackMethod();
}
class Worker {
// Worker gets a handle to the boss object via the Callable interface.
// There's no way this worker class can call any other method other than
// the one in Callable.
public void doSomeWork(Callable myBoss) {
myBoss.callBackMethod();
// ERROR!
//myBoss.directMethod();
}
}
class Boss implements Callable {
public Boss() {
// Boss creates a worker object, and tells it to do some work.
Worker w1 = new Worker();
// Notice, we're passing a reference of the boss to the worker.
w1.doSomeWork(this);
}
//developer that develop library just call controll the place of calling
public void callBackMethod() {
System.out.println("What do you want?");
}
public void directMethod() {
System.out.println("I'm out for coffee.");
}
}
public class Main {
public static void main(String[] args) {
Boss b = new Boss();
b.directMethod();
// write your code here
}
}
this is sample code of call back method
In cases like these I recommend using Dialog, since it allows you to query & wait for user input.
Example
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Dialog?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<Dialog xmlns:fx="http://javafx.com/fxml/1" fx:id="dialog" fx:controller="fxml.DialogController">
<dialogPane>
<DialogPane headerText="Choose item!">
<content>
<VBox prefWidth="100" spacing="5">
<children>
<Button text="a" onAction="#choice" maxWidth="Infinity" />
<Button text="b" onAction="#choice" maxWidth="Infinity" />
<Button text="c" onAction="#choice" maxWidth="Infinity" />
<Button text="Cancel" onAction="#cancel" maxWidth="Infinity" />
</children>
</VBox>
</content>
</DialogPane>
</dialogPane>
</Dialog>
public class DialogController {
#FXML
private Dialog<String> dialog;
#FXML
private void choice(ActionEvent event) {
Button source = (Button) event.getSource();
dialog.setResult(source.getText());
dialog.close();
}
#FXML
private void cancel() {
dialog.setResult("");
dialog.close();
}
}
#Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
Button btn = new Button("Choose");
btn.setOnAction((ActionEvent event) -> {
Dialog<String> dialog;
try {
dialog = FXMLLoader.load(getClass().getResource("/fxml/Dialog.fxml"));
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
Optional<String> result = dialog.showAndWait();
if (!result.orElse("").isEmpty()) {
textField.setText(s);
}
});
VBox root = new VBox(textField, btn);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
How would you implement a full screen feature that can be toggled by pressing F11?
You can add an EventHandler to the primaryStage where you specify the functionality like:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
AnchorPane pane = loader.load();
primaryStage.setScene(new Scene(pane, 400, 400));
primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
if (KeyCode.F11.equals(event.getCode())) {
primaryStage.setFullScreen(!primaryStage.isFullScreen());
}
});
primaryStage.show();
}
}
Just to be complete:
View.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="stackoverflow.testfullscreen.Controller">
</AnchorPane>
Controller:
public class Controller implements Initializable {
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
I didn't implement a webview, but it should work with any scene.
I need to pass a Stage to my Filechooser in the Controller Class.
For that I need to set a Controller in my MainDesignClass.
What is wrong here:
#Override
public void start( Stage primaryStage) throws Exception{
FXMLLoader loader= new FXMLLoader(getClass().getResources("myfxml.fxml");
Parent root =(Parent)loader.load();
primaryStage = new Stage();
Controller myController=loader.getController();
myController.setStage(primaryStage);
primaryStage.setTitle("myapp");
primaryStage.getIcons().add(image);
primaryStage.setScene(new Scene(root,900,600));
primaryStage.show();
}
setStage is marked red. But why? Why it cannot find the method? How can I use FileChooser then in my Controller.class ?
To use Controller you must set it in your FXML file in a parent object like this
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="157.0" prefWidth="430.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controllers.Controller">
Ok, I got this solved:
Main Class
public class Main extends Application {
private static Stage primaryStage; // Declare static Stage, so it can also be accessed in the controller and if you walk through Files!
private void setPrimaryStage(Stage stage) {
Main.primaryStage = stage;
}
static public Stage getPrimaryStage() {
return Main.primaryStage;
}
#Override
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage); // **Set the Stage**
//get new instance of FXMLLoader
FXMLLoader loader= new FXMLLoader(getClass().getResources("myfxml.fxml");
Parent root =(Parent)loader.load();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
}
instanceofmain.getPrimaryStage()
In Controller Class
public class Controller {
private Main mymainclass; //you need an instance of the main class to open the stage on this very instance, as it is static you will be able to get it then.
public void onMouseClickAction(ActionEvent e) {
Stage s = mymainclass.getPrimaryStage();
// do not apply any close actions, as you want to stay on the same stage
FileChooser chooser= new Filechooser();
File defaultfile = chooser.showOpenDialog(s); // for directories the command is showDialog(s);
}
}
There were no other threads related to my specific problem.
I was doing this tutorial in JavaFX and got a null pointer exception on the line marked by " <<--NullPointerException". I just couldnt understand why this is happening. Any help? The method to which "this" goes is also given. The rest of codes are pretty much correct Im sure. The error description is also given.
public class MainApp extends Application{
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Person> personData = FXCollections.observableArrayList();
public MainApp() {
personData.add(new Person("Stefan", "Meier"));
personData.add(new Person("Martin", "Mueller"));
}
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
try {
FXMLLoader loader = new FXMLLoader(ClassLoader.getSystemResource("sample.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException iox){
iox.printStackTrace();
}
showPersonOverview();
}
public Stage getPrimaryStage() {
return primaryStage;
}
public void showPersonOverview() {
try {
FXMLLoader loader = new FXMLLoader(ClassLoader.getSystemResource("fxcontroller.fxml"));
AnchorPane overviewPage = (AnchorPane) loader.load();
rootLayout.setCenter(overviewPage);
// Give the controller access to the main app
Controller controller = loader.getController();
controller.setMainApp(this); // <<--NullPointerException
} catch (IOException e) {
e.printStackTrace();
}
}
public ObservableList<Person> getPersonData(){
return personData;
}
public static void main(String[] args) {
launch(args);
}
}
method setMainApp() in Class Controller. The other codes in this class is correct that I'm sure as most are just set and get or create buttons and labels.
#FXML
private TableView<Person> personTable;
private MainApp mainApp;
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
personTable.setItems(mainApp.getPersonData());
}
This is first portion of fxcontroller.fxml file which gives AnchorPane
<?xml version="1.0" encoding="UTF-8"?>
//import statements
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
.....
The error message:
Exception in Application start method
java.lang.reflect.InvocationTargetException
....
Caused by: **java.lang.NullPointerException**
....
Sorry to make the description too long. I wish I knew how to make it shorter.
Your controller cannot be loaded. That's why you get nullpointerexception.
may be controller path is wrong
or you did some mistake to specify controller in fxml file