I am stuck with this for a while and I am not sure how to fix this. The problem is my SQL query does not get the input from javaFX textfield and passwordfield(I am building a login window).
If I enter the values manually rather than getting them from a textfield the program work fine, otherwise nothing happens when you press login button. The problem occurs at the following lines, of course with no error messages:
preparedStatement.setString(1,txtUserName.getText());
preparedStatement.setString(2,txtPassword.getText());
Here is the full code:
public class LoginWindow implements Initializable{
#FXML
private TextField txtUserName;
#FXML
private PasswordField txtPassword;
#FXML
private Button btnLogin;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
// Setting the login button.
#FXML
private void setBtnLogin(ActionEvent event) {
try {
connection = DBUtilities.getConnection();
String sqlQuery = "SELECT * FROM user_login_details WHERE User_Name = ? AND User_Password = ?";
preparedStatement = connection.prepareStatement(sqlQuery);
preparedStatement.setString(1,txtUserName.getText());
preparedStatement.setString(2,txtPassword.getText());
resultSet = preparedStatement.executeQuery();
if(resultSet.next()) {
DBUtilities.showInforMsg("Logged in:", "You have logged in!");
} else {
DBUtilities.showErrorMsg("Error:", "Invalid username or password");
}
}catch (Exception exception) {
exception.printStackTrace();
}finally {
DBUtilities.closePreparedStatement(preparedStatement);
DBUtilities.closeResultSet(resultSet);
DBUtilities.closeConnection(connection);
}
}
#Override
public void initialize(URL location, ResourceBundle resources) {
btnLogin.setOnAction(this::setBtnLogin);
}
}
Thank you very much. I simply did not gave any ID to the passwordfield.
You can debug by first trying to print the string from your input fields:
String username = txtUserName.getText();
String password = txtPassword.getText();
System.out.println("User name = " + username);
System.out.println("Password = " + password);
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
If the username and password are null then make sure, those fields controller are well bound to the FXML document.
Related
here is my code for the method that I created for my login form.
Everytime "login failed " message commes up even if I entered correct username and password.
What can be wrong here.
public class Controller {
#FXML
private Button cancelbutton;
#FXML
private Label loginmessagelabel;
#FXML
private PasswordField password1;
#FXML
private TextField username1;
PreparedStatement pst;
ResultSet rs;
public void validatelogin() throws SQLException, ClassNotFoundException {
String jdbcURL = "jdbc:mysql://localhost/medibase";
String username = "root";
String password = "0852";
Connection connection = DriverManager.getConnection(jdbcURL,username,password);
Class.forName("com.mysql.jdbc.Driver");
pst=connection.prepareStatement("SELECT * FROM user_account WHERE username=? and password=?");
pst.setString(1, String.valueOf(username1));
pst.setString(2, String.valueOf(password1));
rs = pst.executeQuery();
if(rs.next()){
loginmessagelabel.setText("Congratulations");
} else{
loginmessagelabel.setText("Login failed");
}
}
I found the mistake and fixed it
here are the changes that I made.
String uname = username1.getText();
String psd = password1.getText();
pst=connection.prepareStatement("SELECT * FROM user_account WHERE
username=? and password=?");
pst.setString(1, uname);
pst.setString(2, psd);
I took separate variables and assigned the vales form the textboxes by useing getText() method.
I'm trying to create an application using JavaFX. I want to get current logged userid and username, after successful login. I want to display it is in the home page. How can i do this? please help
MediaController.java
#FXML
private Label tf_getname;
#FXML
void happyButton(ActionEvent event) {
DbConnect dbconnect=new DbConnect();
Connection conn=dbconnect.getConnection();
String username = tf_getname.getText();
// String source1 = event.getSource().toString(); //yields complete string
//String source2 = event.getPickResult().getIntersectedNode().getId(); //returns JUST the id of the object that was clicked
// System.out.println("Full String: " + source1);
// System.out.println("Just the id: " + source2);
// System.out.println(" " + source2);
try {
String sql = "SELECT name FROM users WHERE name='"+username+"'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
tf_getname.setText(rs.getString("name"));
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
Let me get this straight, you have the user login, then change the scene to a main window, but you want to remember the user that logged in and display that username on the homepage?
Sounds like you will have to pass data between scenes.
For that you will need to approach this in OOP. Have a object class representing your user with all the getters and setters.
public class User {
private String email;
public User(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
When you connect to the database at login, validate user then instantiate an object of the "User" class for example, then pass it to the mainwindow scene your are loading.
public class LoginController implements Initializable {
public User user;
// All your FXML code
#FXML
void handleLogin(ActionEvent actionEvent) throws IOException {
// Do your validation and then call the changeToMainWindow()
changeToMainWindow();
}
}
Have a "initData" class or something in the mainwindowcontroller.
Like
public void initData(User user) {
selectedUser = user;
labelUser.setText(selectedUser.getEmail());
}
Then from your login class, upon validation, send the data to the mainwindow before changing your scene by instantiating your User, then passing the object to the initData method from your second scene.
//User validation, then:
// Get the FXMLLoader then
//Instantiate the mainwindow controller:
public void changeToMainWindow() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("mainwindow.fxml"));
Parent root = loader.load();
Scene mainScene = new Scene(root);
// access the controller
MainWindowController mainWindowController = loader.getController();
mainWindowController.initData(user);
Stage primaryStage = (Stage) loginButton.getScene().getWindow();
primaryStage.setScene(mainScene);
primaryStage.show();
}
Then upoin login, use the changeToMainWindow() method and it'll pass the user.
In the above example I am simply passing email, but you get the point.
I think there is something wrong with your statement. Try out the following way to set up and execute a Statement.
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("Select * from test");
while(rs.next()){
System.out.println(rs.getString("name"));
con.close();
}
}catch(Exception e){
}
I have a problem with this piece of code. When I pass user and pass arguments to isLogin fucntion it throws ORA-01008 errror. I am connected to Oracle database using jdbc.
public boolean isLogin(Connection conn, String user, String pass) throws SQLException{
String sql = "SELECT * FROM PRACOWNIK WHERE imie =? AND nazwisko =? ";
PreparedStatement stmt;
ResultSet rs;
try {
stmt = conn.prepareStatement(sql);
stmt.setString(1, user);
stmt.setString(2, pass);
rs = stmt.executeQuery(sql);
if(rs.next()){
return true;
}
else {
return false;
}
} catch (SQLException e){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error ");
alert.setContentText(e.getMessage());
alert.showAndWait();
return false;
}
}
I use this function in Controller class
public class Controller implements Initializable{
public Pracownik pracownik = new Pracownik();
#FXML
private Label isConnected;
#FXML
private TextField txtUsername;
#FXML
private TextField txtPass;
private Connection conn;
// private ObservableList<Pracownik> lista = FXCollections.observableArrayList();
public void initialize(URL url, ResourceBundle rb){
conn = DBConnection.getConnection();
// lista = new Pracownik().getAll(conn);
}
public void login(ActionEvent event){
try {
if(pracownik.isLogin(conn, txtUsername.getText(), txtPass.getText())){
isConnected.setText("Correct");
}
else{
isConnected.setText("False");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
And this is a error message
Caused by: Error : 1008, Position : 0, Sql = SELECT pesel FROM PRACOWNIK WHERE imie =:1 AND nazwisko =:2 , OriginalSql = SELECT pesel FROM PRACOWNIK WHERE imie =? AND nazwisko =? , Error Msg = ORA-01008: not all variables bound
When I use normal Select query just to print the table everything is fine.
You should NOT specify the SQL query again. It's already specified. Change the line:
rs = stmt.executeQuery(sql); // method from java.sql.Statement
to:
rs = stmt.executeQuery(); // method from java.sql.PreparedStatement
The first method does not take parameters into consideration and runs the SQL "as is"... and therefore you get the error you mention.
This question already has answers here:
Pass data between classes
(2 answers)
Closed 5 years ago.
Given a login window which requires 2 inputs from the user: username & password.
After being identified successfully the user gets redirected to the main window.
Here I want to display his or her username but I'm receiving null.
This is my current code:
Login class:
private void LoginUser(String username, String password)
{
user = username;
pass = password;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try
{
conn = MainEngine.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT username FROM users WHERE username ='"+user+"' AND password ='"+getMD5Hex(pass)+"'");
if(rs.next()) // Successful login
{
Window_AfterLogin window_afterlogin = new Window_AfterLogin();
window_afterlogin.setVisible(true);
this.dispose();
}
else
{
label_info.setText("Wrong credentials");
}
}
catch(Exception e)
{
System.err.println(e);
}
}
public String getUserName()
{
return user;
}
Note: user and pass variables are global.
Window_AfterLogin class:
public Window_AfterLogin() {
initComponents();
Window_Login window_login = new Window_Login();
System.out.println(window_login.getUserName());
}
Your Window_AfterLogin() constructor initializes another Window_Login which means there is the username, which you try to retrieve by window_login.getUserName() - null.
In your after login code you could add another field username:
public Window_AfterLogin{
private String username;
public Window_AfterLogin(String username){
initComponents();
this.username = username;
}
}
Where inside your LoginUser class you have to change the code accordingly:
if(rs.next()) // Successful login
{
Window_AfterLogin window_afterlogin = new Window_AfterLogin(user);
window_afterlogin.setVisible(true);
this.dispose();
}
Note:
Your application is vulnerable to SQL-Injections. Please read about prepared statements and how SQL-Injections work in theory and try to prevent them.
https://de.wikipedia.org/wiki/SQL-Injection
https://www.tutorialspoint.com/javaexamples/jdbc_prepared_statement.htm
In the constructor, you are creating a new instance of the Window_Login class and not setting the username.
At the moment i have a work around for this problem it is to use a textfield and a combobox this however is very untidy and wish to remove the textfield as this is to enter data into a mysql database and also retrieve it so i need to be able to add the result to the combobox as thou it where a textfield
private void jTextField15KeyReleased(java.awt.event.KeyEvent evt) {
String ThePub = jTextField15.getText();
int publengh = ThePub.length();
if (publengh > 2) {
jTextField15.setVisible(false);
fillpub(ThePub);
}
public void fillpub(String pub) {
Connection con;
ResultSet rs;
PreparedStatement pst;
String thedata;
try {
String cs = "jdbc:mysql://localhost:3306/booksalvation4";
String user = "root";
String password = "letmein";
pub = "'" + pub + "%'";
con = DriverManager.getConnection(cs, user, password);
String query = "select * from publisher where name like" + pub;
pst = con.prepareStatement(query);
rs = pst.executeQuery();
while (rs.next()) {
thedata = rs.getString(2);
jComboBox11.addItem(thedata);
}
} catch (SQLException ex) {
Logger.getLogger(mainJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Don't use a KeyListener.
Instead you should be using a DocumentListener. You can add the DocumentListener to the Document of the text field that is being used as the editor for the JComboBox.
See the getEditor() method of JComboBox. Once you have the ComboBoxEditor you can get the editor component which by default is a JTextField. Then you add the DocumentListener to the text field.
Read the section from the Swing tutorial on How to Write a Document Listener for more information.