running methods declared in a swing.Jframe Class - java

I have created two swing.JFrames.
login GUI and user GUI. what I want is when it's switches to login gui to user gui, there is a Jlabel in user GUI which needs to be changed as ("you're logged in as" + username);
I tried this code in userjframe source code.
`loggedInAsLable.setText("you're logged in as" + username);`
in a method and it's called in main method of user jframe. but for some reasons
it doesn't work.
how can I run some methods when a Jframe is becoming visible?
public class CustomerServiceOfficerUI extends javax.swing.JFrame {
private static Statement st;
ResultSet rs;
Connection con = null;
Login loginUI = new Login(); // gets current user Id
Employee cso = new CustomerServiceOfficer(); //creates new customer service officer object
/**
* Creates new form CustomerServiceOfficer
*/
public CustomerServiceOfficerUI() {
initComponents();
}
public void getCSOdetails() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/flyingcarsdb", "root", "");
System.out.println("database connected");
} catch (ClassNotFoundException | SQLException ex) {
System.out.println("Error: " + ex);
}
try {
// Retrieve customer service officer details
st = con.createStatement();
String query = "select * FROM customerserviceofficer WHERE Id = '" + loginUI.getCurrentUserId() + "'";
rs = st.executeQuery(query);
while (rs.next()) {
//Assign the details with setters
cso.setFname(rs.getString("Fname"));
cso.setEmail(rs.getString("Email"));
}
} catch (Exception ex) {
System.out.println("Error : " + ex);
}
loggedInAsLable.setText("you're logged in as : " + cso.getId());
//this is where LABLE is changed, 'cso.getId()' returns the user ID
}

If you really need to update your JFrame when it becomes visible (as your last statement suggests), you can use the the WindowListener to call your getCSODetails() method.
public CustomerServiceOfficerUI() {
initComponents();
this.addWindowListener(new WindowAdapter() {
#Override
public void windowOpened(WindowEvent e)
{
this.getCSODetails();
}
#Override
public void windowDeiconified(WindowEvent e)
{
this.getCSODetails();
}
#Override
public void windowActivated(WindowEvent e)
{
this.getCSODetails();
}
});
}
I've included three activation events - opening, activation and deiconfication; you can remove any of them to limit the update to a specific event suiting your needs. If you need to update the label only once the window is opened, remove the methods windowDeiconified() and windowActivated().
Note, however, that the getCSODetails() method is designed quite poorly and calling it whenever the window becomes visible/focused would incur a performance penalty and the responsiveness of your GUI will be heavily influenced by performance of your database. I guess that the customer details you're displaying are not changed during a login session, so it would be more appropriate to perform the query once, cache the details and then display them from the cache.

try this:
public class CustomerServiceOfficerUI extends javax.swing.JFrame {
private static Statement st;
ResultSet rs;
Connection con = null;
Login loginUI = new Login(); // gets current user Id
Employee cso = new CustomerServiceOfficer(); //creates new customer service officer object
/**
* Creates new form CustomerServiceOfficer
*/
public CustomerServiceOfficerUI() {
initComponents();
}
public void getCSOdetails() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/flyingcarsdb", "root", "");
System.out.println("database connected");
// Retrieve customer service officer details
st = con.createStatement();
String query = "select * FROM customerserviceofficer WHERE Id = '" + loginUI.getCurrentUserId() + "'";
rs = st.executeQuery(query);
while (rs.next()) {
//Assign the details with setters
cso.setFname(rs.getString("Fname"));
cso.setEmail(rs.getString("Email"));
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
loggedInAsLable.setText("you're logged in as : " + cso.getId());
loggedInAsLable.repaint();
}
});
} catch (Throwable ex) {
System.out.println("Error : " + ex);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
loggedInAsLable.setText("There is a problem with your code : " + ex);
loggedInAsLable.repaint();
}
});
} finally {
}
//this is where LABLE is changed, 'cso.getId()' returns the user ID
}

Related

How do I pause my main thread so my JFrame can operate properly

