简体   繁体   中英

How can I switch between JPanels in a CardLayout using MVC?

I'm making a Maths Game application and recently began implementing MVC.

I have the following structure:

  • auiAs2

  • auiAs2.view

    • DiffView.java : extends MigJPanel implements ScreenInterface

    • GameView.java: extends MigJPanel implements ScreenInterface

    • EndGameView.java: extends MigJPanel implements ScreenInterface

  • auiAs2.controller

  • auiAs2.model

My MathsGame.java contains a JPanel set to CardLayout which instances of DiffView , GameView , and EndGameView are added to. When I run my program, the diffView 'card' is shown to the user.

If the user clicks "New Game", an ActionListener in DiffControl.java gets the selected difficulty.

public class DiffControl {
    private DiffView diffView;
    private Model model;

    public DiffControl(DiffView diffView, Model model) {
        this.diffView = diffView;
        this.model = model;

        this.diffView.addNewGameListener(new NewGameListener());
    }

    class NewGameListener implements ActionListener {
        String selectedDiff;
        @Override
        public void actionPerformed(ActionEvent e) {
            selectedDiff = diffView.getSelectedDiff();
            //MathsGame.setLayCard(panContainer, "New Game"));
        }
    }
}

This is where I get stuck. Where should I switch between panels in my CardLayout JPanel layCard ? ( MathsGame.java is shown below with irrelevant code removed. The entire code for relevant classes is linked above if required)

public class MathsGame extends JFrame {
    private JPanel panContainer = new JPanel();

    private CardLayout layCard = new CardLayout();

    public MathsGame() {
        panContainer.setLayout(layCard);
        setContentPane(panContainer);
        setSize(new Dimension(WIDTH, HEIGHT));
        setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
        setTitle(TITLE);

        DiffView panDiffView = new DiffView();
        panContainer.add(panDiffView, "Choose Difficulty");

        GameView panGameView = new GameView();
        panContainer.add(panGameView, "New Game");

        EndGameView panEndGameView = new EndGameView();
        panContainer.add(panEndGameView, "End Game");

        Model model = new Model();

        DiffControl diffControl = new DiffControl(panDiffView, model);
        //GameControl gameControl = new GameControl(panGameView, model);
        //EndGameControl EndGameControl = new EndGameControl(panEndGameView, model);

        layCard.show(panContainer, "Choose Difficulty");

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(MathsGame::new);
    }
}

So my question is:

  • Where would be the best place to put code related to switching between Views in my CardLayout container?

The model will have a state field, perhaps an enum, that would reflect the view. You could make this a bound property using a SwingPropertyChangeSupport object. Then the view could listen to the state of this property and swap the Card based on its state. In fact the toString() of each enum constant could be used to add card views to the CardLayout-using container.


Edit
You ask:

Could you elaborate on the usage of SwingPropertyChangeSupport?

You can find examples of this here , here , and especially here .

I've attempted using addPropertyChangeListener in the model. And how would the View control the card change when the CardLayout is in MathsGame.java?

The view would be notified of the state change of the model, and then when this happens, the view would call its code to swap cards.

I've had problems with doing that inside View for "calling a static method from a non-static context".

This is a completely different unrelated issue, a basic core Java issue, that I'm sure with a little work, you'll be able to solve. In brief -- don't try to call instance code in a static way. Always call it on a proper reference, not on the class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM