JavaFx two diffrent classes in tableview and tablecolumn - java

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());
}
}

Related

How to refresh database tableview after updating or Deleting In Javafx?

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);

How the access the multiple fx:id efficiently (in FXML Document Controller)?

I have to set values for labels, I am set values by following way which is very lengthy,
public class FXMLDocumentController implements Initializable {
private TilesLogic gl = new TilesLogic();
private List<List<Integer>> game;
#FXML
private Label C1;
#FXML
private Label C2;
#FXML
private Label C3;
#FXML
.
.
.
private Label C16;
#FXML
private Label timer;
#Override
public void initialize(URL url, ResourceBundle rb) {
game = gl.shuffle();
SetValues();
}
void SetValues(){
C1.setText(String.valueOf(game.get(0).get(0)));
C2.setText(String.valueOf(game.get(0).get(1)));
.
.
C15.setText(String.valueOf(game.get(3).get(2)));
C16.setText(String.valueOf(game.get(3).get(3)));
}
}
is that any other way just like that
for(int i =1;i<17;i++)
setText("#C"+String.valueOf(i),String.valueOf(game.get(i)));
// setText("#id","Sometext");
to do it simple way and less time ?

Adding item from one tableview to another from selection(JAVAFX)

I have products in one product-table that loads on start, from that table I want to add the select item from the first tableview to the cart-table.
So here is the problem, I know how to add a selected item from one table to another. But, if item already exists in a table it should increase the quantity and not add a duplicate row.
I've tried a couple of ways that kinda works except they always have bugs.
The logic is under addButton().
public class OrderController implements Initializable {
OrderRepository or = new OrderRepository();
ShoeRepository sr = new ShoeRepository();
LogInController logInController = new LogInController();
private int customer_ID;
private int total;
private List<ProductCart> productCarts = new LinkedList<>();
#FXML
private Label label_total;
#FXML
private Button button_makeOrder;
#FXML
private Button button_add;
#FXML
private Button button_remove;
#FXML
private TableView<ProductCart> table_cart;
#FXML
private TableView<Product> tableProduct;
#FXML
private TableColumn<Product, String> col_shoe;
#FXML
private TableColumn<Product, String> col_brand;
#FXML
private TableColumn<Product, String> col_color;
#FXML
private TableColumn<Product, Integer> col_size;
#FXML
private TableColumn<Product, Integer> col_price;
#FXML
private TableColumn<Product, Integer> col_stock;
#FXML
private TableColumn<ProductCart, String> col_cart_Shoe;
#FXML
private TableColumn<ProductCart, String> col_cart_brand;
#FXML
private TableColumn<ProductCart, String> col_cart_color;
#FXML
private TableColumn<ProductCart, Integer> col_cart_size;
#FXML
private TableColumn<ProductCart, Integer> col_cart_price;
#FXML
private TableColumn<ProductCart, Integer> col_cart_quantity;
public void a() {
System.out.println(customer_ID);
}
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
col_shoe.setCellValueFactory(new PropertyValueFactory<>("shoeName"));
col_brand.setCellValueFactory(new PropertyValueFactory<>("shoeBrand"));
col_color.setCellValueFactory(new PropertyValueFactory<>("shoeColor"));
col_size.setCellValueFactory(new PropertyValueFactory<>("shoeSize"));
col_price.setCellValueFactory(new PropertyValueFactory<>("shoePrice"));
col_stock.setCellValueFactory(new PropertyValueFactory<>("stock"));
col_cart_Shoe.setCellValueFactory(new PropertyValueFactory<>("name"));
col_cart_brand.setCellValueFactory(new PropertyValueFactory<>("brand"));
col_cart_color.setCellValueFactory(new PropertyValueFactory<>("color"));
col_cart_size.setCellValueFactory(new PropertyValueFactory<>("size"));
col_cart_price.setCellValueFactory(new PropertyValueFactory<>("price"));
col_cart_quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
getProducts();
tableProduct.setItems(observableList);
customer_ID = logInController.getCustomer_ID();
}
ObservableList<Product> observableList = FXCollections.observableArrayList();
ObservableList<ProductCart> observableListC = FXCollections.observableArrayList();
public void getProducts() {
List<Product> products = new ArrayList<>();
List<Shoe> shoes = sr.getAllShoes();
shoes.forEach(shoe -> products.add(new Product(shoe.getShoe_ID(), shoe.getName(), shoe.getBrand().getName(),
shoe.getColor().getName(), shoe.getShoeSize().getShoeSize(), shoe.getInStock().getStock(),
shoe.getPrice().getPrice())));
products.forEach(product -> observableList.add(product));
}
public int getCustomer_ID() {
return customer_ID;
}
public void addButton() {
Product product = tableProduct.getSelectionModel().getSelectedItem();
ProductCart productCart = new ProductCart(product.getID(), product.getShoeName(), product.getShoeBrand(), product.getShoeColor(),
product.getShoeSize(),1, product.getShoePrice());
System.out.println(productCart.getName());
for (ProductCart item: productCarts) {
if (item.getName().equals(productCart.getName())) {
item.setQuantity(item.getQuantity() + 1);
table_cart.getItems().clear();
observableListC.remove(item);
observableListC.add(item);
}
else {
productCarts.add(item);
observableListC.add(item);
}
}
table_cart.setItems(observableListC);
updateTotal();
}
public void removeButton() {
}
public void makeOrder() {
}
public void updateTotal() {
total = 0;
List<ProductCart> productCarts = table_cart.getItems();
productCarts.forEach(productCart -> total += productCart.getPrice());
label_total.setText(total+"");
}
}
Changing only the quantity and stock in the tables works a lot better now.
However once an item is added to the table, adding the same row seems impossible without any bugs for me.
Version 1: Adding quantity to the existing row, unable to add new rows of other producs
Version 2: Being able to add rows, disables the ability to add quantity to existing row.
https://i.stack.imgur.com/EYoJ3.png
public void addButton() {
ProductCart productCart;
Product product = tableProduct.getSelectionModel().getSelectedItem();
productCart = new ProductCart(product.getID(), product.getShoeName(), product.getShoeBrand(),
product.getShoeColor(), product.getShoeSize(), product.getSold()+1, product.getShoePrice());
if (product.getStock() != 0) {
table_cart.getItems().add(productCart);
}
updateStock();
updateTotal();
}