I read a couple questions related to pausing main and both gave answers I didn't understand, and frankly I don't think are applicable.
I have a JFrame that makes use of a database I'm setting up in my driver class.
The JFrame will launch and the window opens; however when I try to make use of the database it fails; because back in main the program just keeps running and shuts down the connection, and closes it.
I tried just removing the connection.close() code just to see if my database methods work in the JFrame, and they do, so I just need to learn how to halt main while my JFrame is running.
public static void main(String[] args) {
File dbPropertiesFile = new File(DbConstants.DB_PROPERTIES_FILENAME);
if (!dbPropertiesFile.exists()) {
showUsage();
System.exit(-1);
}
try {
new Lab9(dbPropertiesFile).run(args);
} catch (Exception e) {
LOG.error(e.getMessage());
e.printStackTrace();
} finally {
shutdown();
}
}
private static void configureLogging() {
ConfigurationSource source;
try {
source = new ConfigurationSource(new FileInputStream(LOG4J_CONFIG_FILENAME));
Configurator.initialize(null, source);
} catch (IOException e) {
System.out.println(
String.format("Can't find the log4j logging configuration file %s.", LOG4J_CONFIG_FILENAME));
}
}
private static void shutdown() {
LOG.info("Shutting down");
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
}
}
private static void showUsage() {
System.err.println(
String.format("Program cannot start because %s cannot be found.", DbConstants.DB_PROPERTIES_FILENAME));
}
private Lab9(File file) throws IOException {
properties = new Properties();
properties.load(new FileInputStream(file));
database = new Database(properties);
}
/**
* Where the computer start making a lot of noise.
*
* #param args
* #throws Exception
*/
private void run(String[] args) throws Exception {
LOG.info("Running");
LOG.info("Loading database properties from: " + DbConstants.DB_PROPERTIES_FILENAME + ".");
LOG.info(properties.getProperty("db.driver"));
LOG.info("Driver loaded");
LOG.info("DB URL = " + properties.getProperty("db.url"));
LOG.info("DB USER = " + properties.getProperty("db.user"));
LOG.info("DB PASSWORD = " + properties.getProperty("db.password"));
connect();
Statement statement = connection.createStatement();
try {
// If the user enters the -drop switch
if (args[0].equalsIgnoreCase(DROP_COMMAND)) {
LOG.info("Table " + CustomerDao.TABLE_NAME + "is being DROPPED!");
customerDao.drop();
LOG.info("Table has been DROPPED!");
}
// Check to see if the table is already made; if its not then make it, and fill
// it.
if (Database.tableExists(CustomerDao.TABLE_NAME) == false) {
createTables(statement);
LOG.info("Created the table: " + CustomerDao.TABLE_NAME + ".");
LOG.info("Inserting Customer objects into table: " + CustomerDao.TABLE_NAME + ".");
insertCustomers();
LOG.info("Inserted customer info into table from file: [" + CUSTOMER_DATA + "].");
}
createUI();
// I NEED MAIN
// TO STOP
// AROUND HERE!
}catch(SQLException e){
e.printStackTrace();
LOG.error(e.getMessage());
}finally{
connection.close();
}
}
public static void createUI() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DatabaseControlFrame frame = new DatabaseControlFrame(customerDao);
frame.setVisible(true);
// OR MAYBE I NEED MAIN
// TO STOP
// AROUND HERE!
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void connect() throws SQLException {
connection = database.getConnection();
customerDao = new CustomerDao(database);
}
}
Any ideas? I tried using a while(frame.isVisilbe()){ wait(600) }; But the compiler had a spas when I tried to use wait().
You'll note I'm passing a customerDAO object to my JFrame constructor; but I'm beginning to wonder could I make a connection inside the JFrame so that when main's connection closes; my JFrame's doesn't? Is that a good idea? Is that even possible I'm not super SQL savvy I'm going to need to study up on it more.
You could use Thread.sleep() - I've found that useful with JFrame before, though I'm not 100% sure it would fit what you're looking for. If you want it to wait indefinitely, put it in a while loop:
while(//condition)
{
Thread.sleep(500); //pauses for .5 sec, then loops back to check condition
}
JFrame event handler runs on a different thread than main thread, so you need to shutdown on that thread.
Here is a example, Using JDBC with GUI API.
This example call connection.close() on received window-closing-event.
public class MyFrame extends JFrame {
public MyFrame() {
// ...
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(final WindowEvent e) {
shutdown();
System.exit(0);
}
});
}
// ...
}

Method never returns when thread join

I'm creating an Android application where I've a login system using MySql. I'm using a Thread for the login.
private static boolean isValid = false;
public static boolean login(final String username, final String password) {
new Thread(new Runnable() {
#Override
public void run() {
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con= DriverManager.getConnection(
"jdbc:mysql://*****/***","*****","******");
Statement stmt=con.createStatement();
String query = "SELECT passHash FROM test WHERE username = '"+ username +"'";
ResultSet rs=stmt.executeQuery(query);
System.out.println(query + " <----");
while(rs.next()) {
isValid = BCrypt.checkpw(password, rs.getString(1));
System.out.println(isValid + "<.daspdfsafpa");
}
System.out.println(isValid +" 1");
con.close();
System.out.println(isValid +" 2");
}
catch(Exception e)
{
System.out.println(e);
}
}
}).start();
try{
Thread.currentThread().join();
}
catch(InterruptedException e){
System.out.println(e.getMessage());
}
System.out.println("blafasf");
return isValid;
}
When I'm using the Thread.currentThread.join(); the app never runs the return isValid;. So my method will never get returned when I'm using the .join() , and if I remove it the method will be returned before the thread is done. How can I fix this issue?
I want the method to run through the thread before returning the isValid in the bottom of the method.
Any ideas?
I'm still looking for a solution on this. How can I make this is another way to still make it work?

