1. DBConnectionPane.java
/*
* This class defines an extension of BorderPane that allows the user to select
* or enter a JDBC driver and a database URL, plus a username and password.
* The pane establishes a connection to that driver and URL when its Connect to
* DB button is clicked, unless there are errors. If the user later changes the
* connection, the previous connection is closed and a new one established; if
* an error occurs, the previous connection is closed and the connection
* property is set to null.
*
* The driver input combo box only offers the MySQL driver. Oracle has removed
* the JDBC-ODBC bridge driver from Java 8, and the online Oracle database
* access doesn't work for me; the page won't load.
*
* Author: Bill Rutherford
*
*/
import javafx.scene.layout.*;
import javafx.scene.control.*;
import javafx.geometry.*;
import java.sql.*;
public class DBConnectionPane extends BorderPane {
/** Database connection object */
private Connection connection;
// UI input controls
private Label lblStatus = new Label();
private ComboBox<String> cboDriver = new ComboBox<>();
private ComboBox<String> cboDatabaseURL = new ComboBox<>();
private TextField tfUsername = new TextField();
private PasswordField pfPassword = new PasswordField();
public DBConnectionPane() {
// Set up the combo boxes
cboDriver.getItems().add("com.mysql.jdbc.Driver");
cboDriver.setEditable(true);
cboDatabaseURL.getItems().addAll("jdbc:mysql://localhost/javabook",
"jdbc:mysql://localhost/test");
cboDatabaseURL.setEditable(true);
// Create UI
HBox labelPane = new HBox();
labelPane.setPadding(new Insets(5, 10, 10, 10));
labelPane.getChildren().add(lblStatus);
GridPane inputPane = new GridPane();
inputPane.setPadding(new Insets(0, 10, 0, 10));
inputPane.setHgap(10);
inputPane.setVgap(10);
inputPane.add(new Label("JDBC Drive"), 0, 0);
inputPane.add(cboDriver, 1, 0);
inputPane.add(new Label("Database URL"), 0, 1);
inputPane.add(cboDatabaseURL, 1, 1);
inputPane.add(new Label("Username"), 0, 2);
inputPane.add(tfUsername, 1, 2);
inputPane.add(new Label("Password"), 0, 3);
inputPane.add(pfPassword, 1, 3);
Button btConnect = new Button("Connect to DB");
HBox buttonPane = new HBox();
buttonPane.setPadding(new Insets(0, 10, 10, 10));
buttonPane.setAlignment(Pos.CENTER_RIGHT);
buttonPane.getChildren().add(btConnect);
2. setTop(labelPane);
setCenter(inputPane);
setBottom(buttonPane);
// Set button event handler
btConnect.setOnAction(e -> connectToDB());
}
// Create DB connection object and return it in the connection property
private void connectToDB() {
try {
if (connection != null) { // A previous connection was established
connection.close();
connection = null;
}
Class.forName(cboDriver.getValue()); // Load the driver
String databaseURL = cboDatabaseURL.getValue();
connection = DriverManager.getConnection(databaseURL,
tfUsername.getText(), pfPassword.getText());
lblStatus.setText("Connected to " + databaseURL);
}
catch (NullPointerException ex) {
lblStatus.setText("Please enter a driver name");
}
catch (ClassNotFoundException ex) {
lblStatus.setText("Invalid driver name, or driver not installed");
}
catch (SQLException ex) {
if (ex.getMessage().contains("Access denied"))
lblStatus.setText("Invalid username/password combination");
else if (ex.getMessage().contains("No suitable driver found"))
lblStatus.setText("Invalid database URL");
else if (ex.getMessage().contains("The url cannot be null"))
lblStatus.setText("Please enter a database URL");
else if (ex.getMessage().contains("Unknown database"))
lblStatus.setText(ex.getMessage());
else {
lblStatus.setText("Unexpected error");
ex.printStackTrace();
}
}
}
/** Return connection property */
public Connection getConnection() {
return connection;
}
}
TestDBConnectionPane.java
/*
* This program defines a DBConnectionPane class that extends BorderPane, and
* tests it. The test program displays two windows - the test window as the
* primary stage, and the DBConnectionPane window off to the left as a secondary
* stage. The test window uses the connection defined in the connection window
* to obtain and show the tables in the database when its Show Database Tables
* button is clicked.
*
* Author: Bill Rutherford
*
*/
3. import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.geometry.Pos;
import javafx.scene.layout.*;
import javafx.scene.control.*;
import java.sql.*;
public class TestDBConnectionPane extends Application {
private TextArea taTables = new TextArea();
@Override
public void start(Stage primaryStage) {
// Create connection pane
DBConnectionPane dbPane = new DBConnectionPane();
// Create UI for test window
Button btShowTables = new Button("Show Database Tables");
HBox buttonPane = new HBox(10);
buttonPane.setAlignment(Pos.CENTER);
buttonPane.getChildren().add(btShowTables);
taTables.setEditable(false);
taTables.setWrapText(true);
VBox testPane = new VBox(10);
testPane.getChildren().addAll(taTables, buttonPane);
// Set button event handler
btShowTables.setOnAction(e -> showDatabaseTables(dbPane));
// Set up the test pane in the primary stage and show it
Scene testScene = new Scene(testPane, 300, 150);
primaryStage.setTitle("Test DBConnectionPane");
primaryStage.setScene(testScene);
primaryStage.show();
// Create a secondary stage, set up the connection pane in it, and show
// it off to the left of the test window
Stage secondaryStage = new Stage();
Scene dbScene = new Scene(dbPane, 320, 210);
secondaryStage.setTitle("DB Connection");
secondaryStage.setScene(dbScene);
secondaryStage.setX(primaryStage.getX() - 350);
secondaryStage.setY(primaryStage.getY() - 30);
secondaryStage.show();
}
// Obtain and show the table names in the database
private void showDatabaseTables(DBConnectionPane dbPane) {
Connection connection = dbPane.getConnection();
String tables = "";
try {
DatabaseMetaData dbMetaData = connection.getMetaData();
ResultSet rsTables = dbMetaData.getTables(null, null, null,
new String[] {"TABLE"});
while (rsTables.next())
tables += (rsTables.getString("TABLE_NAME") + " ");
if (tables.equals(""))
taTables.setText("No tables in database");
else
taTables.setText(tables);
}