Stuck in one place, most likely I do not see the obvious.

There is an application, by pressing the buttons, the panels should change (it works partially). I want to put the buttons on the SOUTH, but they don’t want it (located at the top), and I don’t understand how to make them do it, please look at the code, it’s very simple, tell me the reason.

In fact, for some reason, it turns out that two sweet and my button buttons go right away, sweet is displayed correctly, as I want, and my button is somewhere at the top, and if you click on sweet, nothing happens (and should change panel), and if you click on my button , then sweet also crawls upward, and at the same time the panels change as it should.

enum ViewState { START_STATE, NEXT_STATE; } @SuppressWarnings("serial") class Panel2 extends JPanel { public Panel2() { JPanel panel2 = new JPanel(); panel2.setPreferredSize(new Dimension(1,40)); add(panel2, BorderLayout.SOUTH); panel2.setLayout(new GridLayout()); JButton button = new JButton("sweet"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MyWindowTest.changeState(ViewState.START_STATE); } }); panel2.add(button); this.add(panel2); } } @SuppressWarnings("serial") class Panel1 extends JPanel { public Panel1() { JPanel panel1 = new JPanel(); panel1.setPreferredSize(new Dimension(1,40)); add(panel1, BorderLayout.SOUTH); panel1.setLayout(new GridLayout()); JButton button = new JButton("my button"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MyWindowTest.changeState(ViewState.NEXT_STATE); } }); panel1.add(button); this.add(panel1); } } class MyWindowTest { private static ViewState viewState; private static JPanel mpanel; private static JPanel panel1; private static JPanel panel2; private static JFrame frame; public MyWindowTest() { frame = new JFrame(); mpanel = new JPanel(); panel1 = new Panel1(); panel2 = new Panel2(); frame.setSize(400, 400); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.add(mpanel); frame.add(panel1, BorderLayout.SOUTH); panel1.setLayout(new GridLayout()); frame.add(panel2, BorderLayout.SOUTH); panel2.setLayout(new GridLayout()); changeState(ViewState.START_STATE); frame.setVisible(true); } public static void changeState(ViewState state) { viewState = state; System.out.println("change state: " + viewState); switch (state) { case START_STATE: mpanel.removeAll(); mpanel.add(panel1); mpanel.revalidate(); mpanel.repaint(); break; case NEXT_STATE: mpanel.removeAll(); mpanel.add(panel2); mpanel.revalidate(); mpanel.repaint(); break; default: System.out.println("UNKNOWN STATE!"); break; } } public static void main(String[] args) { @SuppressWarnings("unused") MyWindowTest n = new MyWindowTest(); } } 

If there are suggestions for improving the code, I will be happy to hear.

    1 answer 1

    GridLayout always sorts the components only in the order from being added to the container. You cannot add components to a specific place, if you need to change their position, then you need to add empty components. For example:

     form.add(new JPanel()); form.add(new JPanel()); form.add(new JPanel()); form.add(new JPanel()); 

    Perhaps you can use GridBagLayout, which can do this, but it's a little more difficult to use.

    GridBagLayout supports the preferred size of components and the use of GridBagLayout with GridBagConstraint properties:

    1. gridx, gridy
    2. anchor
    3. weightx, weighty
    4. gridwidth
    5. fill

       import java.awt.*; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.HeadlessException; import java.awt.Insets; import javax.swing.*; import javax.swing.SwingUtilities; /** * * @author Rashed */ class GridBagLayoutDemo extends JFrame{ public JLabel createLabel(String txt, int width, int height, Color color) { JLabel label = new JLabel(txt); label.setOpaque(true); label.setBackground(color); label.setPreferredSize(new Dimension(width, height)); return label; } public GridBagLayoutDemo() throws HeadlessException { setSize(400,400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(new java.awt.GridBagLayout()); GridBagConstraints labCnst = new GridBagConstraints(); labCnst.fill = GridBagConstraints.NONE; labCnst.insets = new Insets(3, 3, 3, 3); labCnst.anchor = GridBagConstraints.FIRST_LINE_START; labCnst.gridx = 0; labCnst.gridy = 0; panel.add(createLabel("play", 100, 30, new Color(0x359DBD)), labCnst); // labCnst.anchor = GridBagConstraints.LAST_LINE_START; labCnst.gridx = 0; labCnst.gridy = 2; panel.add(createLabel("Status: Ready!", 100, 30, new Color(0x359DBD)), labCnst); labCnst.anchor = GridBagConstraints.FIRST_LINE_END; labCnst.gridx = 2; labCnst.gridy = 0; panel.add(createLabel("-0x", 100, 30, new Color(0x359DBD)), labCnst); labCnst.anchor = GridBagConstraints.LAST_LINE_END; labCnst.gridx = 2; labCnst.gridy = 2; panel.add(createLabel("score:30", 100, 30, new Color(0x359DBD)), labCnst); labCnst.anchor = GridBagConstraints.LINE_START; labCnst.fill = GridBagConstraints.VERTICAL; labCnst.gridx = 2; labCnst.gridy = 1; labCnst.gridwidth = 1; labCnst.weightx = 0.7; labCnst.weighty = 0.7; panel.add(createLabel("ScoreList", 100, 200, new Color(0xFFAA00)), labCnst); labCnst.gridx = 0; labCnst.gridy = 1; //labCnst.anchor = GridBagConstraints.LIN; labCnst.gridwidth = 2; labCnst.weightx = 0.8; labCnst.weighty = 0.8; labCnst.fill = GridBagConstraints.BOTH; panel.add(createLabel("It is the center", 200, 200, new Color(0xFFD47E)), labCnst); //labCnst.anchor = GridBagConstraints.LINE_END; add(panel); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new GridBagLayoutDemo().setVisible(true); } }); } } 

    I will not give a complete description, but can be found here: https://stackoverflow.com/questions/19707506/how-to-properly-use-gridlayout-to-position-elements-in-a-jframe

    • I want to clarify on the first point, I need to create a component, and then add a panel with a Button there, and then assign a Layout, right? - Vlad Zherihov
    • @VladZherihov Create a panel, create a Grid, then panel.setlayout (grid), then create a button, then add a button to the panel. Something like this. Then if this panel is part of contentPanel - add it to contentPanel. - Axenow 2:41 pm