How to destroy a frame by clicking on a button?

I want to destroy the frame by clicking on a button. I searched everywhere and it seems that I'm doing this right. but it is not working.
public class LoginWindow {
public void CreateLoginWindow () {
/** Set Style to Main Frame **/
JFrame main_window = new JFrame();
main_window.setUndecorated(true);
main_window.setLocationRelativeTo(null);
main_window.setLayout(new BorderLayout());
main_window.setLayout(new FlowLayout());
main_window.setVisible(false);
main_window.setContentPane(new JLabel(new ImageIcon("images/MainWindow-bg.jpg")));
main_window.setExtendedState(JFrame.MAXIMIZED_BOTH);
main_window.setSize(1920,1080);
main_window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/** Some Codes **/
JButton login_button = new JButton("Click to Exit");
login_button.setBounds(920,480,120,45);
/** Login Button Action **/
login_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ValidateLogin validateLogin = new ValidateLogin();
Boolean valid = validateLogin.ValidateLoginAction(username_field.getText(),password_field.getText());
main_window.dispose();
}
});
main_window.add(login_button);
main_window.setVisible(true);
}
}
It seems ValidateLogin validateLogin = new ValidateLogin(); Boolean valid = validateLogin.ValidateLoginAction(username_field.getText(),password_field.getText()); make some problems.
And this is my ValidateLogin Class :
public class ValidateLogin {
public Boolean ValidateLoginAction (String username, String password){
ConnectToDB validate_login = new ConnectToDB();
String right_password = validate_login.GetPassOfAnUsername(username);
if ( right_password.equals(password) ){
return true;
} else {
return false;
}
}
}
And this is my ConnectToDB Class :
public class ConnectToDB {
/** Connect to Database **/
private Connection connect() {
String url = "jdbc:sqlite:E://Resturant Project/db/Resturant.db";
Connection connection = null;
try {
connection = DriverManager.getConnection(url);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return connection;
}
/** Get Password of an Username **/
public String GetPassOfAnUsername(String username){
String password = "SELECT Password FROM Person WHERE UserName = '" + username +"'";
try (Connection connection = this.connect();
PreparedStatement statement= connection.prepareStatement(password);
ResultSet results = statement.executeQuery()) {
return results.getString("Password");
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return null;
}
}
And this is my MainWindow Class :
public class MainWindow {
public static void main(String[] args) {
LoginWindow loginWindow = new LoginWindow();
loginWindow.CreateLoginWindow();
}
}
I have tried and I am able to close the window and jvm exits also. I provide below the button action code snippet.
login_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
ValidateLogin validateLogin = new ValidateLogin();
Boolean valid = validateLogin.ValidateLoginAction(username_field.getText(),password_field.getText());
}
catch(Exception ex) {
//handle exception
}
finally {
main_window.dispose();
}
}
});
Have the username_field and password_field variables been instantiated somewhere? Perhaps the line where you are accessing the getText() method is throwing a NullPointerException when the actionPerformed method is being called and so the program never reaches the main_window.dispose() line.
Try checking if both of those variables are null when the actionPerformed method is being executed before you try to access the getText() method from them.
On a further note, check if the connection the database is being established successfully.
ConnectToDB validate_login = new ConnectToDB();
String right_password = validate_login.GetPassOfAnUsername(username);
The second line might also throw a NullPointerException in case validate_login is null because your code will return null from your ConnectToDB() constructor in case the connection fails.

My program's Action Listener won't work

