0

Updated: The thing is that I want my prev button to only work if I have been to that one before. For instance, if I logged in and click next, I should be able to go back one step. But not two.

public class MainFrame {

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Dimensions helper");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        final JPanel contentPane = new JPanel();
        contentPane.setLayout(new CardLayout(200, 200));

        Window1 win1 = new Window1();
        contentPane.add(win1);
        Window2 win2 = new Window2();
        contentPane.add(win2);
        Window3 win3 = new Window3();
        contentPane.add(win3);

        JPanel buttonPanel = new JPanel(); 
        final JButton previousButton = new JButton("< PREVIOUS");
        final JButton nextButton = new JButton("NEXT >");
        final JButton cancelButton = new JButton("CANCEL");
        buttonPanel.add(cancelButton);
        buttonPanel.add(previousButton);
        buttonPanel.add(nextButton);

        previousButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                Verifiable verifiable = null;
                Component[] contents = contentPane.getComponents();
                for(Component component : contents) {
                    if(component.isVisible() && component instanceof Verifiable) {
                        verifiable = (Verifiable)component;
                    }
                }
                if(verifiable != null && verifiable.isDataValid()) {
                    CardLayout cardLayout = (CardLayout) contentPane.getLayout();
                    cardLayout.previous(contentPane);
                }
            }
        });

        nextButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                Verifiable verifiable = null;
                Component[] contents = contentPane.getComponents();
                for(Component component : contents) {
                    if(component.isVisible() && component instanceof Verifiable) {
                        verifiable = (Verifiable)component;
                    }
                }
                if(verifiable != null && verifiable.isDataValid()) {
                    CardLayout cardLayout = (CardLayout) contentPane.getLayout();
                    cardLayout.next(contentPane); 
                }
            }
        });

        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                System.exit(0);
            }

        });

        frame.add(contentPane);
        frame.add(buttonPanel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    } }

Window1.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;

public class Window1 extends JPanel implements Verifiable {

    JTextField txtUsername = new JTextField();
    JPasswordField txtPassword = new JPasswordField();

    public Window1() {
        init();
    }

    private void init() {
        setLayout(new GridLayout(2, 2));
        JLabel lblUsername = new JLabel("Username:", JLabel.CENTER);
        txtUsername = new JTextField();

        JLabel lblPassword = new JLabel("Password:", JLabel.CENTER);
        txtPassword = new JPasswordField();

        add(lblUsername);
        add(txtUsername);
        add(lblPassword);
        add(txtPassword);
        String title = "Log in";
        setBorder(BorderFactory.createTitledBorder(title));
    }

    @Override
    public boolean isDataValid() {
        if(txtUsername.getText().equals("foo") &&
                java.util.Arrays.equals(txtPassword.getPassword(), "bar".toCharArray())) {
            return true;
        } else {
            JOptionPane.showMessageDialog(this, "Fel användarnamn och/eller lösenord", 
                    "Error", JOptionPane.ERROR_MESSAGE);
            return false;
        }
    }
}
  • 1
    Why not just have the button's ActionListener first test if the data being displayed is valid and not call next() on the CardLayout if this is false? – Hovercraft Full Of Eels Mar 11 '12 at 19:27
  • Hey. Thanks for the reply. Could you be a little bit more precise how you mean? I'm sorry I I'm asking dumb questions, but I'm new at GUI programming. –  Mar 11 '12 at 19:34
  • possible duplicate of [Implementing back/forward buttons in Swing](http://stackoverflow.com/questions/5654926/implementing-back-forward-buttons-in-swing) – trashgod Mar 11 '12 at 19:40

1 Answers1

1

For example, create an interface, Verifiable, with a boolean method, isDataValid():

interface Verifiable {
   boolean isDataValid();
}

and have your panel classes implement the interface so that each panel can validate its own data.

class Window1 extends JPanel implements Verifiable {

   JTextField txtUsername = new JTextField();
   JPasswordField txtPassword = new JPasswordField();

   public Window1() {
      init();
   }

   private void init() {

      setLayout(new GridLayout(2, 2));
      JLabel lblUsername = new JLabel("Username:", JLabel.CENTER);

      JLabel lblPassword = new JLabel("Password:", JLabel.CENTER);

      add(lblUsername);
      add(txtUsername);
      add(lblPassword);
      add(txtPassword);
      String title = "Use \"foo\" and \"bar\"";
      setBorder(BorderFactory.createTitledBorder(title ));
   }

   @Override
   public boolean isDataValid() {
      return txtUsername.getText().equals("foo") && 
            java.util.Arrays.equals(txtPassword.getPassword(), "bar".toCharArray());
   }
}

Then check that the current displayed panel's data is valid in next and previous JButton's ActionListener.

  nextButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ae) {
        Verifiable verifiable = null;
        Component[] contents = contentPane.getComponents();
        for (Component component : contents) {
           if (component.isVisible() && component instanceof Verifiable) {
              verifiable = (Verifiable) component;
           }
        }
        if (verifiable != null && verifiable.isDataValid()) {
           CardLayout cardLayout = (CardLayout) contentPane.getLayout();
           cardLayout.next(contentPane);
        }

     }
  });
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Ok. Thank you again. I have implemented the abstract class Verifiable with the isDataValid() method and also overriden it in each of the panel classes. However, I don't understand how I am supposed to use it through the JButton's ActionListener. –  Mar 11 '12 at 19:55
  • You shouldn't use an abstract class as this is too confining, but rather an interface. What about the code above is confusing? – Hovercraft Full Of Eels Mar 11 '12 at 19:56
  • Oh, it appears my web browser only showed me your original answer, not the one containing code. Thank you once again! –  Mar 11 '12 at 20:07
  • Still not sure how I'd implement the prev button though. When I click next and the input doesn't verify, I've added a MessageDialog telling the user that there's something wrong with his input. However, I don't want that error when I click the prev button. –  Mar 11 '12 at 21:19
  • @Tobias: then don't put it in the previous button's ActionListener. If you're still stuck, then you should give more specifics on exactly where you're stuck including your latest code for the previous button's ActionListener. This should be as an edit to your original question since code doesn't format well in comments. Just notify me with a comment that you've made changes. – Hovercraft Full Of Eels Mar 11 '12 at 21:25
  • I updated the code and specified more what I'm after. Thank you. –  Mar 11 '12 at 22:00
  • Just wanted to update that I solved the problem using an identifier I got from each class using an additional overriden method in the Interface, so no more help needed. Thanks once again. –  Mar 13 '12 at 16:07