1


What I don't like about my code below is:

  1. getters are needed for every JButton on each page
  2. the actionPerformed method can quickly become bloated with if-else statements

So, is there a better way to control all GUI actions from a single class?

If I define an actionPerformed method within each respective page (JPanel), each page will need access to instances of the page(s) switched to, and I am trying to avoid using the Singleton pattern for each page...


Here is the code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 
 * @author Ian A. Campbell
 *
 */
public class Controller implements ActionListener {

    /**
     * instance variables:
     */
    private Frame frame;
    private OptionPage firstPage;
    private FirstOptionPage firstOption;
    private SecondOptionPage secondOption;

    /**
     * 
     */
    public Controller() {

        // instantiating the frame here:
        this.frame = new Frame();

        /*
         *  instantiating all pages here:
         *  
         *  NOTE: passing "this" because this class
         *  handles the events from these pages
         */
        this.firstPage = new OptionPage(this);
        this.firstOption = new FirstOptionPage(this);
        this.secondOption = new SecondOptionPage(this);
    }

    /**
     * 
     */
    public void start() {
        this.frame.add(this.firstPage); // adding the first page

        // NOTE: these lines prevent blank loading and flickering pages!
        this.frame.validate();
        this.frame.repaint();
        this.frame.setVisible(true);
    }

    /**
     * 
     * @return the JFrame instantiated from the class Frame
     */
    public Frame getFrame() {
        return this.frame;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        // the "first option" button from the OptionPage:
        if (e.getSource() == this.firstPage.getFirstButton()) {
            this.frame.getContentPane().removeAll();
            this.frame.getContentPane().add(this.firstOption);

        // the "second option" button from the OptionPage:
        } else if (e.getSource() == this.firstPage.getSecondButton()) {
            this.frame.getContentPane().removeAll();
            this.frame.getContentPane().add(this.secondOption);
        }

        // NOTE: these lines prevent blank loading and flickering pages!
        this.frame.validate();
        this.frame.repaint();
        this.frame.setVisible(true);
    }
} // end of Controller
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Ian Campbell
  • 2,678
  • 10
  • 56
  • 104
  • 1
    What you're trying to build is called a wizard. Perhaps this will help. http://www.oracle.com/technetwork/articles/javase/wizard-136789.html – Gilbert Le Blanc May 21 '13 at 06:58

2 Answers2

2

Use a Card Layout. Card Layout Actions adds some extra features that you might find helpful.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thanks @camickr. `CardLayout`seems confusing to distinguish hierarchies of page navigation... For example -- if there are two buttons on a page that go to different pages, and if each page has buttons that go to different pages, is it easy to use `CardLayout` methods like `next()` and `previous()`? Should each "branch" of page navigation have a different `CardLayout`? – Ian Campbell May 21 '13 at 04:08
  • 1
    The Next/Previous buttons are for simple navigation and should not be used in your situation. However, the CardLayout is still the best way to manage your requirement. You will need to add individual button to each panel to specify which panel should be displayed when the button is clicked. The CardLayout will manage the swapping of the current panel with the specified panel. – camickr May 21 '13 at 05:02
  • Thanks @camickr, the `RXCardLayout` is interesting... I want to implement this from scratch though, for practice. So, I now have a `CardLayout` in my `Controller` class. In using the `MVC` design-pattern approach, should the `CardLayout` be placed in the model, view, or controller? If I put it in the controller, it seems that I have to include the entire view into the controller... – Ian Campbell May 25 '13 at 04:23
1

You could use card layout, or you could get creative and remove elements. For instance:

panel.remove((JButton)myButton1)); // Remove all of the elements...
panel.add((JButton)myButton2)); // Add the new elements

Of course I wouldn't deal with the java built in GUI at all, IMO the layout designs are horrific. I would much rather use something like "A New Look and Feel" -- http://www.javootoo.com/.

Ian Campbell
  • 2,678
  • 10
  • 56
  • 104
Dillon Burton
  • 363
  • 6
  • 16