Populate TableView using Derby Database - javafx

This is my first time using Derby database and I am having trouble adding information into my tableview.
public class AddController implements Initializable {
final String DB_URL = "jdbc:derby:StudentDB;";
#FXML TableView<Student> studentListView;
#FXML TableColumn stuName;
#FXML TableColumn stuAge;
#FXML TableColumn stuMajor;
#FXML TableColumn stuGPA;
#FXML ComboBox ageCB;
#FXML ComboBox majorCB;
#FXML ComboBox gpaCB;
ObservableList<Student> studentList;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
studentList = FXCollections.observableArrayList();
createDB();
createStudentsDB();
studentListView.setItems(studentList);
}
public void createDB(){
try
{
Connection conn = DriverManager.getConnection("jdbc:derby:StudentDB;create=true");
conn.close();
System.out.println("Connection successful");
}
catch(Exception ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
public void createStudentsDB(){
try{
Connection conn = DriverManager.getConnection(DB_URL);
Statement stmt = conn.createStatement();
stmt.execute("DROP TABLE Student");
stmt.execute("CREATE TABLE Student (" +
"Name CHAR(25), " +
"Age INT, " +
"Major CHAR(45), " +
"GPA DECIMAL, ");
String sql = "INSERT INTO Student VALUES" +
"('Robert', 21, 'Computer Information Systems', 3.8)";
stmt.executeUpdate(sql);
String sqlStatement = "SELECT Name, Age, Major, GPA FROM Student";
ResultSet result = stmt.executeQuery(sqlStatement);
ObservableList<Student> studentList = FXCollections.observableArrayList();
while (result.next())
{
Student newStudent = new Student();
newStudent.name = result.getString("Name");
newStudent.age = result.getInt("Age");
newStudent.major = result.getString("Major");
newStudent.gpa = result.getDouble("GPA");
studentList.add(newStudent);
}
stmt.close();
conn.close();
}
catch (Exception ex)
{
var msg = ex.getMessage();
System.out.println(msg);
}
}
<TableView fx:id="studentListView" prefWidth="400">
<columns>
<TableColumn fx:id="stuName" text="Student" prefWidth="125"/>
<TableColumn fx:id="stuAge" text="Age" prefWidth="75"/>
<TableColumn fx:id="stuMajor" text="Major" prefWidth="125"/>
<TableColumn fx:id="stuGPA" text="GPA" prefWidth="75"/>
</columns>
</TableView>
I already created a TableView in FXML with the 4 columns I want. I just do not know how to get the information from the database to the TableView.

This code reads from a Derby Database the table is named Parent
We are using a MVC Model View Controller Pattern
And we strongly suggest you use the MVC concept when working with any database
private void ReadFromParent() throws SQLException{
ObservableList<ParentModel> TableData = FXCollections.observableArrayList();
stmnt = conn.createStatement();
ResultSet rs = stmnt.executeQuery("SELECT * FROM Parent");
while (rs.next()){// Add data to observableArrayList TableData to select a table ROW
TableData.add(new ParentModel(rs.getString("PID"),rs.getString("pMonth"),rs.getString("pYear")));
}
PropertyValueFactory<ParentModel, String> IDCellValueFactory = new PropertyValueFactory<>("PID");
colID.setCellValueFactory(IDCellValueFactory);
PropertyValueFactory<ParentModel, String> DateCellValueFactory = new PropertyValueFactory<>("pMonth");
colMonth.setCellValueFactory(DateCellValueFactory);
PropertyValueFactory<ParentModel, String> TypeCellValueFactory = new PropertyValueFactory<>("pYear");
colYear.setCellValueFactory(TypeCellValueFactory);
// ================================================================
// colTxDate are the ID's for the tableview columns
// sortDate are the Column Names for the Database TABLE CDBalance
// ================================================================
colMonth.setStyle("-fx-alignment: CENTER;");
colYear.setStyle("-fx-alignment:CENTER;");
Collections.sort(TableData, (p2, p1)-> p1.getPID().compareToIgnoreCase(p2.getPID()));
// Line of Code above Sorts Database Columns based on VARIABLE in ParentModel
// Change p2,p1 to sort Ascending or Descending
if(TableData.size() < 15) {// Format TableView to display Vertical ScrollBar
ptable.setPrefWidth(336);// 19 is the off set
}else {
ptable.setPrefWidth(355);
} ptable.setItems(TableData);
stmnt.close();
}

Related

Barchart don't show correctly

Hello I have a Barchart in JavaFx, the Data Show just fine when is directly loaded in the initialize method, but When I Load a MouseEvent, the Date label does not show correctly. I Put here a minimized example.
this is my code in IncidentesController
#FXML private ComboBox<String> solicitudindc;
#FXML private JFXButton generarind;
#FXML private BarChart <String,Integer> indicadorsoporte;
#FXML private CategoryAxis fechas;
#FXML private NumberAxis cantidades;
public void generaindicador() {
String Bd="jdbc:sqlserver://DESKTOP-
8PJDQNJ:1433;databaseName=QUORA";
String Usuario="myuser";
String Pass="mypass";
String Query= "SELECT FECHA_EJECUTADA , COUNT(PRIORIDAD) AS CANTIDAD FROM RINCIDENTES WHERE PRIORIDAD='ALTA' GROUP BY FECHA_EJECUTADA ORDER BY FECHA_EJECUTADA ASC";
String Query2= "SELECT FECHA_EJECUTADA , COUNT(PRIORIDAD) AS CANTIDAD FROM RINCIDENTES WHERE PRIORIDAD='MEDIA' GROUP BY FECHA_EJECUTADA ORDER BY FECHA_EJECUTADA ASC";
XYChart.Series<String,Integer> DatosPrioridad = new Series<String,Integer> ();
XYChart.Series<String,Integer> DatosPrioridad2 = new Series<String,Integer> ();
Connection Conexiontabla = null;
try {
............conection code...........
while (rs.next()) {
String y=rs.getString("FECHA_EJECUTADA");
int a=rs.getInt("CANTIDAD");
DatosPrioridad.getData().add(new XYChart.Data<>(y,a) );
}
indicadorsoporte.getData().add(DatosPrioridad);
DatosPrioridad.setName("PRIORIDAD ALTA");
}catch(SQLException e) {
e.printStackTrace();
}
try {
............conection code...........
while (rss.next()) {
String x=rss.getString("FECHA_EJECUTADA");
int z=rss.getInt("CANTIDAD");
DatosPrioridad2.getData().add(new XYChart.Data<>(x,z) );
}
indicadorsoporte.getData().add(DatosPrioridad2);
DatosPrioridad2.setName("PRIORIDAD MEDIA");
fechas.setLabel("Fechas");
cantidades.setLabel("Cantidades");
}catch(SQLException e) {
e.printStackTrace();
}
}
If the Combobox have the value "REPORTE DE INCIDENTES" I load the barchart like this:
public void generaincidentes() {
generarind.setOnMouseClicked(e->{
if(solicitudindc.getSelectionModel().getSelectedItem().toString().equals("REPORTE DE INCIDENTES")) {
generaindicador();
}
});
}
this are the images:
when i load directly in the initialize method:
when I select the option in the combobox to load the Barchart:
any guidance?
This work for me!:
#SuppressWarnings("unchecked")
public ObservableList<XYChart.Series<String, Integer>>
getdatosbarchart() {
String Bd="jdbc:sqlserver://DESKTOP-8PJDQNJ:1433;databaseName=QUORA";
String Usuario="sa";
String Pass="milkas87";
String Query= "SELECT FECHA_EJECUTADA , COUNT(PRIORIDAD) AS CANTIDAD FROM RINCIDENTES WHERE PRIORIDAD='ALTA' GROUP BY FECHA_EJECUTADA ORDER BY FECHA_EJECUTADA ASC";
String Query2= "SELECT FECHA_EJECUTADA , COUNT(PRIORIDAD) AS CANTIDAD FROM RINCIDENTES WHERE PRIORIDAD='MEDIA' GROUP BY FECHA_EJECUTADA ORDER BY FECHA_EJECUTADA ASC";
ObservableList<XYChart.Series<String, Integer>> data =FXCollections.observableArrayList();
Series<String, Integer> as = new Series<>();
Series<String, Integer> bs = new Series<>();
Connection Conexiontabla = null;
try {
Conexiontabla=DriverManager.getConnection(Bd, Usuario, Pass);
PreparedStatement ps =Conexiontabla.prepareStatement(Query);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String y=rs.getString("FECHA_EJECUTADA");
int a=rs.getInt("CANTIDAD");
as.getData().add(new XYChart.Data<>(y,a) );
}
as.setName("PRIORIDAD ALTA");
}catch(SQLException e) {
e.printStackTrace();
}
try {
Conexiontabla=DriverManager.getConnection(Bd, Usuario, Pass);
PreparedStatement pd =Conexiontabla.prepareStatement(Query2);
ResultSet rss = pd.executeQuery();
while (rss.next()) {
String y=rss.getString("FECHA_EJECUTADA");
int a=rss.getInt("CANTIDAD");
bs.getData().add(new XYChart.Data<>(y,a) );
}
bs.setName("PRIORIDAD MEDIA");
fechas.setLabel("Fechas");
cantidades.setLabel("Cantidades");
}catch(SQLException e) {
e.printStackTrace();
}
data.addAll(as,bs);
return data;
}
public BarChart<String, Integer>crearbarchart() {
indicadorsoporte.setData(getdatosbarchart());
indicadorsoporte.setTitle("Soportes realizados en el Mes");
return indicadorsoporte;
}

Javafx pie chart made with data from database does not display data

I am new to Javafx and trying to read and understand tutorials on the internet of how to create charts with data from a Derby database using Scenebuilder.
I have managed to create a bar chart - which works fine.
But I am having some trouble getting the same data shown in a pie chart. Scene builder starts but no pie chart is shown.
What am I missing to have it shown as a pie chart?
Thanks for any help :-)
My code:
public class DocumentController implements Initializable {
#FXML
PieChart piechart;
private Connection connexion;
ArrayList < String > p = new ArrayList < String > ();
ArrayList < Double > c = new ArrayList < > ();
#Override
public void initialize(URL url, ResourceBundle rb) {
loadData();
}
public void loadData() {
String query = "select P, C From PIE "; //ORDER BY P asc
ObservableList < PieChart.Data > piechartdata;
piechartdata = FXCollections.observableArrayList();
try {
connexion = connectDB();
ResultSet rs = connexion.createStatement().executeQuery(query);
while (rs.next()) {
piechartdata.add(new PieChart.Data(rs.getString("P"), rs.getDouble("C")));
p.add(rs.getString("P"));
c.add(rs.getDouble("C"));
}
} catch (Exception e) {
}
}
private Connection connectDB() {
try {
String dbString = "jdbc:derby://localhost:1527/Pie";
String user = "pie";
String password = "pie";
Connection conn = DriverManager.getConnection(dbString, user, password);
System.out.println("Connection Ok");
return conn;
} catch (SQLException ex) {
Logger.getLogger(DocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
I think you forgot to set the data of your ObservableList to your pieChart
try something like this:
piechart.setData(piechartdata);
piechart.setVisible(true);

JavaFX combo box repeating the same value set

I used a combo box to retrieve data from MySQL database. But when i inserted the first value set to database, combo box values are repeating. I want to know why it is happening and how to avoid it. i called this method on main. Thanks
public void FillCombo(){
try{
String sql = "Select Name from Employee where Position='Driver'";
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next()){
op.add(rs.getString("Name"));
}
selectDriverC.setItems(op);
pst.close();
rs.close();
}
catch(Exception e){
System.out.println(e);
}
}
Add a condition that checks if the String you wanna insert is already in op,
I assume op type is ObservableList<String>. This should work :
public void FillCombo(){
try{
String sql = "Select Name from Employee where Position='Driver'";
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next()){
if(!op.contains(rs.getString("Name"))
add(rs.getString("Name"));
}
selectDriverC.setItems(op);
pst.close();
rs.close();
}
catch(Exception e){
System.out.println(e);
}
}

How to edit fxml from code?

So I have a BorderPane in my FXML, what I want to do is to reload my BorderPane.Center properties so it shows a different pane with different layout,
How can I achieve this? The codes below doesn't work for me.
p.s : sorry for indonesian.
My FXML :
<BorderPane fx:id="bPane" xmlns:fx="http://javafx.com/fxml" fx:controller="fx.HomeMhsController" stylesheets="#css.css">
<left>
<VBox spacing="10" fx:id="vbox" id="vbox" prefWidth="100" >
<Label id="Label" fx:id="biodata" text="Biodata" onMouseClicked="#showIdentity"/>
<Label id="Label" fx:id="histori" text="Histori Nilai" onMouseClicked="#showHistory" />
<Label id="Label" fx:id="jadwal" text="Jadwal Kuliah" onMouseClicked="#showSchedule" />
<Label id="Label" fx:id="pilih" text="Pilih Mata Kuliah" onMouseClicked="#chooseSchedule"/>
</VBox>
</left>
My Controller :
public class HomeMhsController{
#FXML private Label biodata2;
#FXML private BorderPane bPane;
#FXML private void showIdentity() throws SQLException{
init.initializeDB();
String query="select * from mahasiswa where nama_dpn ='" + MainController.username + "'";
ResultSet rset = init.stmt.executeQuery(query);
if(rset.next()){
String nim = rset.getString(1);
String nama_dpn = rset.getString(2);
String nama_blkg = rset.getString(3);
String tgl_lahir = rset.getString(4);
String tempat_lahir = rset.getString(5);
String jns_kelamin = rset.getString(6);
String agama = rset.getString(7);
String alamat = rset.getString(8);
String no_hp = rset.getString(9);
biodata2.setText(nim + nama_dpn + nama_blkg + tgl_lahir + tempat_lahir + jns_kelamin + agama + alamat + no_hp);
}
}
#FXML private void showHistory() throws IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
((BorderPane) rootNode).setCenter(pane);
}
#FXML private void showSchedule() throws SQLException, IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label tiga = new Label("3");
Pane pane = new Pane();
pane.getChildren().add(tiga);
((BorderPane) rootNode).setCenter(pane);
}
#FXML private void chooseSchedule() throws SQLException{
}
In the following code snippet:
#FXML private void showHistory() throws IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
((BorderPane) rootNode).setCenter(pane);
}
you are loading the fxml file again, which is a new instance and different from the one you already have (since this method in its controller class). Moreover you are not doing anything with this newly loaded one (i.e. rootNode is not being added to any scene).
Instead just use the existing injected border pane:
#FXML private void showHistory() {
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
bPane.setCenter(pane);
}
or more shorter:
#FXML private void showHistory() {
bPane.setCenter(new Pane(new Label("2")));
}

