Question

The next function of my cardlayout is working properly, but previous isnt. As far as I'm concerned, just having "layout.previous(_);" in the actionPerformed method body in my makePanel() method should work, but when I run my program and click the prev button, nothing happens. What am I doing wrong? –

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


public class Temp
{
    public static void main (String[] args)
    {
        new MakeAQuiz();
    }

    static class MakeAQuiz 
{

    private JPanel start, base, fields, buttonz, question;
    private String [] labels = {"Enter your question: ", "Answer 1: ", "Answer 2: ", "Answer 3: ", "Answer 4: "};
    private JButton [] buttons = {new JButton("<<Go back"), new JButton("I'm done"), new JButton("Next>>")};
    private JFrame makeFrame;

    public MakeAQuiz()
    {
        start = new JPanel(new CardLayout());
        start.add(makePanel(),"1");

        makeFrame = new JFrame();
        makeFrame.setSize(500,600);
        makeFrame.add(start);
        makeFrame.setVisible(true);
        makeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    }

    public JFrame getJFrame()
    {
        return makeFrame;
    }

    public JPanel makePanel()
    {
        question = new JPanel(new FlowLayout());
        fields = new JPanel(new GridBagLayout());
        buttonz = new JPanel(new FlowLayout());
        base = new JPanel(new BorderLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.weighty=0.5; //adds padding between the fields vertically

        for (int i = 1; i<5; i++)
        {
            c.gridy++; //puts each field in a seperate line/row
            JLabel label = new JLabel(labels[i]);
//            c.fill = GridBagConstraints.HORIZONTAL;
            fields.add(label,c);
            JTextField textField = new JTextField(20);
            fields.add(textField,c); 
        }


        final CardLayout layout = (CardLayout)start.getLayout();    

        buttons[1].addActionListener(new ActionListener() {
//            @Override
            public void actionPerformed(ActionEvent e) {
                buttons[0].setEnabled(false);
                buttons[2].setEnabled(false);
//                for(Component comp : cardPanel.getComponents()) {
//                    if(comp instanceof Page) {
//                        Page page = (Page)comp;
//                        page.printData();
//                    }
//                }
            }
        });

        buttons[2].addActionListener(new ActionListener() 
        {
//        @Override
            public void actionPerformed(ActionEvent e) 
            {
                start.add(makePanel(), String.valueOf(start.getComponentCount() + 1));              
                layout.next(start);
            }
        });

        buttons[0].addActionListener(new ActionListener() 
        {
            @Override
            public void actionPerformed(ActionEvent e) 
            {           
                layout.previous(start);
            }
        });

        buttonz.add(buttons[0]);    
        buttonz.add(buttons[1]);
        buttonz.add(buttons[2]);   

        JLabel l = new JLabel(labels[0]);
        JTextField t = new JTextField(30);
        question.add(l);
        question.add(t);

        base.add(question,BorderLayout.NORTH);
        base.add(buttonz,BorderLayout.SOUTH);
        base.add(fields,BorderLayout.CENTER);

        return base;
    }

}
}
Was it helpful?

Solution

I have no issue (with your code), once I added some additional components to the start panel.

You will, however, have issues because you've added the buttons to the panel been displayed in the CardLayout.

A better solution would be to put the buttons at the bottom of the main screen and separate it from the cards.

You would need to maintain some kind of counter or reference to the current page, as CardLayout doesn't provide any way to obtain a reference to the current card. This would allow you to enabled/disable the next/previous buttons approritaly...

Updated with runnable example...

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MakeAQuiz {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                new MakeAQuiz();
            }
        });
    }

    private JPanel start, base, fields, buttonz, question;
    private String[] labels = {"Enter your question: ", "Answer 1: ", "Answer 2: ", "Answer 3: ", "Answer 4: "};
    private JButton[] buttons = {new JButton("<<Go back"), new JButton("I'm done"), new JButton("Next>>")};
    private JFrame makeFrame;

    public MakeAQuiz() {
        start = new JPanel(new CardLayout());
        start.add(makePanel(), "1");

        makeFrame = new JFrame();
        makeFrame.add(start);

        buttonz = new JPanel(new FlowLayout());

        final CardLayout layout = (CardLayout) start.getLayout();

        buttons[1].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                buttons[0].setEnabled(false);
                buttons[2].setEnabled(false);
            }
        });

        buttons[2].addActionListener(new ActionListener() {
      @Override
            public void actionPerformed(ActionEvent e) {
                int count = start.getComponentCount();
                start.add(new JLabel(Integer.toString(count), JLabel.CENTER), Integer.toString(count));
                layout.next(start);
            }
        });

        buttons[0].addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                layout.previous(start);
            }
        });

        buttonz.add(buttons[0]);
        buttonz.add(buttons[1]);
        buttonz.add(buttons[2]);

        makeFrame.add(buttonz, BorderLayout.SOUTH);

        makeFrame.pack();
        makeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        makeFrame.setVisible(true);
    }

    public JFrame getJFrame() {
        return makeFrame;
    }

    public JPanel makePanel() {
        question = new JPanel(new FlowLayout());
        fields = new JPanel(new GridBagLayout());
        base = new JPanel(new BorderLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.weighty = 0.5; //adds padding between the fields vertically

        for (int i = 1; i < 5; i++) {
            c.gridy++; //puts each field in a seperate line/row
            JLabel label = new JLabel(labels[i]);
//            c.fill = GridBagConstraints.HORIZONTAL;
            fields.add(label, c);
            JTextField textField = new JTextField(20);
            fields.add(textField, c);
        }

        JLabel l = new JLabel(labels[0]);
        JTextField t = new JTextField(30);
        question.add(l);
        question.add(t);

        base.add(question, BorderLayout.NORTH);
        base.add(fields, BorderLayout.CENTER);

        return base;
    }

}

OTHER TIPS

No. I think its not gonna work that way. Simply clicking the previous button will not bring anything back. You should save your entries somewhere else and load them to corresponding fields when clicking on the previous button.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top