After looking at Trouble inserting data in a SQLite databae, I tried to add 'c.commit();' before I leave the stage and closing the connection c. However it keeps giving me busy for some reason. Don't know if the dynamically added buttons 'addClass' are causing problems with the on action event handlers or not.
the controller file:
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import userGroups.Student;
import java.io.IOException;
import java.sql.*;
public class ClassesController{
private Student user;
@FXML
private GridPane grid;
private int currentId;
private Connection c;
public void initialize(){
Statement stmt;
try{
c = DriverManager.getConnection("jdbc:sqlite:users.db");
//c.setAutoCommit(false);
stmt = c.createStatement();
int currentCol = 0;
int currentRow = 1;
currentId = 1;
ResultSet rs = stmt.executeQuery("SELECT * FROM Classes;");
//assuming all columns are NOT NULL
while(rs.next()){
Label label1 = new Label();
label1.setText(rs.getString("CLASSNAME"));
label1.setAccessibleText(rs.getString("CLASSNAME"));
grid.add(label1, currentCol++, currentRow);
Label label2 = new Label();
label2.setText(rs.getString("SIZE"));
grid.add(label2, currentCol++, currentRow);
Label label3 = new Label();
label3.setText(rs.getString("SPOTSTAKEN"));
grid.add(label3, currentCol++, currentRow);
Label label4 = new Label();
label4.setText(rs.getString("INSTRUCTOR"));
grid.add(label4, currentCol++, currentRow);
Label label5 = new Label();
label5.setText(rs.getString("CRN"));
label5.setTextAlignment(TextAlignment.CENTER);
grid.add(label5, currentCol++, currentRow);
Label label6 = new Label();
label6.setText(rs.getString("DAYS"));
grid.add(label6, currentCol++, currentRow);
Label label7 = new Label();
label7.setText(militaryToRegularTime(rs.getString("STARTTIME")) + "-"
+ militaryToRegularTime(rs.getString("ENDTIME")));
grid.add(label7, currentCol++, currentRow);
Label label8 = new Label();
label8.setText(rs.getString("AREA"));
grid.add(label8, currentCol++, currentRow);
Button addClass = new Button();
addClass.setMaxWidth(Double.MAX_VALUE);
addClass.setText("Add Class");
grid.add(addClass, currentCol, currentRow);
addClass.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e){
Object[] a = addClass.getProperties().values().toArray();//array of row and col values of addClass
int classIndex = Integer.parseInt(a[1].toString());//index of class corresponding to the button
String className = grid.getChildren().get(classIndex * 9).getAccessibleText();
if(studentHasClass(classIndex))//finds if student has the class at specific row of button
User.showAlert("You have already added this class!");
else
addClassToUser(classIndex, className);
addClass.setDisable(true);
}
});
currentCol = 0;
currentRow++;
currentId++;
}
rs.close();
stmt.close();
} catch ( Exception e ){
e.printStackTrace();
User.showAlert("Please contact the admin.");
System.exit(0);
}
}
//adds class at classIndex to student user in database in table CLASSES_HAVE_STUDENTS
private void addClassToUser(int classIndex, String className){
try{
PreparedStatement statement = c.prepareStatement(
"INSERT INTO CLASSES_HAVE_STUDENTS (CLASS_ID, CLASS_NAME, STUDENT_ID, S_USERNAME) VALUES(?,?,?,?)");
statement.setInt(1, classIndex);
statement.setString(2, className);
statement.setInt(3, user.getId());
statement.setString(4, user.getUserName());
statement.executeUpdate();
c.commit();
statement.close();
} catch ( Exception e ){
e.printStackTrace();
User.showAlert("Please contact the admin.");
System.exit(0);
}
}
//Return a boolean where if student user has a class at id
private boolean studentHasClass(int classIndex){
Statement stmt;
try{
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT S_USERNAME FROM CLASSES_HAVE_STUDENTS WHERE CLASS_ID= " + classIndex + ";");
while(rs.next()){
if(rs.getString("S_USERNAME").equals(user.getUserName())){
rs.close();
stmt.close();
return true;
}
}
rs.close();
stmt.close();
} catch ( Exception e ){
e.printStackTrace();
User.showAlert("Please contact an admin.");
System.exit(0);
}
return false;
}
//assumes militaryTime is in '00:00:00' format. returns regular time in '00:00' format
private String militaryToRegularTime(String militaryTime)
{
Integer hour = Integer.parseInt(militaryTime.substring(0, 2));
if(hour > 12){
hour = hour - 12;
return "0" + hour.toString() + militaryTime.substring(2, 5) + " pm";
}
return militaryTime.substring(0, 5) + " am";
}
//Changes stage to the previous stage
public void pressBack(ActionEvent event) throws IOException{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("studentOptions.fxml"));
loader.load();
StudentOptionsController display = loader.getController();
display.setUser(user);
try{
//c.commit();
c.close();
} catch (Exception e){
e.printStackTrace();
User.showAlert("Please contact the admin.");
System.exit(0);
}
Parent userOption = loader.getRoot();
Scene classesToAddScene = new Scene(userOption);
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(classesToAddScene);
app_stage.show();
}
public void setUser(Student user){
this.user = user;
}
}
stacktrace:
org.sqlite.SQLiteException: [SQLITE_BUSY] The database file is locked (database is locked)
at org.sqlite.core.DB.newSQLException(DB.java:909)
at org.sqlite.core.DB.newSQLException(DB.java:921)
at org.sqlite.core.DB.execute(DB.java:822)
at org.sqlite.core.DB.executeUpdate(DB.java:863)
at org.sqlite.jdbc3.JDBC3PreparedStatement.executeUpdate(JDBC3PreparedStatement.java:99)
at login.ClassesController.addClassToUser(ClassesController.java:123)
at login.ClassesController.access$200(ClassesController.java:21)
at login.ClassesController$1.handle(ClassesController.java:94)
at login.ClassesController$1.handle(ClassesController.java:80)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8863)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3876)
at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
at java.base/java.lang.Thread.run(Thread.java:844)