nullPointerException and how to update label the right way?

I have 2 scenes :
The first one has a "Balance" Label, which displays the balance from a variable.
The second scene is the deposit scene where the user adds to the balance.
(Each scene has its controller class)
I want the balance to be updated when the user goes back to the first scene.
what's the best way to do so? I couldn't find an event for the scene shown, I found online only a stage example which triggers an event when the window is closed, but here I am just changing scenes by changing the mainstage scene.
I have tried making an object of the first scene class inside the second scene's class and calling a method to change the label text when I click the back button but that didn't work.
Here's the code for the first scene where lbBalance is the label I want to update, and updateBal is the method I am using in the second scene class.
public class accountController extends Controller implements Initializable {
#FXML private Label gilbert;
#FXML private Label lbBalance;
#FXML private Button deposit;
#FXML private Button btn_showBalance;
private application.depositController depositController;
#Override
public void initialize(URL location, ResourceBundle resources) {
lbBalance.setText(String.valueOf(BAL));
}
#FXML
public void handleDeposit(ActionEvent event) throws IOException {
Parent depositParent = FXMLLoader.load(getClass().getResource("deposit.fxml"));
depositScene = new Scene(depositParent);
mainStage.setScene(depositScene);
mainStage.show();
}
public void updateBal() {
lbBalance.setText(String.valueOf(BAL));
}
}
Here's the second scene's class
accountController backtoscene= new accountController();
#FXML private Label info;
#FXML private Button btn_depositfinal;
#FXML private TextField depositamount;
#FXML private Button btn_back;
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
}
#FXML
public void handleDepositFinal(ActionEvent event) {
deposit(Integer.parseInt(depositamount.getText()));
info.setVisible(true);
}
#FXML
public void handleBackButton(ActionEvent event) throws IOException {
backtoscene.updateBal();
mainStage.setScene(newscene);
}
TL;DR calling the method is giving me a nullPointerException, is there any other way to update the balance label when getting back to previous scene?
NOTE: I haven't tested the code, I just wrote it freehand, but it gives you a general idea.
Your main issue is that you are creating a new AccountController in the DepositController. Meaning it's a different one than the one you originally instantiated.
public class AccountController extends Controller implements Initializable {
#FXML private Label gilbert;
#FXML private Label lbBalance;
#FXML private Button deposit;
#FXML private Button btn_showBalance;
private application.DepositController depositController;
#Override
public void initialize(URL location, ResourceBundle resources) {
lbBalance.setText(String.valueOf(BAL));
}
#FXML
public void handleDeposit(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("deposit.fxml"));
Parent depositParent = loader.load();
depositScene = new Scene(depositParent);
depositController = loader.getController();
depositController .setAccountController(this);
mainStage.setScene(depositScene);
mainStage.show();
}
public void updateBal() {
lbBalance.setText(String.valueOf(BAL));
}
}
Here's the second class where you need to set the AccountController to be the one you originally initialized :
public class DepositController extends Controller implements Initializable {
AccountController backtoscene;
#FXML private Label info;
#FXML private Button btn_depositfinal;
#FXML private TextField depositamount;
#FXML private Button btn_back;
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
}
public void setAccountController(AccountController controller){
backtoscene = controller;
}
#FXML
public void handleDepositFinal(ActionEvent event) {
deposit(Integer.parseInt(depositamount.getText()));
info.setVisible(true);
}
#FXML
public void handleBackButton(ActionEvent event) throws IOException {
backtoscene.updateBal();
mainStage.setScene(newscene);
}
}
Now you have access to the AccountController you originally initialized at the start, and the AccountController has access to the correct DepositController.

