Search code examples
javaarraysswingjpaneljbutton

JButton are on JPanel on which it isn't should be


Hi this is my concrete problem. I was tried to add one button to one panel with for loop.

This is for loop for creating JButtons.

nizButtona=new JButton[22];
for(int i=0;i<nizButtona.length;i++){

    nizButtona[i] = new JButton();
    if(i==0){
    nizButtona[i].setText("Započni kviz"); //Start quiz
    nizButtona[i].addActionListener(new ActionListener(){
         @Override 
        public void actionPerformed(ActionEvent e){
            cl.next(nizPanela[1]);
        }
    });
    }else if(i==1){
        nizButtona[i].setText("Izlaz"); //Quit
        nizButtona[i].addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                System.exit(0);
            }
        });
        }else if(i<12){
        nizButtona[i].setText("Sledeće pitanje"); //Next question, on next panel
        nizButtona[i].addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    cl.next(nizPanela[1]);
                }
            });
    }

This is new loop for adding buttons on panels. Here nizButtona[i-1] is i-1 because first button for next question have for 1 argument than JPanel where it's need to be add, and you GridBagLayout for all components so i will put all on the same location for each panel. Without it the problem is the same.

     for(int i=3;i<=11;i++){
        nizPanela[i].add(nizButtona[i-1]);
    }

Here is how i was create array for JPanels.

nizPanela = new JPanel[13];

    for (int i=0;i<nizPanela.length;i++ ){

        nizPanela[i] = new JPanel();

        if(i<=1){
        okvir.getContentPane().add(nizPanela[i]);//Does i real need this getContentPane?
        }else{
            nizPanela[i].setLayout(new GridBagLayout());
            nizPanela[1].add(nizPanela[i], String.valueOf(i));
        }

    }
    cl=new CardLayout();

    nizPanela[1].setLayout(cl); 

    cl.show(nizPanela[1],"2");

This is how program look photo Button Sledeće pitanje visible on this panel but it don't should be. It's only visible if i move mouse pointer through place of this button.


Solution

  • Instead of setLayout(null), learn to use layouts to your advantage. The example below uses a series of nested layouts to add a one grid inside another.

    image

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    
    /**
     * @see https://stackoverflow.com/a/36243395/230513
     */
    public class Test {
    
        private static final int ROW = 2;
        private static final int COL = 5;
    
        private void display() {
            JFrame f = new JFrame("Test");
            f.setLayout(new GridLayout(0, 1));
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel top = new JPanel(new GridBagLayout());
            top.setBackground(Color.darkGray);
            JLabel label = new JLabel("Post no bills.");
            label.setForeground(Color.yellow);
            top.add(label);
            f.add(top);
            f.add(createGridPanel());
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        private JPanel createGridPanel() {
            JPanel p = new JPanel(new GridLayout(ROW, COL, 5, 5));
            p.setBorder(BorderFactory.createLineBorder(Color.yellow,5));
            p.setBackground(Color.yellow);
            for (int r = 0; r < ROW; r++) {
                for (int c = 0; c < COL; c++) {
                    p.add(createSubPanel());
                }
            }
            return p;
        }
    
        private JPanel createSubPanel() {
            JPanel p = new JPanel(new GridLayout(0, 1));
            JPanel top = new JPanel();
            top.add(new JButton("One"));
            top.add(new JButton("Two"));
            JPanel bot = new JPanel();
            bot.add(new JRadioButton("A"));
            bot.add(new JRadioButton("B"));
            bot.add(new JRadioButton("C"));
            bot.add(new JRadioButton("D"));
            p.add(top);
            p.add(bot);
            return p;
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Test()::display);
        }
    }
    

    Addendum: "I want … two JButtons for next and back."

    To permit navigation by button from one panel to another, use CardLayout, shown here and revised below.

    image

    import java.awt.BorderLayout;
    import java.awt.CardLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import javax.swing.AbstractAction;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    
    /**
     * @see https://stackoverflow.com/a/36243395/230513
     */
    public class CardPanel extends JPanel {
    
        private static final JPanel cards = new JPanel(new CardLayout());
        private final String name;
    
        public CardPanel(String name) {
            super(new GridLayout(0, 1));
            this.name = name;
            JPanel top = new JPanel(new GridBagLayout());
            top.setBackground(Color.darkGray);
            JLabel label = new JLabel(name);
            label.setForeground(Color.yellow);
            top.add(label);
            JPanel bot = new JPanel();
            bot.setBorder(BorderFactory.createLineBorder(Color.yellow, 5));
            bot.add(new JRadioButton("A"));
            bot.add(new JRadioButton("B"));
            bot.add(new JRadioButton("C"));
            bot.add(new JRadioButton("D"));
            this.add(top);
            this.add(bot);
        }
    
        @Override
        public String toString() {
            return name;
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    create();
                }
            });
        }
    
        private static void create() {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            for (int i = 1; i < 9; i++) {
                CardPanel p = new CardPanel("Panel " + String.valueOf(i));
                cards.add(p, p.toString());
            }
            JPanel control = new JPanel();
            control.add(new JButton(new AbstractAction("\u22b2Prev") {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    CardLayout cl = (CardLayout) cards.getLayout();
                    cl.previous(cards);
                }
            }));
            control.add(new JButton(new AbstractAction("Next\u22b3") {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    CardLayout cl = (CardLayout) cards.getLayout();
                    cl.next(cards);
                }
            }));
            f.add(cards, BorderLayout.CENTER);
            f.add(control, BorderLayout.SOUTH);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    }