ComboBox is null on start of ActionEvent - fxmlloader

Problem:After the ActionEvent is triggered (selecting an account), the comboBox is null. When I run the program, I can see that the ComboBox is populated. I think I'm doing something wrong with the FXML loader. I read through the following document: https://openjfx.io/javadoc/12/javafx.fxml/javafx/fxml/doc-files/introduction_to_fxml.html#controllers
While thrilling (actually learned a lot), the document did not give me an answer to my problem. Please advise.... Referring me to another source for further education would be appreciated. If you need more information to answer the question, let me know.
Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.ComboBox.setItems(javafx.collections.ObservableList)" because "this.accountComboBox" is null at application.budget/application.budget.Controller.initialize(Controller.java:67)
Line 67 is: accountComboBox.setItems(accountlist);
package application.budget;
import datamodel.Account;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import java.io.IOException;
import java.text.NumberFormat;
public class Controller {
public Button detacctinfo;
private Stage stage;
private Scene scene;
private Parent root;
#FXML
private Button createnewacct, Submit;
#FXML
private AnchorPane mainPanel;
#FXML
private ComboBox<Account> accountComboBox;
#FXML
Label acctbalField = new Label();
private NumberFormat fmt;
public void initialize () {
ObservableList<Account> accountlist = FXCollections.observableArrayList();
accountlist.add(new Account("Bank of America", 10010101.32));
accountlist.add(new Account("Prosperity Bank", 10010101.32));
//ComboBox<Account> selectacct = new ComboBox<>();
// Use a StringConverter to configure our ComboBox to display only the film's title
/* accountComboBox.setConverter(new StringConverter<Account>() {
#Override
public String toString(Account account) {
return account.getAccountName();
}
#Override
public Account fromString(String string) {
return accountComboBox.getItems().stream().filter(ap ->
ap.getAccountName().equals(string)).findFirst().orElse(null);
}
});*/
// Finally, set our ComboBox's items to our sample list
accountComboBox.setItems(accountlist);
System.out.println(accountlist);
}
public void OnItemSelected(ActionEvent e ) throws IOException {
root = FXMLLoader.load(getClass().getResource("AccountHome.fxml"));
Stage window = (Stage) Submit.getScene().getWindow();
window.setScene(new Scene(root));
}
}
package datamodel;
public class Account {
private String accountName;
private Double accountBalance;
public Account(String accountName, Double accountBalance) {
this.accountName = accountName;
this.accountBalance = accountBalance;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public Double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(Double accountBalance) {
this.accountBalance = accountBalance;
}
#Override //Esto dice que cuando un variable se usa, va a dar el valor de abajo
public String toString() {
return accountName;
}
public String getBalance() {
return String.valueOf(accountBalance);
}
}
Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.ComboBox.setItems(javafx.collections.ObservableList)" because "this.accountComboBox" is null
at application.budget/application.budget.Controller.initialize(Controller.java:67)
Line 67 is: accountComboBox.setItems(accountlist);

After some research, it seems like each FXML document needs it's own controller. Been doing this for about 2 weeks. Excuse the lack of education on my part.

Related

JavaFx: I need something similar to this but for a TableView instead of a ListView

I took a stab at this yesterday but the TableView documentation has me a bit confused. After working on it for a couple of hours I gave up. Just wondering if any javafx experts out there can help me with this. I want to update a TableView in a background thread periodically when items in my database change.
Rather than post my entire application I have tried to break it down to a simple example. Replace all occurrences of ListView with TableView and ....
Then what?
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.Event;
import javafx.event.EventType;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* An example of triggering a JavaFX ListView when an item is modified.
*
* Displays a list of strings. It iterates through the strings adding
* exclamation marks with 2 second pauses in between. Each modification is
* accompanied by firing an event to indicate to the ListView that the value
* has been modified.
*
* #author Mark Fashing
*/
public class ListViewTest extends Application {
/**
* Informs the ListView that one of its items has been modified.
*
* #param listView The ListView to trigger.
* #param newValue The new value of the list item that changed.
* #param i The index of the list item that changed.
*/
public static <T> void triggerUpdate(ListView<T> listView, T newValue, int i) {
EventType<? extends ListView.EditEvent<T>> type = ListView.editCommitEvent();
Event event = new ListView.EditEvent<>(listView, type, newValue, i);
listView.fireEvent(event);
}
#Override
public void start(Stage primaryStage) {
// Create a list of mutable data. StringBuffer works nicely.
final List<StringBuffer> listData = Stream.of("Fee", "Fi", "Fo", "Fum")
.map(StringBuffer::new)
.collect(Collectors.toList());
final ListView<StringBuffer> listView = new ListView<>();
listView.getItems().addAll(listData);
final StackPane root = new StackPane();
root.getChildren().add(listView);
primaryStage.setScene(new Scene(root));
primaryStage.show();
// Modify an item in the list every 2 seconds.
new Thread(() -> {
IntStream.range(0, listData.size()).forEach(i -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(listData.get(i));
Platform.runLater(() -> {
// Where the magic happens.
listData.get(i).append("!");
triggerUpdate(listView, listData.get(i), i);
});
});
}).start();
}
public static void main(String[] args) {
launch(args);
}
}
Here is my first attempt:
Create a person class....
package org.pauquette.example;
import javafx.beans.property.SimpleStringProperty;
public class Person {
private final SimpleStringProperty email;
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getEmail() {
return email.get();
}
public String getFirstName() {
return firstName.get();
}
public String getLastName() {
return lastName.get();
}
public void setEmail(String fName) {
email.set(fName);
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public void setLastName(String fName) {
lastName.set(fName);
}
}
Create an extremely simple model class...
package org.pauquette.example;
import javafx.collections.*;
public class PeopleModel {
private ObservableList<Person> people=FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith#example.com"),
new Person("Isabella", "Johnson", "isabella.johnson#example.com"),
new Person("Ethan", "Williams", "ethan.williams#example.com"),
new Person("Emma", "Jones", "emma.jones#example.com"),
new Person("Michael", "Brown", "michael.brown#example.com")
);
public ObservableList<Person> getPeople() {
return people;
}
}
Now create a TableView of just firstName and build the columns then update the firstName every 2 seconds.......
package org.pauquette.example;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* An example of triggering a JavaFX TableView when an item is modified.
*
* Displays a list of strings. It iterates through the strings adding
* exclamation marks with 2 second pauses in between. Each modification is
* accompanied by firing an event to indicate to the TableView that the value
* has been modified.
*
* #author Mark Fashing-Modified for TableView by Bryan Pauquette
*/
public class TableViewTest extends Application {
/*
public static <T> void triggerUpdate(TableView<T> listView, T newValue, int i) {
EventType<? extends TableView.EditEvent<T>> type = TableView.editCommitEvent();
Event event = new TableView.EditEvent<>(listView, type, newValue, i);
listView.fireEvent(event);
}*/
#Override
public void start(Stage primaryStage) {
final TableView<Person> listView = new TableView<Person>();
final PeopleModel model=new PeopleModel();
final ObservableList<Person> listData=model.getPeople();
listView.getItems().addAll(listData);
final StackPane root = new StackPane();
buildColumns(listView,listData);
root.getChildren().add(listView);
primaryStage.setScene(new Scene(root));
primaryStage.show();
// Modify an item in the list every 2 seconds.
new Thread(() -> {
IntStream.range(0, listData.size()).forEach(i -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(listData.get(i));
Platform.runLater(() -> {
// Where the magic happens.
Person p=listData.get(i);
p.setFirstName(new StringBuilder(p.getFirstName()).append("!").toString());
//triggerUpdate(listView, listData.get(i), i);
});
});
}).start();
}
private void buildColumns(TableView<Person> listView,ObservableList<Person> listData) {
TableColumn<Person, String> dataCol = new TableColumn<Person, String>("First Name");
dataCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
listView.getColumns().add(dataCol);
listView.setItems(listData);
}
public static void main(String[] args) {
launch(args);
}
}
The method I am struggling with is triggerUpdate.....
I want the firstName column to get updated in the view with an appended exclamation point every 2 seconds just like in the original simple list view.
Here is working code.....
package org.pauquette.example;
import java.util.Observable;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
public class Person extends Observable {
private final SimpleStringProperty email;
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getEmail() {
return email.get();
}
public String getFirstName() {
return firstName.get();
}
public String getLastName() {
return lastName.get();
}
public void setEmail(String emailIn) {
email.setValue(emailIn);
setChanged();
notifyObservers(email);
}
public void setFirstName(String fNameIn) {
firstName.setValue(fNameIn);
setChanged();
notifyObservers(firstName);
}
public void setLastName(String lNameIn) {
lastName.setValue(lNameIn);
setChanged();
notifyObservers();
}
public ObservableValue<String> firstNameProperty() {
return firstName;
}
}
And......
package org.pauquette.example;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
* An example of triggering a JavaFX TableView when an item is modified.
*
* Displays a list of strings. It iterates through the strings adding
* exclamation marks with 2 second pauses in between. Each modification is
* accompanied by firing an event to indicate to the TableView that the value
* has been modified.
*
* #author Mark Fashing-Modified for TableView by Bryan Pauquette
*/
public class TableViewTest extends Application {
/*
public static <T> void triggerUpdate(TableView<T> listView, T newValue, int i) {
EventType<? extends TableView.EditEvent<T>> type = TableView.editCommitEvent();
Event event = new TableView.EditEvent<>(listView, type, newValue, i);
listView.fireEvent(event);
}*/
#Override
public void start(Stage primaryStage) {
final TableView<Person> listView = new TableView<Person>();
final PeopleModel model=new PeopleModel();
final ObservableList<Person> listData=model.getPeople();
/* int row=0;
for (Person p : listData) {
p.addObserver(new PersonObserver(listView,row));
row++;
}*/
listView.getItems().addAll(listData);
final StackPane root = new StackPane();
buildColumns(listView,listData);
root.getChildren().add(listView);
primaryStage.setScene(new Scene(root));
primaryStage.show();
// Modify an item in the list every 2 seconds.
new Thread(() -> {
IntStream.range(0, listData.size()).forEach(i -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(listData.get(i));
Platform.runLater(() -> {
// Where the magic happens.
Person p=listData.get(i);
p.setFirstName(new StringBuilder(p.getFirstName()).append("!").toString());
//triggerUpdate(listView, listData.get(i), i);
});
});
}).start();
}
private void buildColumns(TableView<Person> listView,ObservableList<Person> listData) {
TableColumn<Person, String> dataCol = new TableColumn<Person, String>("First Name");
//dataCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
dataCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
// p.getValue() returns the Person instance for a particular TableView row
return p.getValue().firstNameProperty();
}
});
listView.getColumns().add(dataCol);
listView.setItems(listData);
}
public static void main(String[] args) {
launch(args);
}
}