how to refer to a non-declared variables in setResultConverter

I'd like to re-use a dialog class for data manipulation. The data will be retrieved from database. It depends on which table the class retrieve the data from, the size of the table columns is not fixed, so I can't declare column variables. After users update data, I would like to convert the input data using setResultConverter but do not know how to refer to the variable, since the program generates TextFields dynamically. Please help. Here is the the code.
public class AddDialog {
private Dialog<DBtable> dialog = new Dialog<DBtable>();
private ButtonType saveBtn;
//database variables
private Connection connect; // = null;
private String dbTblName;
//gridpane content variables
private GridPane contentPane = new GridPane();
private HashMap<String, TextField> fieldMap =
new HashMap<String, TextField>();
private ArrayList<String> dataList = new ArrayList<String>();
public AddDialog (String title, String header, String dbTable) {
this.dbTblName = dbTable;
dialog.setTitle(title);
dialog.setHeaderText(header);
saveBtn = new ButtonType("Save", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(saveBtn,
ButtonType.CANCEL);
dialog.getDialogPane().setContent(getLayout(dbTable));
Optional<DBtable> result = dialog.showAndWait();
result.ifPresent(data -> {
System.out.println(" data="+data+" 0="+data.getID()+
" 1="+data.getField1());
});
} // constructor ends
public GridPane getLayout(String dbTable) {
String sql = "select column_name, description ";
sql += "from syscolumn_description ";
sql += "where table_name = \'" + dbTable + "\'";
String fieldLabel, fieldCol;
ResultSet ds = null;
// retrieve meta data from database
connect = DBConnect.getConnect(connect);
try {
Statement labelStmnt = connect.createStatement();
ds = labelStmnt.executeQuery(sql);
int row = 0;
while (ds.next()) {
row += 2;
//label....column=0 row=row+2;
fieldLabel = ds.getString("DESCRIPTION");
contentPane.add(new Text(fieldLabel), 0, row);
//textField...column=1 row=row+2;
contentPane.add(new TextField(), 1, row);
fieldCol = ds.getString("COLUMN_NAME");
fieldMap.put(fieldCol, new TextField());
} // while result set loop ends
} catch (Exception e) {
e.printStackTrace();
} finally {
try {if(ds != null) ds.close();} catch (Exception e) {};
}
// convert result
dialog.setResultConverter(dialogButton -> {
if (dialogButton == saveBtn) {
int i=0;
for (Map.Entry<String, TextField> e : fieldMap.entrySet()) {
dataList.add(e.getValue().getText());
i++;
System.out.println("col="+e.getKey()+
" data="+e.getValue().getText());
} // map loop end
return new DBtable(dataList, i);
}
return null;
});
return contentPane;
} //getLayout ends
} // AddDialog ends

Resources