2

Good day all, first of all, what am trying to do is have an animation run in between the time the user presses the OK button in an input dialog and the response from a database that he has successfully logged in.

I have a class that takes care of setting up the UI and animation and have a seperate classes for the login dialog and database respectively. I have tried using booleans to make the animation, but it just gets stuck and would only animate after i dismiss the dialog. How do i set this up correctly. here is what i tried and the relevant codes in both class. Thank you

for Login dialog, loginInput.class:

   class LoginInput extends JDialog {
    private JPanel myPanel;
    private JPanel buttons_panel;
    private JTextField username;
    private JPasswordField password;
    private JLabel username_label;
    private JLabel password_label;
    private JButton ok;
    private JButton cancel;
    protected static boolean succeeded;


    public LoginInput(JFrame parent){
        super(parent,"Login", true);
        initUI(parent);

    }

    private void initUI(JFrame parent) {

       myPanel = new JPanel(new GridLayout(3,2,1,1));
       buttons_panel = new JPanel(new FlowLayout());

       username_label = new JLabel("Username: ");
       password_label = new JLabel("Password: ");
       username = new JTextField(20);
       password = new JPasswordField(20);

       ok = new JButton("Ok");
       ok.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

               LoginDB db = new LoginDB(getUsername(), getPassword());

               try {
                    db.createConn();
                    db.execute();

                } catch (SQLException ex) {
                    Logger.getLogger(LoginInput.class.getName()).log(Level.SEVERE, null, ex);
                }

               /*check if login input is correct and display information dialog accordingly*/
              // try {
                 // if (db.checkUserInput(getUsername(), getPassword())){
                   if(isSucceeded() == true ){
                      JOptionPane.showMessageDialog(LoginInput.this, "Hi" + getUsername()+ "! " +
                              "You have successfully Logged in", "XLite", JOptionPane.INFORMATION_MESSAGE);
                      succeeded = true;
                      dispose();

                  }else{

                      JOptionPane.showMessageDialog(LoginInput.this,"Invalid username or password","Login",JOptionPane.ERROR_MESSAGE);
                    // reset username and password
                    username.setText("");
                    password.setText("");
                    succeeded = false;
                  }
               // } catch (SQLException ex) {
                    //Logger.getLogger(LoginInput.class.getName()).log(Level.SEVERE, null, ex);
                //}
               }               
        });

        cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
               dispose();
            }
        });

        myPanel.add(username_label);
        myPanel.add(username);
        myPanel.add(password_label);
        myPanel.add(password);

        buttons_panel.add(ok);
        buttons_panel.add(cancel);

        getContentPane().add(myPanel, BorderLayout.CENTER);
        getContentPane().add(buttons_panel, BorderLayout.PAGE_END);

        pack();
        setResizable(false);
        setLocationRelativeTo(parent);
    }


    /*return the username from the textbox*/
    public String getUsername(){
        return username.getText().trim();
    }

    /*return the password from the textbox*/
    public String getPassword(){
        return new String(password.getPassword());
    }

    /*return login status*/
     public boolean isSucceeded() {
        return succeeded;
    }
}

and for the main class:

  public myTest() {
        initComponents();
        String image_name = "/my/myTest/resource/Envelope.jpg";
        Image = new ImageIcon(this.getClass().getResource(image_name));
        currentImage = Image.getImage();
        prepareImage(currentImage, this);
        envelope.setX(xpos); //envelope is a class with getters and setters for x and y positions
        envelope.setY(ypos);
        timer = new Timer(150, this);
        //timer.start();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        loginClient();  //method to call the login dialog class
        /*if (login_page.animate == true) {
            timer.start();
        } */



    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new myTest().setVisible(true);
            }
        });
    }

    private void loginClient() {
        login_page = new LoginInput(this);  // login dialog class
        login_page.setSize(220, 150);
        login_page.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        Dimension d = jPanel1.getSize();
        envelope.setX(envelope.getX() + xmove);
        envelope.setY(envelope.getY() + ymove);
        if (envelope.getX() > d.getWidth() - imageWidth) {
            xmove *= -0.1;
        }
        if (xpos < 1) {
            xmove *= -1;
        }
        if (envelope.getY() <= d.getHeight() - imageHeight) {
            ymove *= -1;
        }
        repaint();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(currentImage, envelope.getX(), envelope.getY(), this);
        g.dispose();
    }

for loginDB class:

public class LoginDB extends SwingWorker<Object, Object> {
 public Connection conn;
  String driver;
  String URL;
 //username and password to check database
  String username;
  String password;

  //remporary user name and password to hold data
  String user;
  String pwd;

  myTest testview = new myTest();
  Timer timer;
boolean result = false;


  public LoginDB(String username, String password){
       this.user = username;
       this.pwd = password;


  }


