Существует 4 java-файла - SargonVenture, TimesheetScene, StaffTimesheetAccessor и StaffTimesheet.
SargonVenture - это основная программа, которая запускает программу и отображает TimesheetScene следующим образом: TimesheetSceneImage
StaffTimesheetAccessor - это соединитель базы данных, который выполняет запрос и сохраняет результат запроса в объекте StaffTimesheet, который затем сохраняется в observableArrayList ().
В TimesheetScene я хочу сделать следующее (если TableColumnofdayListColumn равно значению TaskDay объекта StaffTimesheet, хранящегося в observableArrayList, тогда он будет отображать TaskNumberOfHours в соответствующих столбцах dayListColumn).Секция ошибки комментируется в файле TimesheetScene.
Коды приведены ниже.
SargonVenture.java:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class SargonVenture extends Application {
private static Stage primaryStage;
private static Scene scene;
@Override
public void start(Stage primaryStage) throws Exception {
SargonVenture.primaryStage = primaryStage;
TimesheetScene timesheetScene = new TimesheetScene();
scene = new Scene(timesheetScene);
primaryStage.setTitle("");
primaryStage.setScene(scene);
primaryStage.show();
}
public void setStage(Stage stage)
{
primaryStage = stage;
}
public static Stage getStage()
{
return primaryStage;
}
public static void setNewScene(Scene scene)
{
SargonVenture.scene = scene;
}
public static Scene getTheScene()
{
return scene;
}
public static void main(String[] args) {
launch(args);
}
}
TimesheetScene.java:
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
public class TimesheetScene extends BorderPane{
private final TableView<StaffTimesheet> tableView = new TableView<>();
private final ComboBox<String> comboBoxStaffName;
private final ComboBox<String> comboBoxMonth;
private final ComboBox<String> comboBoxYear;
Button buttonSearch;
private final StaffTimesheetAccessor dataTimesheetAccessor;
public TimesheetScene() throws SQLException, ClassNotFoundException{
dataTimesheetAccessor = new StaffTimesheetAccessor("com.mysql.cj.jdbc.Driver", "jdbc:mysql://localhost/rka?useTimezone=true&serverTimezone=UTC", "root", "291222");
GridPane gridPane1 = new GridPane();
gridPane1.setHgap(10);
GridPane gridPane2 = new GridPane();
gridPane2.setHgap(10);
GridPane gridPane3 = new GridPane();
gridPane3.setHgap(10);
comboBoxStaffName = new ComboBox<>();
comboBoxStaffName.getItems().addAll(dataTimesheetAccessor.getStaffName());
gridPane1.add(new Label("Staff Name: "), 0, 0);
gridPane1.add(comboBoxStaffName, 1, 0);
comboBoxMonth = new ComboBox<>();
comboBoxMonth.getItems().addAll("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12");
comboBoxMonth.setValue("01");
gridPane2.add(new Label("Month: "), 0, 0);
gridPane2.add(comboBoxMonth, 1, 0);
comboBoxYear = new ComboBox<>();
comboBoxYear.getItems().addAll(dataTimesheetAccessor.getYear());
gridPane3.add(new Label("Year: "), 0, 0);
gridPane3.add(comboBoxYear, 1, 0);
HBox hbox1 = new HBox(100);
hbox1.getChildren().addAll(gridPane1, gridPane2, gridPane3);
hbox1.setPadding(new Insets(0, 0, 0, 0));
buttonSearch = new Button("Search");
HBox hbox2 = new HBox(40);
hbox2.getChildren().addAll(hbox1, buttonSearch);
hbox2.setAlignment(Pos.CENTER);
hbox2.setPadding(new Insets(20, 50, 20, 50));
setTop(hbox2);
TableColumn dayColumn = new TableColumn("Day");
tableView.getColumns().addAll(dayColumn);
TableColumn[] dayListColumn = new TableColumn[31];
int x = 1;
for(int i = 0; i < dayListColumn.length; i++)
{
String y = String.valueOf(x);
dayListColumn[i] = new TableColumn(y);
dayColumn.getColumns().add(dayListColumn[i]);
// HERE IS THE ERROR
if(dayListColumn[i].getText().equals(dataTimesheetAccessor.getStaffDayHourList().get(i).getTaskDay())){
dayListColumn[i].setCellValueFactory(new PropertyValueFactory<>("TaskNumberOfHours"));
}
x=x+1;
}
buttonSearch.setOnAction(e ->{
String staffName = comboBoxStaffName.getValue();
String monthOfTaskDay = comboBoxMonth.getValue();
String yearOfTaskDay = comboBoxYear.getValue();
try {
tableView.setItems(dataTimesheetAccessor.getStaffDayHour(staffName, monthOfTaskDay, yearOfTaskDay));
} catch (SQLException ex) {
Logger.getLogger(TimesheetScene.class.getName()).log(Level.SEVERE, null, ex);
}
});
setCenter(tableView);
}
}
StaffTimesheetAccessor.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class StaffTimesheetAccessor {
private final Connection connection;
ObservableList<StaffTimesheet> staffDayHourList;
public StaffTimesheetAccessor(String driverClassName, String dbURL, String user, String password) throws SQLException, ClassNotFoundException{
Class.forName(driverClassName);
connection = DriverManager.getConnection(dbURL, user, password);
}
public void shutdown() throws SQLException {
if(connection != null)
{
connection.close();
}
}
public ObservableList<StaffTimesheet> getStaffDayHour(String staffName, String monthOfTaskDay, String yearOfTaskDay) throws SQLException{
String nameOfStaff = staffName;
String month = monthOfTaskDay;
String year = yearOfTaskDay;
try(
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT DAY(Timesheet.TaskDay), ROUND((Timesheet.TaskNumberOfHours + (Timesheet.TaskNumberOfMinutes/60)), 2)\n" +
"FROM Clients\n" +
"INNER JOIN Timesheet ON Clients.ClientID = Timesheet.ClientID\n" +
"INNER JOIN Task ON Task.TaskID = Timesheet.TaskID\n" +
"INNER JOIN Staff ON Timesheet.StaffID = Staff.StaffID\n" +
"WHERE Staff.StaffName = '" + nameOfStaff + "'\n" +
"AND MONTH(Timesheet.TaskDay) = " + month + "\n" +
"AND YEAR(Timesheet.TaskDay) = " + year + ";");
)
{
staffDayHourList = FXCollections.observableArrayList();
while(resultSet.next()){
String TaskDay = resultSet.getString(1);
String TaskNumberOfHours = resultSet.getString(2);
staffDayHourList.add(new StaffTimesheet(TaskDay, TaskNumberOfHours));
}
return staffDayHourList;
}
}
public ObservableList<StaffTimesheet> getStaffDayHourList(){
return staffDayHourList;
}
public ObservableList<String> getStaffName() throws SQLException{
try(
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select StaffName from Staff");
){
ObservableList<String> staffNameList = FXCollections.observableArrayList();
while(resultSet.next()){
String StaffName = resultSet.getString(1);
staffNameList.add(StaffName);
}
return staffNameList;
}
}
public ObservableList<String> getYear() throws SQLException{
try(
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select DISTINCT(YEAR(TaskDay)) from Timesheet");
){
ObservableList<String> timesheetYearList = FXCollections.observableArrayList();
while(resultSet.next()){
String timesheetYear = resultSet.getString(1);
timesheetYearList.add(timesheetYear);
}
return timesheetYearList;
}
}
}
StaffTimesheet.java:
import javafx.beans.property.SimpleStringProperty;
public class StaffTimesheet{
private SimpleStringProperty TaskDay;
private SimpleStringProperty TaskNumberOfHours;
public StaffTimesheet(String TaskDay, String TaskNumberOfHours){
this.TaskDay = new SimpleStringProperty(TaskDay);
this.TaskNumberOfHours = new SimpleStringProperty(TaskNumberOfHours);
}
public String getTaskDay(){
return TaskDay.get();
}
public void setTaskDay(String TaskDay){
this.TaskDay.set(TaskDay);
}
public String getTaskNumberOfHours(){
return TaskNumberOfHours.get();
}
public void setTaskNumberOfHours(String TaskNumberOfHours){
this.TaskNumberOfHours.set(TaskNumberOfHours);
}
}
Результат запроса следующий: Изображение результата запроса