I have two Controller class(Controller and Dailog Controller). COntroller class has tableView. On Double click on Tableview row the Dialog popup. The dialogController class has two button i.e update and delete.
The Update button updating and deleting data in database. After updating or deleting i want to refresh tableview. The problem is tablview refresh method is in Controller class. So how can i refresh it?
public class Controller implements Initializable{
#FXML
private TabPane tabPane;
#FXML
private Tab createTaskTab;
#FXML
private TextArea textArea;
#FXML
private Button saveBtn;
#FXML
private Tab viewTasksTab;
#FXML
private TableView<Task> tableView;
#FXML
private TableColumn<Task, Integer> idColumn;
#FXML
private TableColumn<Task, String> dateColumn;
#FXML
private TableColumn<Task, String> timeColumn;
#FXML
private TableColumn<Task, String> taskColumn;
#FXML
private TableColumn<Task, String> statusColumn;
#FXML
void saveTask(ActionEvent event) {
String getTask = textArea.getText();
if(getTask.length() > 0)
{
MysqlConnection mysqlConnection = new MysqlConnection();
int count = mysqlConnection.insertTask(getTask);
if(count > 0)
{
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Saved");
alert.setContentText("Task Saved");
alert.show();
textArea.clear();
}
}
else
{
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Empty TextArea");
alert.setContentText("Please write the task");
alert.show();
}
}
#FXML
public void viewTasks(Event e)
{
try{
tabPane.getSelectionModel().selectedItemProperty().addListener(
new ChangeListener<Tab>() {
#Override
public void changed(ObservableValue<? extends Tab> observable, Tab oldValue, Tab newValue) {
if(newValue == viewTasksTab)
{
refreshTable();
}
}
});
}catch(Exception exception)
{
System.out.println("Exception in viewTasks");
}
}
protected void refreshTable() {
MysqlConnection myconn = new MysqlConnection();
idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
dateColumn.setCellValueFactory(new PropertyValueFactory<>("date"));
timeColumn.setCellValueFactory(new PropertyValueFactory<>("time"));
taskColumn.setCellValueFactory(new PropertyValueFactory<>("task"));
statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
tableView.setItems(myconn.fetchTasks());
}
#FXML
public void onEdit(MouseEvent event)
{
if(event.getClickCount() == 2){
Task selectedTask = tableView.getSelectionModel().getSelectedItem();
Scene scene;
Stage stage;
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("DialogBox.fxml"));
Parent root = (Parent) loader.load();
DialogBoxController dialog = loader.getController();
dialog.editTask(selectedTask);
scene = new Scene(root);
stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setScene(scene);
stage.showAndWait();
} catch (IOException e) {
System.out.println("Exception in onEdit"+e.getMessage());
}
}
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
DialogController class:
[public class DialogBoxController implements Initializable{
#FXML
private Label idLabel;
#FXML
private Label dateLabel;
#FXML
private Label timeLabel;
#FXML
private ComboBox<String> statusComboBox;
#FXML
private TextArea textAreaDialog;
#FXML
private Button updateBtn;
#FXML
private Button deleteBtn;
private void closeStage(ActionEvent event) {
Node source = (Node) event.getSource();
Stage stage = (Stage) source.getScene().getWindow();
stage.close();
}
public void editTask(Task task)
{
idLabel.setText(""+task.getId());
dateLabel.setText(task.getDate());
timeLabel.setText(task.getTime());
textAreaDialog.setText(task.getTask());
statusComboBox.setValue(task.getStatus());
textAreaDialog.setEditable(false);
}
#FXML
public void update(ActionEvent event){
int taskID = Integer.parseInt(idLabel.getText());
String status = statusComboBox.getSelectionModel().getSelectedItem().toString();
MysqlConnection myconn = new MysqlConnection();
myconn.updateTask(taskID, status);
closeStage(event);
}
#FXML
public void delete(ActionEvent event){
int taskID = Integer.parseInt(idLabel.getText());
MysqlConnection myconn = new MysqlConnection();
myconn.deleteTask(taskID);
closeStage(event);
}
#Override
public void initialize(URL location, ResourceBundle resources) {
statusComboBox.getItems().addAll("Pending","Done","Aborted");
}
Snapcshot of Application
You can add this to the DialogBoxController class:
public class DialogBoxController {
private Controller controller;
public void setController(Controller controller){
this.controller = controller;
}
#FXML
public void delete(ActionEvent event){
// Your code
controller.refreshTable();
closeStage(event);
}}
And in the Controller:
DialogBoxController dialog = loader.getController();
dialog.editTask(selectedTask);
dialog.setController(this);
Related
My problem is that I have two different classes : "Book" and "User".
I want to display Books in my table after clicking button "Show all books" and then all Users in this same table after clicking button "show all users". I don't know what type I should give in tableview and tablecolumn.
What can i put instead of "?" ?
public class WorkerPaneController implements Initializable {
#FXML
private TableView<?> tab;
#FXML
private TableColumn<?, ?> c3;
#FXML
private TableColumn<?, ?> c4;
#FXML
private TableColumn<?, ?> c5;
#FXML
private TableColumn<?, ?> c6;
#FXML
private Button test;
#FXML
private ComboBox<String> wybor;
#FXML
private Button show;
#FXML
private TableColumn<Data, ?> c1;
#FXML
private TableColumn<?, ?> c2;
#Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
this.wybor.getItems().addAll("Książek", "Egzemplarzy", "Czytelników",
"Pracowników");
}
#FXML
public void ChangeScene(ActionEvent event) throws IOException {
Parent userMenu =
FXMLLoader.load(getClass().getResource("/LibDB/view/UserPane.fxml"));
Stage s = new Stage();
s.setTitle("test");
s.setScene(new Scene(userMenu));
s.show();
}
#FXML
public void pokaz(ActionEvent event) throws IOException {
if (wybor.getValue() != null) {
switch (this.wybor.getValue()) {
case "Czytelników":
c1.setText("id_czytelnika");
c2.setText("Imie");
c3.setText("Nazwisko");
c4.setText("Wiek");
c5.setText("PESEL");
c6.setText("id_adresu");
break;
case "Pracowników":
c1.setText("id_czytelnika");
c2.setText("Imie");
c3.setText("Nazwisko");
c4.setText("Wiek");
c5.setText("PESEL");
c6.setText("id_adresu");
break;
case "Książek":
c1.setText("id_ksiazki");
c2.setText("Tytul");
c3.setText("Ilosc stron");
c4.setText("ISBN");
c5.setText("Rok Wydania");
c6.setText("id_wydawnictwa");
break;
case "Egzemplarzy":
c1.setText("id_egzemplarza");
c2.setText("Numer katalogowy");
c3.setText("id_Typ okladki");
c4.setText("Numer ksiazki");
c5.setText("opis");
c6.setText("Dostepnosc");
break;
}
} else {
System.out.println("test");
}
}
public void initPracownikow() {
// c1.setCellValueFactory(data ->
// data.getValue().getUzytkownicy().get(0).getImieProperty());
}
}
I am trying to fill data into my new scene when I switch to it. The user logs in (which is working because if I toString() him I get everything I need). When I call setText() on the JFXTextField for example, it does not work.
This is my controller. Updatehome is called when I switch to this scene
public class DashboardController {
#FXML JFXTextField txtGastDashboardSuchfeld;
#FXML Label lblGastDashboardNachnameVorname;
#FXML JFXTextField txtGastHomeVorname;
#FXML JFXTextField txtGastHomeNachname;
#FXML JFXTextField txtGastHomeSteuernummer;
#FXML JFXTextField txtGastHomeAusweisnummer;
#FXML JFXTextField txtGastHomeEmail;
#FXML JFXPasswordField pwfGastHomePasswort;
public void updateHome() {
if(Main.user == null) {
Controller.errorMessage("Fataler Fehler", "User konnte nicht aufgelöst werden!");
return;
}
System.out.println(Main.user.toString());
lblGastDashboardNachnameVorname.setText(Main.user.getVollername());
txtGastHomeVorname.setText(Main.user.getVorname());
txtGastHomeNachname.setText(Main.user.getNachname());
txtGastHomeSteuernummer.setText(Main.user.getSteuernummer());
txtGastHomeAusweisnummer.setText(Main.user.getAusweisnummer());
txtGastHomeEmail.setText(Main.user.getEmailAdresse());
pwfGastHomePasswort.setText(Main.user.getPasswort().toString());
}
}
In my Main class I have this (Scenes are being loaded)
public static Controller controller;
public static DashboardController dashboardController;
public static Person user = null;
public static Stage window;
public static TreeMap<String, Scene> scenes = new TreeMap<>();
public static ArrayList<Scene> history = new ArrayList<>();
#Override
public void start(Stage primaryStage) {
window = primaryStage;
controller = new Controller();
dashboardController = new DashboardController();
loadScenes();
}
This is a snippet from the method that loads the scenes into my treemap
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlPath));
try {
if(sceneName.contains("dashboard")) {
loader.setController(dashboardController);
} else
loader.setController(controller);
Parent parent = (Parent)loader.load();
scenes.put(sceneName, new Scene(parent));
I have been working on JavaFX and trying figure out how to connect classes contained withing the package. I want the "text1btn" button from MainController class to send a text from "scene1TextField" also in MainController class to TextArea in LeftTextArea class. I would appreciate any comments on that. Thank you.
package sample;
public class Main extends Application {
public static BorderPane root = new BorderPane();
public static BorderPane getRoot() {
return root;
}
#Override
public void start(Stage primaryStage) throws Exception {
URL url1 = getClass().getResource("../view/MainView.fxml");
BorderPane bp1 = FXMLLoader.load(url1);
URL url2 = getClass().getResource("../view/LeftTextArea.fxml");
AnchorPane bp2 = FXMLLoader.load(url2);
root.setTop(bp1);
root.setCenter(bp2);
primaryStage.setScene(new Scene(root, 500, 400));
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
package Controller;
public class MainController {
#FXML
Button scene1btn;
#FXML
Button scene2btn;
#FXML
TextField scene1TextField;
#FXML
TextField scene2TextField;
#FXML
Button text1btn;
#FXML
Button text2btn;
#FXML
TextArea mainViewTextArea;
#FXML
public void initialize() {
}
#FXML
public void text1btnClicked() {
}
#FXML
public void text2btnClicked() {
}
#FXML
private void scene1btnClicked() {
try {
URL url1 = getClass().getResource("../view/LeftTextArea.fxml");
AnchorPane bp1 = FXMLLoader.load(url1);
BorderPane border = Main.getRoot();
border.setCenter(bp1);
} catch (IOException e) {
e.printStackTrace();
}
}
#FXML
private void scene2btnClicked() {
try {
URL url2 = getClass().getResource("../view/RightTextArea.fxml");
AnchorPane bp2 = FXMLLoader.load(url2);
BorderPane border = Main.getRoot();
border.setCenter(bp2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package Controller;
public class LeftTextArea {
#FXML
public TextArea leftTextArea;
}
A quick and simple approach is just to expose a StringProperty in the MainController, and when it changes call a method in the LeftTextArea:
public class MainController {
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text ;
}
// existing code ...
#FXML
public void text1btnClicked() {
textProperty().set(scene1TextField.getText());
}
// ...
}
In LeftTextArea do
public class LeftTextArea {
#FXML
public TextArea leftTextArea;
public void setText(String text) {
leftTextArea.setText(text);
}
}
And then you can tie it all together with
#Override
public void start(Stage primaryStage) throws Exception {
URL url1 = getClass().getResource("../view/MainView.fxml");
FXMLLoader loader1 = new FXMLLoader(url1);
BorderPane bp1 = loader1.load();
MainController mainController = loader1.getController();
URL url2 = getClass().getResource("../view/LeftTextArea.fxml");
FXMLLoader loader2 = new FXMLLoader(url2);
AnchorPane bp2 = loader2.load();
LeftTextArea leftTextArea = loader2.getController();
mainController.textProperty().addListener((obs, oldText, newText) ->
leftTextArea.setText(newText));
root.setTop(bp1);
root.setCenter(bp2);
primaryStage.setScene(new Scene(root, 500, 400));
primaryStage.setResizable(false);
primaryStage.show();
}
If you end up needing multiple properties like this that are essentially shared between controllers, you probably need to define a "model" class to encapsulate them all in one place, and pass the model to the controllers. See, e.g. JavaFX controller to controller - access to UI Controls or Applying MVC With JavaFx
If you want to set any field in the class LeftTextArea just simply create a public setter method in Class LeftTextArea like
public void setTextArea(Text text){
//do what you want to do
}
Then call the method from MainController class with the object of LeftTextArea class. like
LeftTextArea leftTextArea = new LeftTextArea();
leftTextArea.setTextArea(text); //text is the desired you want to send
How can i add an item to an already existing ListView from a different Stage (Window).
Basically i just want to add Text to the ListView from Window 2 to the ListView in Window 1.
Thanks in advance.
Sorry i forgot this is what i've got so far in my controller class: (im a beginner in javafx ..)
(below i try to add a String to the ListView but this doesnt work...and i dont know why )
public class ClientGUIController implements Initializable {
#FXML private Text usernameText;
#FXML private Button cancelButtonNewDate;
#FXML private TextField newDateTitel,newDateJahr;
#FXML private TextArea newDateNotiz;
#FXML private ComboBox<String> newDateTag,newDateMonat,newDateStunde,newDateMinute;
#FXML private ListView<String> terminListView;
private ObservableList<String> termine =
FXCollections.observableArrayList();
private ObservableList<String> listItems = FXCollections.observableArrayList("Add Items here");
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public Text getUsernameText() {
return usernameText;
}
public void setUsernameText(String username ) {
this.usernameText.setText(username);
terminListView.setItems(listItems);
listItems.add("test");
}
public void newDate() {
Stage newDate = new Stage();
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("newDate.fxml"));
// FXMLLoader loader = new FXMLLoader();
// root = (Parent) loader.load(getClass().getResource("NewDate.fxml").openStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
Scene sceneNewDate = new Scene(root);
// sceneNewDate.getStylesheets().add(getClass().getResource("Style.css").toExternalForm());
newDate.setTitle("Neuer Termin");
newDate.setScene(sceneNewDate);
newDate.show();
}
public void createNewDate() throws IOException {
// Termine meinTermin = new Termine(Integer.parseInt(newDateTag.getValue()), Integer.parseInt(newDateMonat.getValue()), Integer.parseInt(newDateJahr.getText()), newDateTitel.getText(), newDateNotiz.getText(),
// Integer.parseInt(newDateStunde.getValue()), Integer.parseInt(newDateMinute.getValue()));
//Add item to ListView
listItems.add("test"); <- this doesnt work
}
public void closeDialogue(){
Stage stage = (Stage) cancelButtonNewDate.getScene().getWindow();
stage.close();
}
}
One way to do this is to pass listItems to the controller for newDate.fxml, so it can just add to that list. So, assuming the controller class for newDate.fxml is NewDateController, you would do something like:
public class NewDateController {
private ObservableList<String> data ;
public void setData(ObservableList<String> data) {
this.data = data ;
}
// other code as before...
// button handler:
#FXML
private void handleButtonPress() {
data.addItem("test");
}
}
Then in your ClientGUIController, load the fxml like this:
public void newDate() {
Stage newDate = new Stage();
Parent root;
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("newDate.fxml"));
root = loader.load();
NewDateController controller = loader.getController();
controller.setData(listItems);
} catch (IOException e) {
e.printStackTrace();
return;
}
Scene sceneNewDate = new Scene(root);
newDate.setTitle("Neuer Termin");
newDate.setScene(sceneNewDate);
newDate.show();
}
I have a TableView with three TableColumns. There is an ObservableList named "sensorDataList " in MainApp.java that stores the objects to be shown in the TableView. With the following code, only the first TableColumn named "idColumn" doesn't show the values from the observable list, however, the other two TableColumns works fine.
MainApp.java (this has an "ObservableList" of Sensor objects (see Sensor.java). Also this class has the method named "showSensorDialog()" which loads the .fxml file that has the TableView in question. FYI, this method is invoked by a button in other controller.)
public class MainApp extends Application {
private Stage primaryStage;
private Stage sensorDialogStage;
private ObservableList<sensor> sensorDataList = FXCollections.observableArrayList();
public MainApp(){
sensorDataList.add(new sensor("testText","1 1 0.7", "0 0 1"));
}
public ObservableList<Sensor> getSensorDataList(){return sensorDataList;}
public void showSensorDialog() {
try {
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("/view/SensorDialog.fxml"));
Object object = loader.load();
sensorDialogStage = new Stage();
Scene scene = new Scene((Parent) object);
sensorDialogStage.setScene(scene);
SensorDialogController controller = loader.getController();
controller.setSensorDialogStage(sensorDialogStage);
controller.setMainApp(this); // this line connects the ObservableList to the TableView.
sensorDialogStage.showAndWait();
} catch (IOException e) {}
}
}
SensorDialogController.java
public class SensorDialogController implements Initializable {
#FXML
private TableView<Sensor> sensorTable;
#FXML
private TableColumn<Sensor, String> idColumn;
#FXML
private TableColumn<Sensor, String> locationColumn;
#FXML
private TableColumn<Sensor, String> directionColumn;
private MainApp mainApp;
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
sensorTable.setItems(mainApp.getSensorDataList()); // ObservableList and TableView gets connected.
}
#Override
public void initialize(URL url, ResourceBundle rb){
idColumn.setCellValueFactory(new PropertyValueFactory<Sensor, String>("id"));
locationColumn.setCellValueFactory(new PropertyValueFactory<Sensor, String>("location"));
directionColumn.setCellValueFactory(new PropertyValueFactory<Sensor, String>("direction"));
}
}
Sensor.java
public class Sensor{
private SimpleStringProperty id;
private SimpleStringProperty location;
private SimpleStringProperty direction;
public Sensor(String i, String loc, String dir){
this.id = new SimpleStringProperty(i);
this.location = new SimpleStringProperty(loc);
this.direction = new SimpleStringProperty(dir);
}
}