Recyclerview Filter not working.its not searching the elements

when i filter recyclerview it shows Not found .My Searchview not working.when i run the code its result in Not Found i think there is problem in onQueryTextChange
myfilter function also did not work
#Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(SecondActivity1.this, "Name is : " + query, Toast.LENGTH_SHORT).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
final List<DatabaseModel> filteredModelList = filter(dbList, newText);
if (filteredModelList.size() > 0) {
// Toast.makeText(SecondActivity1.this, "Found", Toast.LENGTH_SHORT).show();
recyclerAdapter.setFilter(filteredModelList);
return true;
} else {
Toast.makeText(SecondActivity1.this, "Not Found", Toast.LENGTH_SHORT).show();
return false;
}
private List filter(List models, String query) {
query = query.toLowerCase();
recyclerAdapter.notifyDataSetChanged();
final List<DatabaseModel> filteredModelList = new ArrayList<>();
// mRecyclerView.setLayoutManager(new LinearLayoutManager(SecondActivity1.this));
// mRecyclerView.setAdapter(RecyclerAdapter);
for (DatabaseModel model : models) {
final String text = model.getName().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
//
}
here is filter method which recieve parameter(dblist,newtext) filter method recieves these method when i use toast its show that it takes newText But didnot filter this.i checked many sites but this is same in many sites points.when i enter name toast shows name which i enter but it did not filter
RecyclerAdapter.java
package com.example.prabhu.databasedemo;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by user_adnig on 11/14/15.
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
List<DatabaseModel> dbList;
static Context context;
RecyclerAdapter(Context context, List<DatabaseModel> dbList ){
this.dbList = new ArrayList<>();
this.context = context;
this.dbList = (ArrayList<DatabaseModel>) dbList;
}
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_row, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {
holder.name.setText(dbList.get(position).getName());
holder.email.setText(dbList.get(position).getEmail());
}
#Override
public int getItemCount() {
return dbList.size();
}
public void setFilter(List<DatabaseModel> countryModels) {
// Toast.makeText(RecyclerAdapter.this,"Method is called", Toast.LENGTH_SHORT).show();
dbList = new ArrayList<>();
dbList.addAll(countryModels);
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView name,email;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
name = (TextView) itemLayoutView
.findViewById(R.id.rvname);
email = (TextView)itemLayoutView.findViewById(R.id.rvemail);
itemLayoutView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(context,DetailsActivity.class);
Bundle extras = new Bundle();
extras.putInt("position",getAdapterPosition());
intent.putExtras(extras);
/*
int i=getAdapterPosition();
intent.putExtra("position", getAdapterPosition());*/
context.startActivity(intent);
Toast.makeText(RecyclerAdapter.context, "you have clicked Row " + getAdapterPosition(), Toast.LENGTH_LONG).show();
}
}
}
this is my recyclerAdapterCode.i also used Recycleradapter.setFilter(filterModeList) method but it did not work for me.i think in my set filter method error which i did not solve yet.
. But when I clear the search widget I don't get the full list instead I get the empty RecyclerView.