    /*create a database connection object with the connection driver Manager*/
    public void createConn() throws SQLException{
        String filename = "C:/PROJECTS/com/me/login_client/LoginDB";
            driver = "sun.jdbc.odbc.JdbcOdbcDriver";
           //URL = "jdbc:odbc:XliteLoginDB";
           URL = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)}; DBQ=";
           URL += filename.trim() + ";DriverID=22;READONLY=true}";
            username = "";
            password = "";

        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(URL, username, password);

        } catch (ClassNotFoundException ex) {
            Logger.getLogger(LoginDB.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public boolean checkUserInput(String username, String password) throws SQLException{
        boolean result;

        Statement query = conn.createStatement();
        ResultSet rs = query.executeQuery("SELECT Username, Password FROM XliteLogin where " +
                "Username='" + username + "'AND Password='" + password +"'");

            //ResultSet rs = query.executeQuery("SELECT FROM XliteLogin where " +
               // "Username='" + username + "'AND Password= '" + password +"'");
        if(rs.next()){
            result = true;
        }else{
            result =false;
        }
        query.close();
        conn.close();

        return result;
    }

    @Override
    protected Object doInBackground() throws Exception {

          publish(checkUserInput(user,pwd));
          return checkUserInput(user,pwd);
    }


    //@Override
        protected void process(boolean chunks) {               
           testview.timer.start();
        }


    @Override
        protected void done(){

          testview.timer.start();
        }


}

EDIT: can't seem to start the timer from the SwingWorker class or any other class outside the main.

irobotxx
  • 5,963
  • 11
  • 62
  • 91
  • 1
    Please Learn Java Naming Conventions, and follow them strictly :-) . Seems like the connection to your database must be done with the help of [SwingWorker](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) , do override [paintComponent(...)](http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)), instead of `paint(...)` – nIcE cOw Mar 27 '12 at 16:35
  • @GagandeepBali, sorry about that.. just wasn't looking at that. – irobotxx Mar 27 '12 at 16:52

1 Answers1

4

You're blocking the event dispatch thread. Instead, access the database from a SwingWorker in doInBackground() and synchronize the animation in process(), as shown in this example.

Addendum: Regarding animation, the example's process() implementation appends newly published data to a JTextArea, but the background thread may also generate animation events by invoking setProgress(). Because listeners are notified on the EDT, any component may be updated, not just a JProgressBar.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • +1, all is good in the answer. You just missed `paintComponent(...)` part, hehe :-) – nIcE cOw Mar 27 '12 at 16:37
  • @GagandeepBali: Good catch; I always welcome your critical review. The poster may be extending `JFrame`; but as you comment above, "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[Painting in AWT and Swing: The Paint Methods](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#callbacks). – trashgod Mar 27 '12 at 16:48
  • @trashgod, thanks for the post.. sorry i was out. yeah i am extending jFrame. is there any good reason for using paintComponent() over paint() becausei sometimes hear this in forum. – irobotxx Mar 27 '12 at 19:38
  • @sparrow: It looks like the article is being updated, but it's dispositive. You rarely want to change how the frame is painted; more frequently, you want to change how a (lightweight) component is painted. – trashgod Mar 27 '12 at 19:50
  • @trashgod : oh thats what it means. thanks for clearing that up. From the example you gave, you are saying i can start the animation in the process() before i call the publish() in doInBackground(), am i correct on this?.. – irobotxx Mar 27 '12 at 23:36
  • @sparrow: You would start the _query_ in `doInBackground()`, which would `publish()` interim results that `process()` receives and uses to update the GUI. – trashgod Mar 28 '12 at 00:46
  • @trashgod, sorry to bother but i did not want to start a new post. for some reason, its not animating when i try to start the timer from any other class apart from the main class. I know its working because i set print outs in the actionperformed() and they are calling, but there is no animation. it seems the jPanel is not be recognised at that time. in other words, if i start the timer before the login(), all is fine but if i start it after the login() method has been called, no animation happens.. by the way, the login calls a database class where the swing worker is used as you suggested. – irobotxx Mar 29 '12 at 12:32
  • @trashgod, i have added the full set of code so you see what am trying to say. Thanks for taking the time to help out. – irobotxx Mar 29 '12 at 13:03
  • I can't run your example, but I'm suspicious of overriding `paint()`, instead of `paintComponent()`. You could try drawing your envelope in a custom [`ProgressBarUI`](http://stackoverflow.com/a/8886795/230513). – trashgod Mar 29 '12 at 16:50
  • @trashgod, sorry was busy. just wondering, can it also be that setting the image Observer to "this" instead of null in the drawImage() method can be causing this. Anyways,Thanks for the update of your answer. really Appreciate all the help you have given. – irobotxx Mar 29 '12 at 23:44
  • Only if the `Observer` blocks the EDT. Does `myTest` extend `JFrame`? Class names usually start with upper case. – trashgod Mar 29 '12 at 23:49