Changing TextArea in another class

There is a class FXMLDocumentController.
There is a class ThreadForFile which has been inheriting from class Thread (which I read data from a file)
After I pressed the button (in the class FXMLDocumentController) I create a flow of class ThreadForFile.
I need to in the class ThreadForFile, when reading, the string displayed in the TextArea. But I can not figure out if I pass a parameter TextArea, and change it in the constructor, then there is a change in this component.But if I assign the class field this TextArea, it displays an error :
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
ThreadForFile extends Thread
private String path;
private long ms;
private int id;
private String name;
private boolean stop = false;
private HTMLEditor web;
private DB db = new DB();
private Button doc;
public void setMS(long ms){
System.out.print(ms);
this.ms =ms;
}
public ThreadForFile(String name,String path,long ms,int id,Button doc) {
this.path = new String();
this.path = path;
this.ms = ms;
this.id = id;
this.name = name;
this.doc = new Button();
this.doc = doc;
}
public void Stop(boolean stop){
this.stop = stop;
}
public void run( ) {
try {
doc.setText("Zsczsc");
System.out.print("asdasd");
File file = new File(path);
File file1 = new File("C:\\out.txt");
BufferedReader br = new BufferedReader (new InputStreamReader(new FileInputStream(file), "UTF-8"));
String line = null;
while( (line = br.readLine()) != null){
if(!Thread.interrupted()) //Проверка прерывания
{
if(!stop){
PrintWriter out = new PrintWriter(file1.getAbsoluteFile());
try {
sytem.out.print(line+"\n");
} finally {
out.close();
}
Thread.sleep(db.getParam().getMS()*1000);
System.out.print("ms" + db.getParam().getMS());
}
}else{
return;
}
}
} catch (Exception ex) {
System.out.print(ex.toString());
Logger.getLogger(ThreadForFile.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void read()throws FileNotFoundException, IOException
{
}
FXMLDocumentController
<!-- language: JavaFX -->
public class FXMLDocumentController implements Initializable {
private long ms = 5;
private ObservableList<ThreadForFile> threadForFile = FXCollections.observableArrayList();
private ObservableList<threadFile> threadFile = FXCollections.observableArrayList();
private int index ;
private DB db = new DB();
private Parametrs param = new Parametrs();
#FXML
private Button btnAdd;
#FXML
private Button btnStop;
#FXML
public Button btnDel;
#FXML
private Button btnStart;
#FXML
private TextField textFValueText;
#FXML
private TextField textFMs;
#FXML
private Button btnUpdate;
#FXML
public static TextArea textArea;
#FXML
private Label nameLabel;
#FXML
private Label pathLabel;
#FXML
private TextField textFName;
#FXML
private TextField textFPath;
#FXML
private TableColumn nameCol;
#FXML
private TableColumn pathCol;
#FXML
private TableColumn statCol;
public static FXMLDocumentController doc;
private ResourceBundle bundle;
#FXML
private TableView table;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
bundle = rb;
System.out.println("You clicked me!");
FileRead file = new FileRead(FXMLDocumentController.this);
Tab1();
Tab2();
Tab3();
param = db.getParam();
System.out.print(param.getMS() + " " + param.getValue());
}
public void Tab1()
{
}
public void Tab2()
{
//root.getChildren().addAll(btn,table,btnStop,btnStart,btnDel,nameField,pathField,name,path);
btnAdd.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
threadFile.add(new threadFile(textFName.getText(),textFPath.getText(),1));
threadForFile.add(new ThreadForFile(threadFile.get(threadFile.size()-1).getName(),threadFile.get(threadFile.size()-1).getPath(),ms,threadFile.size(),btnAdd));
threadForFile.get(threadForFile.size()-1).start();
index = table.getSelectionModel().getSelectedIndex();
System.out.print(index+ "\n");
}
});
.
.
.
.
.
.
.
.
.
.
}
You are trying to access a JavaFX Control outside the JavaFX Application thread.
Never use your controls, out of your Controller or pass them as a parameter to other methods. Instead, try to pass data to the controller, which in turn will set it to the controls inside the controller.
Some useful links are on passing data to the Controller :
Passing Parameters JavaFX FXML
How to have constructor with arguments for controller?
Some useful links on multi-threading in JavaFX:
How do I safely modify JavaFX GUI nodes from my own Thread?
JavaFX working with threads and GUI

Categories