It's me again and I just can't seem to get this code to work. I'm basically asking for any advice on why the button does nothing when clicked. Would you like me to attach the source code?
The method I'm trying to implement:
public static void UserInput() {
try {
stmt = connect.createStatement();
ResultSet res = stmt.executeQuery("SELECT * FROM " + tableName);
while (res.next()) {
if (res.getString("Username").equals(usernameField.getText())) {
if (res.getString("Password").equals(passwordField.getPassword())) {
JOptionPane.showMessageDialog(null, "Correct", "Correct",
JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, "Error. Incorrect "
+ "username or password.", "Error",
JOptionPane.ERROR_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(null, "Error. Incorrect "
+ "username or password.", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
res.close();
stmt.close();
connect.close();
} catch (SQLException sqlExcept) {
sqlExcept.printStackTrace();
}
}
And here's how I'm calling it:
if(firstTime == false) {
JavaDB jdb = new JavaDB();
}
JavaDB window = new JavaDB("");
window.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
And here's the actionListner:
submit = new JButton("Submit");
c.add(submit);
submit.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
if(e.getSource().equals(submit)) {
UserInput();
}
}
}); ;
If you need anymore let me know. I've been teaching myself Java and I don't really know what to learn so any tips will be welcomed. I'm also new to stack overflow and posting code so any thing you can give me will be more than appreciated. Thanks in advance.
Edit: I now added a class for event handling with the Thread inside of it like this;
public class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
if(e.getSource().equals(submit)){
Thread th = new Thread(new JavaDB());
th.start();
th.run();
try {
th.wait();
} catch (InterruptedException e1) {
}
}
else{
System.exit(0);
}
}
And I changed UserInput to run(). However,now when I click the submit button,The GUI disappears. Just for a reference you might need, here's my main method:
public static void main(String args[]) throws SQLException,
InterruptedException {
createConnection();
boolean firstTime = firstTime();
if (firstTime) {
JavaDB db = new JavaDB("");
db.createAccount();
try {
connect = DriverManager
.getConnection("jdbc:derby:\\KeithDB;shutdown=true");
} catch (SQLException XJ015) {
}
}
if (firstTime == false) {
JavaDB jdb = new JavaDB();
Thread th = new Thread();
}
JavaDB window = new JavaDB("");
window.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
Anything else you need,let me know
PasswordDemo, as shown in How to Use Password Fields, would be a good starting point for your study, and it would make an effective sscce.
Addendum: Absent a complete example or knowledge of what database you are using, I got the following result,
Version: H2 1.3.157 (2011-06-25) 1.3
by running the following modification to PasswordDemo against H2 Database:
if (isPasswordCorrect(input)) {
try {
Connection conn = DriverManager.getConnection(
"jdbc:h2:mem:", "sa", "secret");
DatabaseMetaData metaData = conn.getMetaData();
System.out.println("Version:"
+ " " + metaData.getDatabaseProductName()
+ " " + metaData.getDatabaseProductVersion()
+ " " + metaData.getDatabaseMajorVersion()
+ "." + metaData.getDatabaseMinorVersion());
} catch (SQLException ex) {
ex.printStackTrace(System.err);
}
} ...
Addendum: I got the following result,
Version: Apache Derby 10.6.2.1 - (999685) 10.6
by running the following modification to PasswordDemo against Apache Derby:
if (isPasswordCorrect(input)) {
try {
EmbeddedDataSource ds = new EmbeddedDataSource();
ds.setDatabaseName("/home/trashgod/.netbeans-derby/dbtest");
Connection conn = ds.getConnection("sa", "secret");
DatabaseMetaData metaData = conn.getMetaData();
System.out.println("Version:"
+ " " + metaData.getDatabaseProductName()
+ " " + metaData.getDatabaseProductVersion()
+ " " + metaData.getDatabaseMajorVersion()
+ "." + metaData.getDatabaseMinorVersion());
} catch (SQLException ex) {
ex.printStackTrace(System.err);
}
} ...
I finally got it to work! I had another constructor with the same variable names and my call to the JTextFields were mistaken to be the call to the other constructor. The foo statements really helped!!! Thank you everyone!

How can I update my JList without running that frame again?

I have a main frame that has a list and "add" button. When I click on the 'add' button, one frame will be shown that I can enter name, family and id.
And by clicking on the "addAPerson", the name will be stored in the SQL. But when I close the frame, the new person will not be added to my list which is in my main frame but if I close the main frame and run it again, the new person will be added to the list.
How can I update the JList without running the main frame?
My main frame (a part of that):
public class ListFrame extends javax.swing.JFrame {
private InformationClass client;
private DefaultListModel model = new DefaultListModel();
/** Creates new form ListFrame. */
public ListFrame(InformationClass client) {
initComponents();
this.client = client;
fillTable();
}
public void fillTable() {
try {
List<InformationClass> list = null;
list = Manager.getClientListFromMySQL();
if (list == null) {
JOptionPane.showMessageDialog(
this,
"You should add a person to your list",
"Information",
JOptionPane.OK_OPTION);
return;
}
else {
for (int i = 0; i < list.size(); i++) {
InformationClass list1 = list.get(i);
model.add(i, list1.getId());
}
jList1.setModel(model);
}
}
catch (SQLException ex) {
Logger.getLogger(
ListFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
My frame which will be shown when you click on the add button (a part of that):
public class Add extends javax.swing.JFrame {
private InformationClass client;
public Add(InformationClass client) {
initComponents();
this.client = client;
}
private void addAPersonActionPerformed(java.awt.event.ActionEvent evt) {
submit();
clear();
}
private void submit() {
String s1 = nameF.getText();
String s2 = familyF.getText();
String s3 = iDf.getText();
if (s1.equals("") || s2.equals("") || s3.equals("")) {
JOptionPane.showMessageDialog(
this,
"fill the empty name/family/id text fields",
"Error",
JOptionPane.ERROR_MESSAGE);
return;
}
else {
try {
boolean b = Manager.isAddPerson(s1, s2, s3);
if (b == false) {
Manager.addPerson(s1, s2, s3);
JOptionPane.showMessageDialog(
this,
"The person has been added successfully",
"Information",
JOptionPane.INFORMATION_MESSAGE);
}
else {
JOptionPane.showMessageDialog(
this,
"These datas has been added before!!",
"Information",
JOptionPane.INFORMATION_MESSAGE);
}
}
catch (NullPointerException e) {
e.printStackTrace();
}
}
}
}
My Manager class (a part of that):
public static void addPerson(String name, String family, String yahooId) {
PreparedStatement pstmt;
String query;
try {
query = ("INSERT INTO newpersontable(name,family,yahooId) VALUES(?,?,?)");
pstmt = (PreparedStatement) conn.prepareStatement(query);
pstmt.setString(1, name);
pstmt.setString(2, family);
pstmt.setString(3, yahooId);
pstmt.executeUpdate();
}
catch (SQLException e) {
Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, e);
}
}
An implementation of the Observer pattern will do the trick.
Your InformationClass calls the Manager to add a person, if it is not already known. But you want that new person appear in the ListFrame. With the Observer pattern, the ListFrame will observe the Manager if it has some added, changed or deleted records. If it is the case, the ListFrame can update itself with the actual values, that it just requests again from the Manager.
We need one additional interface, a Listener and some methods on the Manager, that's all.
Here's a basic implementation:
public interface PersonsModelChangeListener {
public void modelHasChanged();
}
In Manager, add the following fields and methods:
List<PersonsModelChangeListener> listeners = new ArrayList<PersonsModelChangeListener>();
public void addListener(PersonsModelChangeListener listener) {
listeners.add(listener);
}
private void fireModelChangeEvent() {
for (PersonsModelChangeListener listener:listeners) {
listener.modelHasChanged();
}
}
Add the following line to the add method of Manager:
public void add(String s1, String s2, String s3) {
// existing code
fireModelChanged();
}
Next step: make ListFrame implement the PersonsModelChangeListener interface and implement the modelHasChanged method so that ListFrame can 'get' the actual values whenever the Managers data set has changed.
Edit
public class Manager {
// existing code
private static List<PersonsModelChangeListener> listeners = new ArrayList<PersonsModelChangeListener>();
public static void addListener(PersonsModelChangeListener listener) {
listeners.add(listener);
}
private static void fireModelChangeEvent() {
for (PersonsModelChangeListener listener:listeners) {
listener.modelHasChanged();
}
}
public static void addPerson(String name, String family, String yahooId) {
PreparedStatement pstmt;
String query;
try {
query = ("INSERT INTO newpersontable(name,family,yahooId) VALUES(?,?,?)");
pstmt = (PreparedStatement) conn.prepareStatement(query);
pstmt.setString(1, name);
pstmt.setString(2, family);
pstmt.setString(3, yahooId);
pstmt.executeUpdate();
fireModelChangedEvent();
} catch (SQLException e) {
Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, e);
}
}
public class ListFrame extends javax.swing.JFrame implements PersonsModelChangeListener {
// your fields
/** Creates new form ListFrame */
public ListFrame(InformationClass client) {
initComponents();
this.client = client;
fillTable();
Manager.addListener(this);
}
#Override
public void modelHasChanged() {
// this method will be called when you add something with the
// Manager.
// Add your code here to get the actual data from the Manager
// and update this component
}
}
Hope it helps :)
In the submit method save the created person and create a field for it which you can 'get' from the actionPerformed method for the 'add' button in the ListFrame class. Then just add it to the list model.
you just call the update method at the end of your coding.the update method should display the table.So when you add some thing to the list it will get updated in the database. so at the end of your coding it will call the update method which will display the updated table.Hopu u got my point

Categories