I can't display my Observable List in the table view. I don't get any error. I was check if Observable List and List have value and everything looks fine. I don't have any idea where is a problem. I was try to add ValueFactory also in FXML code and it still don't work
FXML
<TableView fx:id="laczenie" layoutX="641.0" layoutY="52.0" prefHeight="415.0" prefWidth="438.0">
<columns>
<TableColumn prefWidth="75.0" text="Wezly" fx:id="C1" >
</TableColumn>
<TableColumn prefWidth="361.0" text="MozliwePolaczenia" fx:id="C2">
</TableColumn>
</columns>
</TableView>
JavaFx Controller
public class FXMLDocumentController implements Initializable {
private JavaFXApplication4 mainApp;
public List<Krawendzie> list = new ArrayList<Krawendzie>();
#FXML
private TableColumn C1;
#FXML
private TableColumn C2;
#FXML
private TableView<Krawendzie> laczenie;
#FXML
private Label label;
#FXML
private ComboBox<String> combo;
#FXML
private GridPane Scena;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
C1.setCellValueFactory(new PropertyValueFactory<Krawendzie,Integer>("Wezel"));
C2.setCellValueFactory(new PropertyValueFactory<Krawendzie,Integer>("Mozliwosci"));
combo.getItems().addAll("2","3","4","5","6","7","8");
list.removeAll(list);
}
#FXML
private void itemselected(ActionEvent event){
}
#FXML
private void rysuj(ActionEvent event) {
rysuj2(Integer.parseInt(combo.getValue()));
}
private void rysuj2(Integer Ilosc){
list.removeAll(list);
Scena.getChildren().clear();
laczenie = new TableView<Krawendzie>();
File f = new File("././Image/Imapges1.jpg");
Image image = new Image(f.toURI().toString());
Integer ilosc = 0;
for (int i = 0; i<=Ilosc;i++)
{
for(int k = 1;k<Scena.getColumnConstraints().size();k=k+2)
{
if(k%2 != 0)
{
Circle circle = new Circle(20, 20, 20);
circle.setFill(new ImagePattern(image));
Scena.add(circle,k,i);
list.add(new Krawendzie(ilosc,ilosc));
ilosc++;
}
if(ilosc == Ilosc)
break;
}
if(ilosc == Ilosc)
break;
}
getData();
}
public void getData()
{
ObservableList<Krawendzie> obsList = FXCollections.observableArrayList(list);
laczenie.setItems(obsList);
//return obsList;
}
}
And Main Application
public class JavaFXApplication4 extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
sorry for question i have an answer. I only need to delete
laczenie = new TableView();
because i was create a new object of talbeview so i can't work
Related
I am trying to run a method in a controller class specified to a particular task, once a specified key is pressed using KeyListener. But i'm unable to detect the keypress and invoke the java.awt.event keyPressed method. My code is as follows :
public class POSController implements KeyListener {
#Override
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == com.sun.glass.events.KeyEvent.VK_F1) {
try {
paymentAction();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
What could have gone wrong? Thanks in advance.
Here is the minimal executable example of the problem.
public class POSController implements KeyListener {
#FXML
private TableView<Product> productTableView;
#FXML
private TableView<Item> listTableView;
#FXML
private MenuItem logoutItem, profile;
#FXML
private javafx.scene.image.ImageView backImage;
#FXML
private MenuButton menuButton;
#FXML
private TableColumn<Item, String> itemColumn;
#FXML
private ComboBox<String> clientId, paymentMethod;
#FXML
private TableColumn<Item, Double> priceColumn, totalColumn, discountPercentageColumn, amountColumn;
#FXML
private TableColumn<Item, Integer> quantityColumn;
#FXML
private TableColumn<Product, String> productColumn;
#FXML
private TextField searchField,discountPercentage,productField,priceField,quantityField,vatPercentage,subTotalField,discountField,totalVatField,vatField,netPayableField,totalDiscountField;
#FXML
private TextField ;
#FXML
private TextField ;
#FXML
private TextField ;
#FXML
private TextField ;
#FXML
private TextArea descriptionArea;
#FXML
private Button addButton, removeButton, paymentButton, resetTableButton, resetButton;
#FXML
private Label quantityLabel, errorLabel, userName, backLabel;
#FXML
private ObservableList<Item> ITEMLIST;
public static Scene paymentScene;
private double xOffset = 0;
private double yOffset = 0;
public static double finalNetPayablePrice = 0.0;
public static double finalSubTotalPrice = 0.0;
public static double finalVat = 0.0;
public static double finalDiscount = 0.0;
public static String clientName = null;
public static String selectedPaymentMethod = null;
public static List<String> itemNames = new ArrayList<>();
public static List<Double> itemDiscounts = new ArrayList<>();
public static List<String> prices = new ArrayList<>();
public static List<String> quantities = new ArrayList<>();
public static List<String> subTotals = new ArrayList<>();
public static ObservableList<Item> itemList;
public static List<String> columnItemData = new ArrayList<>();
public static List<String> columnQuantityData = new ArrayList<>();
#FXML
private void initialize() throws SQLException, ClassNotFoundException, IOException {
ObservableList<Product> productsData = ProductDAO.searchGoodProducts(app.values.getProperty("STATUS_TYPE1"));
populateProducts(productsData);
}
#FXML
private void populateProducts(ObservableList<Product> productData) throws ClassNotFoundException {
productTableView.setItems(productData);
}
#Override
public void keyTyped(java.awt.event.KeyEvent e) {
}
#Override
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_F1) {
try {
paymentAction();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
#Override
public void keyReleased(java.awt.event.KeyEvent e) {
}
#FXML
public void paymentAction() throws Exception {
if (validateInputsForPayment()) {
Payment payment = new Payment();
FXMLLoader loader = new FXMLLoader((getClass().getResource(app.values.getProperty("INVOICE_VIEW_LOCATION"))));
Parent root = loader.load();
Stage stage = new Stage();
root.setOnMousePressed((MouseEvent e) -> {
xOffset = e.getSceneX();
yOffset = e.getSceneY();
});
root.setOnMouseDragged((MouseEvent e) -> {
stage.setX(e.getScreenX() - xOffset);
stage.setY(e.getScreenY() - yOffset);
});
Scene scene = new Scene(root);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initStyle(StageStyle.UNDECORATED);
stage.setScene(scene);
this.paymentScene = scene;
stage.showAndWait();
}
}
You shouldn't be using java.awt.event.KeyListener for a JavaFX application. JavaFX has its own set of event API.
Assuming that POSController is a controller class for a particular FXML:
public class POSController {
#FXML private BorderPane root; // Or any other Node from FXML file
#FXML private void initialize() {
javafx.event.EventHandler<javafx.scene.input.KeyEvent> handler = event -> {
if (event.getCode() == javafx.scene.input.KeyCode.F1) {
try {
paymentAction();
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
// I'm using root to get scene, but any node would be fine
if (root.getScene() != null) {
root.getScene().addEventHandler(javafx.scene.input.KeyEvent.KEY_PRESSED, handler);
}
else {
root.sceneProperty().addListener((obs, oldScene, newScene) -> {
if (newScene != null) {
root.getScene().addEventHandler(javafx.scene.input.KeyEvent.KEY_PRESSED, handler);
}
});
}
}
}
This will add the key event to the Scene. If you do not need to apply this event scene-wide, then you can add the event handler at other appropriate nodes.
Update
If there are any input controls in the scene, then you may need to use setEventFilter() instead of setEventHandler(). This is because those controls are probably going to consume the key event during the event bubbling phase.
My UI has a adding button and I want to assign a keyboard shortcut combination for that. I have failed to use the setAcceleartor for this purpose.
What is the easiest way to set up keyboard shortcuts in javafx applications?
button declaration in the UI:
<Button fx:id="addButton" alignment="CENTER" minWidth="-Infinity" mnemonicParsing="false" onAction="#addAction" prefHeight="31.0" prefWidth="130.0" text="Add" HBox.hgrow="ALWAYS" />
Controller button binding:
#FXML
private Button addButton;
The method that wants to setOnAction for the shortcut for the button:
public void addAction(ActionEvent event) throws SQLException, ClassNotFoundException {
if (validateInput()) {
String productName = productField.getText();
double unitPrice = Double.parseDouble(priceField.getText());
int quantity = Integer.parseInt(quantityField.getText());
double total = unitPrice * quantity;
ITEMLIST.add(new Item(productName, unitPrice, quantity, total));
calculation();
resetAdd();
productTableView.getSelectionModel().clearSelection();
ObservableList<Product> productsData = ProductDAO.searchProducts();
populateProducts(productsData);
searchField.setText("");
}
}
initialize() method:
#FXML
private void initialize() throws SQLException, ClassNotFoundException, IOException {
setSaveAccelerator(addButton);
}
The code I tried with setAccelerator:
private void setSaveAccelerator(final Button button) {
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
In your setSaveAccelerator method, instead of directly calling addAction(ActionEvent event), just instruct the button to fire its event to its listeners such as: button.fire(). For example:
private void setSaveAccelerator(Button button) {
if(button==null) {
System.out.println("Button is null! "); // check that the button was injected properly through your fxml
}
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
EDIT
To also avoid the IllegalArgumentException you must attach the accelerator after the button is attached to a scene. I managed to achieve this by creating a public method in the controller to attach the accelerator after the scene has been set. Then, in the class where the scene is loaded the controller's method can be called which sets up this functionality. See the example below:
In the controller class (in my case MainController):
public void setup() {
setSaveAccelerator(button);
}
In your main class when loading the fxml file:
FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
AnchorPane page = (AnchorPane) loader.load();
MainController controller = loader.getController();
Scene scene = new Scene(page);
controller.setup(); // calls the setup method attaching the accelerators
FULL EXAMPLE
Main class:
public class Main extends Application{
public static Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception {
Main.primaryStage=primaryStage;
FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
AnchorPane page = (AnchorPane) loader.load();
MainController controller = loader.getController();
Scene scene = new Scene(page);
primaryStage.setTitle("Shortcut example");
primaryStage.setScene(scene);
controller.setup();
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Maincontroller:
public class MainController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button button;
#FXML
private AnchorPane rootPane;
#FXML
private TextArea textarea;
#FXML
void action(ActionEvent event) {
textarea.setText("Action fired!!");
}
#FXML
void initialize() {
assert button != null : "fx:id=\"button\" was not injected: check your FXML file 'MainFXML.fxml'.";
assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'MainFXML.fxml'.";
assert textarea != null : "fx:id=\"textarea\" was not injected: check your FXML file 'MainFXML.fxml'.";
}
public void setup() {
setSaveAccelerator(button);
}
private void setSaveAccelerator(Button button) {
if(button==null) {
System.out.println("Button null!!");
}
Scene scene = button.getScene();
if (scene == null) {
throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene");
}
scene.getAccelerators().put(
new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN),
new Runnable() {
#FXML public void run() {
button.fire();
}
}
);
}
}
MainFXML.fxml
<AnchorPane fx:id="rootPane" prefHeight="408.0" prefWidth="330.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<Button fx:id="button" layoutX="139.0" layoutY="350.0" mnemonicParsing="false" onAction="#action" text="Button" />
<TextArea fx:id="textarea" layoutX="73.0" layoutY="38.0" prefHeight="200.0" prefWidth="200.0" />
</children>
</AnchorPane>
I tried a lot but my value entered in the textfield is not getting populated to tableview when add button is clicked.Please give me a solution to populate values into the tableview whenever i click on add button !
public class Refreshtable extends Application {
#FXML
private TextField fname;
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primarystage) {
Scene scene = new Scene(new Group());
// this.primaryStage.setTitle("Table View Sample");
primarystage.setWidth(450);
primarystage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory("firstName"));
table.setItems(data);
table.getColumns().addAll(firstNameCol);
final Button addButton = new Button("Add");
addButton.setOnAction((ActionEvent e) -> {
System.out.println("u entered");
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Refreshtable.class.getResource("newaddframe.fxml"));
AnchorPane anchorpane = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Main");
dialogStage.initModality(Modality.WINDOW_MODAL);
Scene scenee = new Scene(anchorpane);
dialogStage.setScene(scenee);
dialogStage.showAndWait();
} catch (IOException es) {
es.printStackTrace();}
});
hb.getChildren().addAll(addButton);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll( table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
primarystage.setScene(scene);
primarystage.show();
}
#FXML
private void addd(){
data.add(new Person(
fname.getText()));
fname.clear();
}
public static class Person {
private final SimpleStringProperty firstName;
private Person(String fName) {
this.firstName = new SimpleStringProperty(fName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
}
}
I will not talk about the (many) issues with your code and keep the answer short, addressing your original problem.
You need to add the data entered by the user to the ObservableList backing the TableView.
#FXML
private void update()
{
...
// Create new instance of UserData
UserData userData = new UserData(name.getText(), country.getText());
// Add it to the backing list
data.add(userData);
}
Sample refresh tableview code:
Cloud.java
public class Cloud extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
/**
* The data as an observable list of Persons.
*/
private ObservableList<Person> personData = FXCollections.observableArrayList();
/**
* Constructor
*/
public Cloud() {
}
/**
* Returns the data as an observable list of Persons.
* #return
*/
public ObservableList<Person> getPersonData() {
return personData;
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
// Set the application icon.
this.primaryStage.getIcons().add(new Image("file:resources/images/address_book_32.png"));
showPersonOverview();
}
/**
* Initializes the root layout and tries to load the last opened
* person file.
*/
/**
* Shows the person overview inside the root layout.
*/
public void showPersonOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Cloud.class.getResource("root.fxml"));
AnchorPane personOverview = (AnchorPane) loader.load();
Stage dialogStagee = new Stage();
dialogStagee.setTitle("Edit Person");
dialogStagee.initModality(Modality.WINDOW_MODAL);
dialogStagee.initOwner(primaryStage);
Scene scene = new Scene(personOverview);
dialogStagee.setScene(scene);
// Give the controller access to the main app.
rootcontroller controller = loader.getController();
controller.setMainApp(this);
dialogStagee.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Opens a dialog to edit details for the specified person. If the user
* clicks OK, the changes are saved into the provided person object and true
* is returned.
*
* #param person the person object to be edited
* #return true if the user clicked OK, false otherwise.
*/
public boolean showPersonEditDialog(Person person) {
try {
// Load the fxml file and create a new stage for the popup dialog.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Cloud.class.getResource("add.fxml"));
AnchorPane page = (AnchorPane) loader.load();
// Create the dialog Stage.
Stage dialogStage = new Stage();
dialogStage.setTitle("Edit Person");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
// Set the person into the controller.
addcontroller controller = loader.getController();
controller.setDialogStage(dialogStage);
controller.setPerson(person);
// Set the dialog icon.
dialogStage.getIcons().add(new Image("file:resources/images/edit.png"));
// Show the dialog and wait until the user closes it
dialogStage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
Person.java
public class Person {
private final StringProperty firstName;
private final StringProperty lastName;
/**
* Default constructor.
*/
public Person() {
this(null, null);
}
/**
* Constructor with some initial data.
*
* #param firstName
* #param lastName
*/
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
}
addcontroller.java
public class addcontroller {
#FXML
private TextField firstNameField;
#FXML
private TextField lastNameField;
private Stage dialogStage;
private Person person;
// private boolean okClicked = false;
public void setDialogStage(Stage dialogStage) {
this.dialogStage = dialogStage;
}
/**
* Sets the person to be edited in the dialog.
*
* #param person
*/
public void setPerson(Person person) {
this.person = person;}
#FXML
private void handleOk() {
person.setFirstName(firstNameField.getText());
person.setLastName(lastNameField.getText());
dialogStage.close();
}
}
rootcontroller.java
public class rootcontroller {
#FXML
private TableView<Person> personTable;
#FXML
private TableColumn<Person, String> firstNameColumn;
#FXML
private TableColumn<Person, String> lastNameColumn;
// Reference to the main application.
private Cloud mainApp;
/**
* The constructor.
* The constructor is called before the initialize() method.
*/
public rootcontroller() {
}
#FXML
private void initialize() {
// Initialize the person table with the two columns.
firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
}
public void setMainApp(Cloud mainApp) {
this.mainApp = mainApp;
personTable.setItems(mainApp.getPersonData());
}
#FXML
private void handleNewPerson() {
Person tempPerson = new Person();
System.out.println("1");
mainApp.showPersonEditDialog(tempPerson);
mainApp.getPersonData().add(tempPerson);
}
}
root.fxml
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cloud.rootcontroller">
<children>
<TableView fx:id="personTable" layoutX="215.0" layoutY="106.0" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn fx:id="firstNameColumn" prefWidth="75.0" text="name" />
<TableColumn fx:id="lastNameColumn" prefWidth="75.0" text="country" />
</columns>
</TableView>
<Button layoutX="415.0" layoutY="334.0" mnemonicParsing="false" onAction="#handleNewPerson" text="add" />
</children>
</AnchorPane>
add.fxml
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cloud.addcontroller">
<children>
<TextField fx:id="firstNameField" layoutX="97.0" layoutY="113.0" />
<TextField fx:id="lastNameField" layoutX="259.0" layoutY="113.0" />
<Button layoutX="451.0" layoutY="113.0" mnemonicParsing="false" onAction="#handleOk" text="save" />
</children>
</AnchorPane>
I have seen a lot of question similar to mine, but I didn't figure it out how to solve my problem, so there is my code:
I have a simple main:
MainClassFXGui.java
public class MainClassFXGui extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
and three fxml files, one of them that contains the other two, by the tag
<fx:include source="MyTab1.fxml" />
MyProgramMainGuiTab.fxml
...
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5000.0" prefWidth="5000.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab closable="false" text="MyTab1">
<content>
<fx:include source="MyTab1.fxml" />
</content>
</Tab>
<Tab closable="false" text="MyTab2">
<content>
<fx:include source="MyTab2.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
...
and three controller:
MyProgramMainGuiTabController.java
....
#FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
public void setLeftSt(String st){
LeftSt.setText(st);
}
...
MyTab1Controller.java
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
I tried in this way:
MyTab1Controller.java
private MyProgramMainGuiTabController controller;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
controller.setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
FXMLLoader fxmlLoader = new
FXMLLoader(getClass().getResource("MyProgramMainGuiTab.fxml"));
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
controller = (MyProgramMainGuiTabController)fxmlLoader.getController();
}
But I have a null pointer exception or if I move the code for the instanzialization of the object 'controller' in the handleButtonAction function, I don't have any error, but the label does not change.
Maybe I can create a static Scene and a static Stage in the MainClassFXGui.java?
but then I don't know how I could use them...
MainClassFXGui.java
public class MainClassFXGui extends Application {
static private Scene scene;
static private Stage stage;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
this.scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
this.stage = stage;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static Scene getScene(){
return AssicurazioneFXGui.scene;
}
public static Stage getStage(){
return AssicurazioneFXGui.stage;
}
}
can I do something with getScene() or getStage()? any idea or suggest?
thanks to everyone
Define a StringProperty in MyTab1Controller, with the usual methods:
public class MyTab1Controller {
private final StringProperty leftSt = new SimpleStringProperty();
public StringProperty leftStProperty() {
return leftSt ;
}
public final String getLeftSt() {
return leftStProperty().get();
}
public final void setLeftSt(String leftSt) {
leftStProperty().set(leftSt);
}
// ...
#FXML
public void handleButtonAction() {
setLeftSt(...);
}
// ...
}
Now assign an fx:id attribute to the fx:include tag:
<Tab closable="false" text="MyTab1">
<content>
<fx:include fx:id="myTab1" source="MyTab1.fxml" />
</content>
</Tab>
This means you can inject the controller for MyTab1.fxml into the controller for the FXML where it is included (MyProgramMainGuiTabController):
public class MyProgramMainGuiTabController {
#FXML
private MyTab1Controller myTab1Controller ;
}
and then you can just observe the property and update the label when it changes:
public class MyProgramMainGuiTabController {
#FXML
private MyTab1Controller myTab1Controller ;
#FXML
private Label leftSt;
public void initialize() {
leftSt.setText("");
myTab1Controller.leftStProperty().addListener((obs, oldValue, newValue) ->
leftSt.setText(newValue));
}
}
Note the rule here is that the field name for the controller is the value of the fx:id attribute with the word "Controller" appended: myTab1 in the fx:id resolves to myTab1Controller for the field where the controller is injected. See NestedControllers for more information.
At the moment I have solved in this way. If anyway someone has a better solution, please write. Also because this does not solve the problem if I need to execute a function.. thanks
MyProgramMainGuiTabController.fxml
...
#FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
...
MyTab1Controller.fxml
#FXML
private Button myObject;
private Scene scene;
private Label lblDataLeft;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("this works!");
}
public void setLeftSt(String st){
if(this.scene == null)
this.scene = myObject.getScene();
if(this.lblDataLeft==null)
this.lblDataLeft = (Label) scene.lookup("#LeftSt");
if (this.lblDataLeft!=null)
this.lblDataLeft.setText(st);
}
I have the following problem. When I press the Button, I execute a Service that parses an html page and puts the results in a table. When I click on the table, while the Service is running, the Service will be terminated.
Can someone help me with this problem?
Here is my controller class:
public class ProxySearchController implements Initializable {
private Scene scene;
#FXML
private Button btn_refresh;
#FXML
private TableView<ProxyResult> tbl_results;
#FXML
private ProgressBar pb_search;
#FXML
private TableColumn<ProxyResult, String> column_ip;
#FXML
private TableColumn<ProxyResult, Integer> column_port;
#FXML
private TableColumn<ProxyResult, Locale> column_locale;
#FXML
private TableColumn<ProxyResult, String> column_anonymity;
#FXML
private TableColumn<ProxyResult, Boolean> column_google;
#FXML
private TableColumn<ProxyResult, Boolean> column_https;
#FXML
private TableColumn<ProxyResult, String> column_lastchecked;
#FXML
private TableColumn<ProxyResult, Long> column_response;
private ObservableList<ProxyResult> data = FXCollections.observableArrayList();
/*
* (non-Javadoc)
*
* #see javafx.fxml.Initializable#initialize(java.net.URL, java.util.ResourceBundle)
*/
#Override
public void initialize(URL location, ResourceBundle resources) {
tbl_results.setItems(data);
tbl_results.getSelectionModel().setCellSelectionEnabled(true);
Clipboard clipboard = Clipboard.getSystemClipboard();
// add listner to your tableview selecteditemproperty
tbl_results.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ProxyResult>() {
#Override
public void changed(ObservableValue observable, ProxyResult oldValue, ProxyResult newValue) {
ObservableList<TablePosition> posList = tbl_results.getSelectionModel().getSelectedCells();
int old_r = -1;
StringBuilder clipboardString = new StringBuilder();
for (TablePosition p : posList) {
int r = p.getRow();
int c = p.getColumn();
Object cell = tbl_results.getColumns().get(c).getCellData(r);
if (cell == null)
cell = "";
if (old_r == r)
clipboardString.append('\t');
else if (old_r != -1)
clipboardString.append('\n');
clipboardString.append(cell);
old_r = r;
}
final ClipboardContent content = new ClipboardContent();
content.putString(clipboardString.toString());
Clipboard.getSystemClipboard().setContent(content);
}
});
column_ip.setCellValueFactory(new PropertyValueFactory<ProxyResult, String>("ip"));
column_port.setCellValueFactory(new PropertyValueFactory<ProxyResult, Integer>("port"));
column_locale.setCellValueFactory(new PropertyValueFactory<ProxyResult, Locale>("locale"));
column_anonymity.setCellValueFactory(new PropertyValueFactory<ProxyResult, String>("anonymity"));
column_google.setCellValueFactory(new PropertyValueFactory<ProxyResult, Boolean>("google"));
column_https.setCellValueFactory(new PropertyValueFactory<ProxyResult, Boolean>("https"));
column_lastchecked.setCellValueFactory(new PropertyValueFactory<ProxyResult, String>("lastChecked"));
column_response.setCellValueFactory(new PropertyValueFactory<ProxyResult, Long>("responseTime"));
}
public void handleSearchButton(ActionEvent event) {
Service<Void> searchWorker = new SearchProxyWorker(pb_search, data);
searchWorker.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
System.out.println("Tadaaa");
}
});
searchWorker.start();
}
/**
* Set the current scene.
*
* #param scene A scene
*/
public void setScene(Scene scene) {
this.scene = scene;
}
}