Get row from selected cell in TableView in JavaFX when setCellSelectionEnabled(true)

I have the following code which works great when I have standard row selection (always single, never multi).
//This is needed to set the X & Y coordinates of the stage for edit.
myTable.setRowFactory(tableView -> {
TableRow<MyDTO> row = new TableRow<MyDTO>();
row.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
lastSelectedRow.set(row);
}
});
return row ;
});
I am using the row to get the bounds in parent so that when a user selects to edit that row, I can pop a modal window up under the row for them to edit this.
However, my table is also editable for the common fields where there is no look up needed, etc. In that case I want to edit in the table. All this is working, however to make it more user friendly, I want to have cell selection turned on, but when I do that, the row.selectedProptery() listener doesn't fire.
How can I accomplish that, without trying to listen to the selectedProperty() of each cell?
Thanks
I don't think there's a way to do this without registering a listener with the selection property of each cell, via a cell factory on each table column.
However, this isn't too difficult, and can be done both generically (i.e. with the same code no matter the type of the table column) and also respecting any other cell factory behavior you need. Here is a SSCCE:
import java.util.Random;
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Callback;
public class SelectedTableCellTracking extends Application {
private final ObjectProperty<TableCell<?,?>> selectedCell = new SimpleObjectProperty<>();
#Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
TableColumn<Item, String> itemCol = column("Item", Item::nameProperty);
TableColumn<Item, Number> valueCol = column("Value", Item::valueProperty);
table.getColumns().add(itemCol);
table.getColumns().add(valueCol);
Random rng = new Random();
for (int i = 1 ; i <= 100; i++) {
table.getItems().add(new Item("Item "+i, rng.nextInt(1000)));
}
table.getSelectionModel().setCellSelectionEnabled(true);
Rectangle highlight = new Rectangle();
highlight.setManaged(false);
highlight.setHeight(12);
highlight.setFill(Color.CORAL);
StackPane root = new StackPane(table, highlight);
selectedCell.addListener((obs, oldCell, newCell) -> {
if (newCell == null) {
highlight.setVisible(false);
} else {
highlight.setVisible(true);
highlight.setX(newCell.localToScene(newCell.getBoundsInLocal()).getMinX());
highlight.setWidth(newCell.getWidth());
highlight.setY(newCell.localToScene(newCell.getBoundsInLocal()).getMaxY());
}
});
table.getColumns().forEach(this::addCellSelectionListenerToColumn);
Scene scene = new Scene(root, 800, 800);
primaryStage.setScene(scene);
primaryStage.show();
}
private <S,T> void addCellSelectionListenerToColumn(TableColumn<S,T> col) {
Callback<TableColumn<S,T>, TableCell<S,T>> currentCellFactory = col.getCellFactory();
col.setCellFactory(tc -> {
TableCell<S,T> cell = currentCellFactory.call(tc);
cell.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
selectedCell.set(cell);
}
});
return cell ;
});
}
private static <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) {
TableColumn<S,T> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
return col ;
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty value = new SimpleIntegerProperty();
public Item(String name, int value) {
setName(name);
setValue(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
}
public static void main(String[] args) {
launch(args);
}
}

Deleting Data From Database Through JavaFX GUI

What I want to be able to do is load my database through a table view select an item and have it deleted into the database. I do not have users entering the id of a particular song so it makes it harder for me to accomplish this. I have the GUI set up and all the code that I have so far.
GUI CODE:
SongContent Code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package playmymusic;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
*
* #author man
*/
public class SongContent
{
private final StringProperty artist;
private final StringProperty title;
private final StringProperty genre;
private final IntegerProperty id;
public SongContent(int id, String artist, String title, String genre)
{
this.artist = new SimpleStringProperty(artist);
this.title = new SimpleStringProperty(title);
this.genre = new SimpleStringProperty(genre);
this.id = new SimpleIntegerProperty(id);
}
public Integer getId()
{
return id.get();
}
public void setID(int paramId)
{
id.set(paramId);
}
public String getArtist()
{
return artist.get();
}
public void setArtist(String paramArtist)
{
artist.set(paramArtist);
}
public String getTitle()
{
return title.get();
}
public void setTitle(String paramTitle)
{
title.set(paramTitle);
}
public String getGenre()
{
return genre.get();
}
public void setGenre(String paramGenre)
{
genre.set(paramGenre);
}
public StringProperty artistProperty(){return artist;}
public StringProperty titleProperty(){return title;}
public StringProperty genreProperty(){return genre;}
public IntegerProperty idProperty() { return id;}
}
Controller Code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package playmymusic;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
import javafx.beans.property.IntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javax.swing.JOptionPane;
import org.apache.derby.jdbc.ClientDriver;
/**
*
* #author man
*/
public class FXMLDocumentController implements Initializable {
public LoginModel loginModel = new LoginModel();
#FXML
private TextField txtUsername;
#FXML
private TextField txtPassword;
#FXML
private TextField txtArtist;
#FXML
private TextField fxTitle;
#FXML
private TextField fxGenre;
#FXML
private TableView<SongContent> tableView;
#FXML
private TableColumn<SongContent, Integer> id;
#FXML
private TableColumn<SongContent, String> artist;
#FXML
private TableColumn<SongContent, String> title;
#FXML
private TableColumn<SongContent, String> genre;
private ObservableList<SongContent> data;
#FXML
private void Login(ActionEvent event) throws SQLException {
try {
if(loginModel.isLogin(txtUsername.getText(), txtPassword.getText()))
{
Stage primaryStage = new Stage();
FXMLLoader loader = new FXMLLoader();
Pane root = loader.load(getClass().getResource("PopUpWindow.fxml").openStream());
Scene scene = new Scene(root, 785, 809);
primaryStage.setScene(scene);
primaryStage.show();
PlayMyMusic.primaryStage.close();
}else
{
System.out.println("WOOPS");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#FXML
private void songs(ActionEvent e) throws SQLException, ClassNotFoundException
{
loginModel.insertSongs(txtArtist.getText(), fxTitle.getText(), fxGenre.getText());
try
{
int i = 1;
Connection conn = DriverManager.getConnection("jdbc:derby://localhost:1527/PlayMyMusicDB;user=test;password=test");
data = FXCollections.observableArrayList();
ResultSet rs = conn.createStatement().executeQuery("select * from Song");
while(rs.next())
{
data.add(new SongContent(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4)));
i++;
}
}catch(SQLException ex) {
System.err.println("Error" + ex);
}
id.setCellValueFactory(new PropertyValueFactory<>("id"));
artist.setCellValueFactory(new PropertyValueFactory<>("artist"));
title.setCellValueFactory(new PropertyValueFactory<>("title"));
genre.setCellValueFactory(new PropertyValueFactory<>("genre"));
tableView.setItems(null);
tableView.setItems(data);
txtArtist.clear();
fxTitle.clear();
fxGenre.clear();
}
#FXML
public void deleteItems(ActionEvent e) throws SQLException, ClassNotFoundException
{
Connection c = DriverManager.getConnection("jdbc:derby://localhost:1527/PlayMyMusicDB;user=test;password=test");
int action = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete this item?");
if(action == 0)
{
try
{
IntegerProperty i = SongContent.idProperty();
ResultSet rs = c.createStatement().executeQuery("DELETE FROM Song where i = " + i);
}catch(Exception e1)
{
e1.printStackTrace();
}
}
}
#Override
public void initialize(URL url, ResourceBundle rb)
{
}
}
`
Any explination of why this could not be deleting my data? I would also love it if someone explained to me a strategy of resetting the SongNumberID every time the GUI opened and closed. But, the main goal for me is to figure out how to delete songs.
Thanks so much
-Aaron
The result of calling toString on a SimpleIntegerProperty is something like IntegerProperty [value: 10]. You should use the value, not the IntegerProperty. Furthermore it's better to use a PreparedStatement to create the query. Also you should get the selected item from the table instead of trying to reference a instance method as if it was static:
SongContent song = tableView.getSelectionModel().getSelectedItem();
if (song != null) {
// there is a selection -> delete
...
PreparedStatement statement = c.prepareStatement("DELETE FROM Song WHERE i = ?");
statement.setInt(1, song.getId());
statement.executeUpdate();
...
}
Furthermore you should make sure i is actually the column name of the id column (and not id).

How to populate TableView data on the other screen TextField in JavaFX 2.0

I am having problem in populating data from a table in one screen to a Text Field in the other screen. I have two classes FirstClass containing a textbox and a button. On pressing a button a second window is opened containing a Table of values. As the user double clicks a row the value of the second column of the row should be inserted into the textbox of the FirstClass. Code of both the classes is attached. Thanking you in anticipation.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class FirstClass extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage primaryStage) {
primaryStage.setTitle("First Class");
GridPane gridpane = new GridPane();
gridpane.setPadding(new Insets(5));
gridpane.setHgap(5);
gridpane.setVgap(5);
final TextField userNameFld = new TextField();
gridpane.add(userNameFld, 1, 1);
Button btn = new Button();
btn.setText("Show Table");
gridpane.add(btn, 1, 3);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
String a = TableClass.showDialog(primaryStage, true, "Table Window" );
userNameFld.setText(a);
}
});
StackPane root = new StackPane();
Scene scene =new Scene(root, 300, 250);
root.getChildren().addAll(gridpane);
primaryStage.setScene(scene);
primaryStage.show();
}
}
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class TableClass extends Stage {
private static TableClass dialog;
private static String value = "";
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private Person(String fName, String lName) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
}
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("JACK", "BROWN"),
new Person("JOHN", "VIANNEYS"),
new Person("MICHAEL", "NELSON"),
new Person("WILLIAM", " CAREY")
);
public TableClass(Stage owner, boolean modality, String title) {
super();
initOwner(owner);
Modality m = modality ? Modality.APPLICATION_MODAL : Modality.NONE;
initModality(m);
setOpacity(1);
setTitle(title);
StackPane root = new StackPane();
Scene scene = new Scene(root, 750, 750);
setScene(scene);
GridPane gridpane = new GridPane();
gridpane.setPadding(new Insets(5));
gridpane.setHgap(5);
gridpane.setVgap(5);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("firstName")
);
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(200);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person,String>("lastName")
);
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol);
table.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
if (me.getClickCount() >= 2) {
String srr = table.getItems().get (table.getSelectionModel().getSelectedIndex()).getLastName();
value = srr;
dialog.hide();
}
}
});
gridpane.add(table, 1, 5,1,20 );
root.getChildren().add(gridpane);
}
public static String showDialog(Stage stg, Boolean a , String title){
dialog = new TableClass( stg,a, title);
dialog.show();
return value;
}
}
The quick and easy way (but it introduces coupling between the 2 classes) would be to pass userNameFld to your showDialog method and make it a member of TableClass. You can then change its value from the TableClass class.
A better way would be to bind the value of userNameFld to value.

Resources