Reputation: 113
This problem has been baffling me for a few hours. It isn't giving me any exceptions, the console gets updated which tells me that the method is being executed but there is no change in the ui. Here are my classes:
Controller class:
public class Controller {
public HBox billbox;
public int childnr;
public void createBill(){
System.out.println("Creating");
TableView<Item> bill = new TableView<>();
DropShadow dropShadow = new DropShadow();
dropShadow.setRadius(5.0);
dropShadow.setOffsetX(3.0);
dropShadow.setOffsetY(3.0);
dropShadow.setColor(Color.color(0.4, 0.5, 0.5));
VBox fullbill = new VBox();
fullbill.setPadding(new Insets(1,1,1,1));
fullbill.getStyleClass().add("fullbill");
TableColumn<Item,String> nameColumn = new TableColumn<>("Emri");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<Item,String> quantsColumn = new TableColumn<>("Sasia");
quantsColumn.setMinWidth(50);
quantsColumn.setCellValueFactory(new PropertyValueFactory<>("quants"));
double tablewidth = nameColumn.getWidth() + quantsColumn.getWidth();
Label tablenrlabel = new Label("Table 5");
tablenrlabel.getStyleClass().add("tablenr-label");
tablenrlabel.setMinWidth(tablewidth);
Button closebutton = new Button("Mbyll");
closebutton.setMinWidth(tablewidth);
closebutton.getStyleClass().add("red-tint");
bill.setItems(getItem());
bill.setMinWidth(256);
bill.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
bill.getColumns().addAll(nameColumn,quantsColumn);
fullbill.setEffect(dropShadow);
fullbill.getChildren().addAll(tablenrlabel,bill,closebutton);
billbox.getChildren().addAll(fullbill);
childnr += 1;
//Loops over every button in every vbox and gives it a seperate listener (the index of the button is hardcoded so it can cause problems if you add more items)
for(int i = 0; i < childnr; i++){
VBox box = (VBox) billbox.getChildren().get(i);
Button btn = (Button) box.getChildren().get(2); //if sudden issues change this
btn.setId(Integer.valueOf(i).toString());
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
int index = billbox.getChildren().indexOf(btn.getParent());
billbox.getChildren().remove(index);
childnr -= 1;
System.out.println(btn.getId());
}
});
}
System.out.println("done");
}
public ObservableList<Item> getItem(){
ObservableList<Item> items = FXCollections.observableArrayList();
items.add(new Item("Fanta",1));
items.add(new Item("Kafe",1));
items.add(new Item("Schweps",1));
return items;
}
Class that calls controller createBill() Method:
public void run(){
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
URL location = getClass().getResource("sample.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
Parent root = (Parent) fxmlLoader.load(location.openStream());
Controller controller = fxmlLoader.<Controller>getController();
root.setUserData(controller);
controller.createBill();
}catch (Exception x){
System.out.println(x);
}
}
});
}
And here's my main method:
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("uPick Smart Service");
primaryStage.setScene(new Scene(root, 1600, 600));
primaryStage.show();
}
public static void main(String args[]){
launch(args);
}
}
Upvotes: 0
Views: 316
Reputation: 209330
FXMLLoader.load()
loads an FXML file and creates an object hierarchy out of it: that is it creates a new object corresponding to the class specified in the root element, and sets properties on it (usually setting those properties involves creating further objects, etc). The controller that the FXMLLoader
(usually) creates is associated with that particular object hierarchy.
In your run()
method, you load an FXML file, and retrieve the associated controller, but you never actually display the UI defined by the FXML file:
URL location = getClass().getResource("sample.fxml");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
// Loads the FXML file and creates a bunch of objects,
// but you never display the result: you do nothing with root:
Parent root = (Parent) fxmlLoader.load(location.openStream());
// retrieve the controller associate with root:
Controller controller = fxmlLoader.<Controller>getController();
// not sure what this is for...
root.setUserData(controller);
// now call a method on the controller.
controller.createBill();
When you call controller.createBill()
, it modifies the UI elements the controller is associated with, so it modifies root
and its child elements. However, since root
is never displayed anywhere, you never see the result.
Note that you load the same FXML file twice, so you have two copies of the UI it defines, along with two instances of the controller class. Each instance of the controller is associated with one instance of the UI. The UI that you get from loading the FXML file in your start()
method is the one that is displayed; so to modify what that UI looks like, you need to call methods on the controller instance that is created by the FXMLLoader
you create there, not some other FXMLLoader
.
Upvotes: 2