Попытка заставить свинг-меню работать с GridBagLayout - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь создать приложение с двумя вертикальными столбцами, закрепленными на левой стороне, и одна большая коробка справа. Я могу получить первое меню, чтобы придерживаться справа, но по какой-то причине второе меню не появится рядом с первым меню. Я прочитал кое-что о дополнительном пространстве, помещаемом к последнему столбцу и последнему ряду (справа). Как я должен справиться с этим?

P.S. Я использую сетку для сумок.

Вот что у меня есть:

Основной класс UserView: пакет gui;

import actions.DepositAddButtonAction;
import actions.DepositButtonAction;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;

public class UserView {
    public JFrame frame;
    private JPanel menuPanel;
    private JPanel secondMenuPanel;
    private JPanel contentPanel;
    private JButton depositButton;
    private JButton creditButton;
    private JButton exchangeButton;
    private JButton simulationButton;
    private JButton informationButton;
    private JLabel menuLabel;
    private GridBagLayout gridBagLayout;
    private GridBagConstraints constraints;
    private Border border;

    public UserView() {
        frame = new JFrame("E-Banking");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        menuPanel = new JPanel();
        secondMenuPanel = new JPanel();
        contentPanel = new JPanel();
        depositButton = new JButton("Deposit: ", new ImageIcon(UserView.class.getResource("/money_box_icon.png")));
        creditButton = new JButton("Credit: ", new ImageIcon(UserView.class.getResource("/credit_icon.png")));
        exchangeButton = new JButton("Exchange: ", new ImageIcon(UserView.class.getResource("/exchange_icon.png")));
        simulationButton = new JButton("Simulation: ", new ImageIcon(UserView.class.getResource("/simulation_icon.png")));
        informationButton = new JButton("Information: ", new ImageIcon(UserView.class.getResource("/info_icon.png")));
        menuLabel = new JLabel(new ImageIcon(UserView.class.getResource("/bank_icon.png")), SwingConstants.LEFT);
        gridBagLayout = new GridBagLayout();
        constraints = new GridBagConstraints();
        border = BorderFactory.createLineBorder(new Color(102, 102, 153), 1, true);
        frame.setSize(800, 600);
        applyButtonStyles();
        initialize();
    }

    private void applyButtonStyles() {
        depositButton.setHorizontalTextPosition(SwingConstants.RIGHT);
        creditButton.setHorizontalTextPosition(SwingConstants.RIGHT);
        exchangeButton.setHorizontalTextPosition(SwingConstants.RIGHT);
        simulationButton.setHorizontalTextPosition(SwingConstants.RIGHT);
        informationButton.setHorizontalTextPosition(SwingConstants.RIGHT);
        menuLabel.setHorizontalAlignment(SwingConstants.RIGHT);

        menuPanel.setBorder(border);
        secondMenuPanel.setBorder(border);
        secondMenuPanel.setVisible(false);
        contentPanel.setBorder(border);
        contentPanel.setVisible(false);

    }

    private void initialize() {
        menuLabel.setText("E-Banking");

        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.anchor = GridBagConstraints.FIRST_LINE_START;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(4, 4, 4, 4);
        menuPanel.setLayout(gridBagLayout);

        menuPanel.add(menuLabel);
        constraints.gridy++;
        menuPanel.add(depositButton, constraints);
        constraints.gridy++;
        menuPanel.add(creditButton, constraints);
        constraints.gridy++;
        menuPanel.add(exchangeButton, constraints);
        constraints.gridy++;
        menuPanel.add(simulationButton, constraints);
        constraints.gridy++;
        menuPanel.add(informationButton, constraints);

        constraints.gridx = 1;
        constraints.gridy = 0;

        frame.getContentPane().setLayout(gridBagLayout);
        constraints.gridx = 0;
        constraints.gridy = 0;

        constraints.weightx = 0.4;
        constraints.weighty = 0.4;
        constraints.fill = GridBagConstraints.NONE;
        frame.getContentPane().add(menuPanel, constraints);
        constraints.gridx++;

        frame.getContentPane().add(secondMenuPanel, constraints);
        constraints.gridx++;

        frame.getContentPane().add(contentPanel, constraints);
        constraints.gridx++;

        DepositAddButtonAction depositAddButtonAction = new DepositAddButtonAction(contentPanel);
        DepositButtonAction depositButtonAction = new DepositButtonAction(secondMenuPanel, contentPanel, depositAddButtonAction, null, null);
        depositButton.addActionListener(depositButtonAction);


        }

}

Другой класс, который представляет поведение первой кнопки:

package actions;

import gui.UserView;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class DepositButtonAction implements ActionListener {
    private JPanel secondMenuPanel;
    private JPanel contentPanel;
    private JButton addButton;
    private JButton queryButton;
    private JLabel operationLabel;
    private GridBagLayout gridBagLayout;
    private GridBagConstraints constraints;

    public DepositButtonAction(JPanel secondMenuPanel, JPanel contentPanel, ActionListener otherDepositAddButtonAction,
                               ActionListener otherDepositRemoveButtonAction, ActionListener otherDepositQueryButtonAction) {

        this.secondMenuPanel = secondMenuPanel;
        secondMenuPanel.setVisible(false);
        this.contentPanel = contentPanel;
        addButton = new JButton("Request", new ImageIcon(UserView.class.getResource("/add_icon.png")));
        queryButton = new JButton("Query", new ImageIcon(UserView.class.getResource("/info_icon.png")));
        operationLabel = new JLabel(new ImageIcon(UserView.class.getResource("/options_icon.png")));
        operationLabel.setText("Options ");
        gridBagLayout = new GridBagLayout();
        constraints = new GridBagConstraints();
        applyStyles();
        addButton.addActionListener(otherDepositAddButtonAction);
//        removeButton.addActionListener(otherDepositRemoveButtonAction);
//        queryButton.addActionListener(otherDepositQueryButtonAction);
    }

    private void applyStyles() {
        secondMenuPanel.setLayout(gridBagLayout);
        addButton.setHorizontalTextPosition(SwingConstants.RIGHT);
        queryButton.setHorizontalTextPosition(SwingConstants.RIGHT);
    }

    private void initialize() {
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.anchor = GridBagConstraints.FIRST_LINE_START;
        constraints.fill = GridBagConstraints.BOTH;


        constraints.insets = new Insets(4, 4, 4, 4);
        secondMenuPanel.add(operationLabel, constraints);
        constraints.gridy++;

        secondMenuPanel.add(addButton, constraints);
        constraints.gridy++;

        secondMenuPanel.add(queryButton, constraints);

    }


    @Override
    public void actionPerformed(ActionEvent arg0) {
        secondMenuPanel.setVisible(true);
        contentPanel.setVisible(false);
        secondMenuPanel.removeAll();
        contentPanel.removeAll();
        contentPanel.revalidate();
        contentPanel.repaint();
        initialize();
        secondMenuPanel.revalidate();
        secondMenuPanel.repaint();
    }

}

Что я пытаюсь получить: enter image description here

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

Я пробовал это с двумя вертикальными Box es (макет) для кнопок в JPanel (панель кнопок) с GridLayout из двух столбцов и одной строки. Эта панель кнопок расположена слева (BorderLayout.WEST) от JFrame.

Пример кода:

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

public class TestingLayout {

    public static void main(String[] args) {
        gui();
    }

    private static void gui() {
        JFrame frame = new JFrame();
        frame.setTitle("JButtons Layout");

        JPanel pane = new JPanel();
        pane.setLayout(new GridLayout(1, 2));
        pane.add(getLeftButtons());
        pane.add(getRightButtons());

        frame.add(pane, BorderLayout.WEST);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setSize(800, 500);        
        frame.setVisible(true);
    }

    private static Box getLeftButtons() {
        Box box = Box.createVerticalBox();
        box.add(new JButton("b1"));
        box.add(new JButton("b2"));
        box.add(new JButton("b3"));
        box.add(new JButton("b4"));
        box.add(new JButton("b5"));
        return box;
    }

    private static Box getRightButtons() {
        Box box = Box.createVerticalBox();
        box.add(new JButton("b11"));
        box.add(new JButton("b12"));
        box.add(new JButton("b13"));
        return box;
    }
}


Пример вывода:

enter image description here

0 голосов
/ 30 августа 2018

Помните, вы не ограничены использованием одного менеджера компоновки. Вы можете комбинировать менеджеры компоновки, используя несколько контейнеров, что позволяет вам сосредоточиться на индивидуальных потребностях каждого контейнера и дополнительно изолировать функциональность и уменьшить сложность накладывающихся требований макета.

Вы также должны взглянуть на Как использовать CardLayout , который предоставит вам средства для переключения между различными представлениями.

С этой целью я пошел немного другим путем, я начал с концепции "контейнера меню", который может содержать "подменю"

public class MenuPane extends JPanel {

    public MenuPane() {
        setLayout(new GridBagLayout());
    }

    public void addSubMenuPane(SubMenuPane pane) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.NORTH;
        gbc.weighty = 1;
        add(pane, gbc);

        revalidate();
        repaint();
    }

    public void removeSubMenu(SubMenuPane pane) {
        remove(pane);
        revalidate();
        repaint();
    }

    public void popLastMenu() {
        if (getComponentCount() == 1) {
            return;
        }
        remove(getComponent(getComponentCount() - 1));
        revalidate();
        repaint();
    }

}

public class SubMenuPane extends JPanel {

    public SubMenuPane(String name) {
        setLayout(new GridLayout(0, 1));
        setBorder(new LineBorder(Color.DARK_GRAY));
        add(new JLabel(name, JLabel.CENTER));
    }

    public SubMenuPane addAction(MenuAction action) {
        JButton btn = new JButton(action);
        add(btn);
        return this;
    }

}

Что-то, что я хотел сделать, это отделить части API и уменьшить объем знаний, которые есть у любой части API.

По сути, это проявляется в SubMenuPane, это просто контейнер для некоторых кнопок, которые настраиваются и управляются через класс MenuAction, кроме того, он ничего не делает.

public interface MenuAction extends Action {

    public MenuController getController();
}

public abstract class AbstractMenuAction extends AbstractAction implements MenuAction {

    private MenuController controller;

    public AbstractMenuAction(MenuController controller, String name) {
        this.controller = controller;
        putValue(NAME, name);
    }

    @Override
    public MenuController getController() {
        return controller;
    }

}

MenuAction основан на API действий , который обеспечивает автономную и настраиваемую единицу работы

И просто для примера я добавил контроллер, чтобы он находился между панелью меню и действиями меню.

public interface MenuController {
    public void addSubMenu(SubMenuPane subMenuPane);
    public void popLastMenu();
}

public class DefaultMenuController implements MenuController {

    private MenuPane menuPane;

    public DefaultMenuController(MenuPane menuPane) {
        this.menuPane = menuPane;
    }

    @Override
    public void addSubMenu(SubMenuPane subMenuPane) {
        menuPane.addSubMenuPane(subMenuPane);
    }

    @Override
    public void popLastMenu() {
        menuPane.popLastMenu();
    }

}

Смысл здесь в том, что я не хотел, чтобы действия могли неблагоприятно изменять панель меню, вместо этого я ограничил их только двумя операциями.

Хорошо, но как это вам поможет?

Хорошо, давайте построим меню и узнаем ...

MenuPane menuPane = new MenuPane();
DefaultMenuController controller = new DefaultMenuController(menuPane);

SubMenuPane ebanking = new SubMenuPane("E-Banking");
ebanking.addAction(new AbstractMenuAction(controller, "Deposit") {
    @Override
    public void actionPerformed(ActionEvent e) {
        getController().popLastMenu();
        SubMenuPane deposit = new SubMenuPane("Options").addAction(new AbstractMenuAction(getController(), "Request") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        }).addAction(new AbstractMenuAction(getController(), "Query") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        });
        getController().addSubMenu(deposit);
    }
}).addAction(new AbstractMenuAction(controller, "Credit") {
    @Override
    public void actionPerformed(ActionEvent e) {
        getController().popLastMenu();
        SubMenuPane deposit = new SubMenuPane("Credit-Options").addAction(new AbstractMenuAction(getController(), "Request") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        }).addAction(new AbstractMenuAction(getController(), "Query") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        });
        getController().addSubMenu(deposit);
    }
}).addAction(new AbstractMenuAction(controller, "Exchange") {
    @Override
    public void actionPerformed(ActionEvent e) {
        getController().popLastMenu();
        SubMenuPane deposit = new SubMenuPane("Exchange-Options").addAction(new AbstractMenuAction(getController(), "Request") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        }).addAction(new AbstractMenuAction(getController(), "Query") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        });
        getController().addSubMenu(deposit);
    }
}).addAction(new AbstractMenuAction(controller, "Simulation") {
    @Override
    public void actionPerformed(ActionEvent e) {
        getController().popLastMenu();
        SubMenuPane deposit = new SubMenuPane("Simulation-Options").addAction(new AbstractMenuAction(getController(), "Request") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        }).addAction(new AbstractMenuAction(getController(), "Query") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        });
        getController().addSubMenu(deposit);
    }
}).addAction(new AbstractMenuAction(controller, "Information") {
    @Override
    public void actionPerformed(ActionEvent e) {
        getController().popLastMenu();
        SubMenuPane deposit = new SubMenuPane("Information-Options").addAction(new AbstractMenuAction(getController(), "Request") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        }).addAction(new AbstractMenuAction(getController(), "Query") {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Use Card layout to show next avaliable options
            }
        });
        getController().addSubMenu(deposit);
    }
});
controller.addSubMenu(ebanking);

Хорошо, так что много "Что за ... код". Я использовал много анонимных классов просто для краткости, реально, у меня, вероятно, есть настройка подкласса для каждого действия меню, но это обеспечивает основную работу.

Дело в том, что каждое подменю может создаваться просто и легко, независимо от MenuPane, так как они связаны друг с другом через контроллер.

Вы можете дополнительно расширить контроллер, чтобы предоставить дополнительные функциональные возможности либо для запуска операций, которые создают подпредставления, либо для предоставления средств непосредственно через контроллер для открытия предоставленного вами подпредставления.

Причина, по которой я хотел продемонстрировать эту идею, заключается в том, что при добавлении новых подменю это будет влиять на оставшуюся область содержимого. Если вы попытаетесь сохранить это в одном макете / контейнере, вы будете постоянно бороться пытаясь сохранить все это вместе и хорошо работать вместе.

Вместо этого это решение содержит подменю для своего собственного контейнера, который управляет только меню, затем оно добавляется в другой контейнер, потенциально используя другой менеджер компоновки, который затем управляет внешними задачами отдельно.

Просто как идея

Пример выполнения ...

Putting to together

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                MenuPane menuPane = new MenuPane();
                DefaultMenuController controller = new DefaultMenuController(menuPane);

                SubMenuPane ebanking = new SubMenuPane("E-Banking");
                ebanking.addAction(new AbstractMenuAction(controller, "Deposit") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        getController().popLastMenu();
                        SubMenuPane deposit = new SubMenuPane("Options").addAction(new AbstractMenuAction(getController(), "Request") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        }).addAction(new AbstractMenuAction(getController(), "Query") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        });
                        getController().addSubMenu(deposit);
                    }
                }).addAction(new AbstractMenuAction(controller, "Credit") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        getController().popLastMenu();
                        SubMenuPane deposit = new SubMenuPane("Credit-Options").addAction(new AbstractMenuAction(getController(), "Request") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        }).addAction(new AbstractMenuAction(getController(), "Query") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        });
                        getController().addSubMenu(deposit);
                    }
                }).addAction(new AbstractMenuAction(controller, "Exchange") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        getController().popLastMenu();
                        SubMenuPane deposit = new SubMenuPane("Exchange-Options").addAction(new AbstractMenuAction(getController(), "Request") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        }).addAction(new AbstractMenuAction(getController(), "Query") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        });
                        getController().addSubMenu(deposit);
                    }
                }).addAction(new AbstractMenuAction(controller, "Simulation") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        getController().popLastMenu();
                        SubMenuPane deposit = new SubMenuPane("Simulation-Options").addAction(new AbstractMenuAction(getController(), "Request") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        }).addAction(new AbstractMenuAction(getController(), "Query") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        });
                        getController().addSubMenu(deposit);
                    }
                }).addAction(new AbstractMenuAction(controller, "Information") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        getController().popLastMenu();
                        SubMenuPane deposit = new SubMenuPane("Information-Options").addAction(new AbstractMenuAction(getController(), "Request") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        }).addAction(new AbstractMenuAction(getController(), "Query") {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                // Use Card layout to show next avaliable options
                            }
                        });
                        getController().addSubMenu(deposit);
                    }
                });
                controller.addSubMenu(ebanking);

                JPanel someContent = new JPanel() {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(200, 200);
                    }
                };
                someContent.setBackground(Color.RED);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(menuPane, BorderLayout.WEST);
                frame.add(someContent);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface MenuController {

        public void addSubMenu(SubMenuPane subMenuPane);

        public void popLastMenu();
    }

    public class DefaultMenuController implements MenuController {

        private MenuPane menuPane;

        public DefaultMenuController(MenuPane menuPane) {
            this.menuPane = menuPane;
        }

        @Override
        public void addSubMenu(SubMenuPane subMenuPane) {
            menuPane.addSubMenuPane(subMenuPane);
        }

        @Override
        public void popLastMenu() {
            menuPane.popLastMenu();
        }

    }

    public interface MenuAction extends Action {

        public MenuController getController();
    }

    public abstract class AbstractMenuAction extends AbstractAction implements MenuAction {

        private MenuController controller;

        public AbstractMenuAction(MenuController controller, String name) {
            this.controller = controller;
            putValue(NAME, name);
        }

        @Override
        public MenuController getController() {
            return controller;
        }

    }

    public class MenuPane extends JPanel {

        public MenuPane() {
            setLayout(new GridBagLayout());
        }

        public void addSubMenuPane(SubMenuPane pane) {
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.NORTH;
            gbc.weighty = 1;
            add(pane, gbc);

            revalidate();
            repaint();
        }

        public void removeSubMenu(SubMenuPane pane) {
            remove(pane);
            revalidate();
            repaint();
        }

        public void popLastMenu() {
            if (getComponentCount() == 1) {
                return;
            }
            remove(getComponent(getComponentCount() - 1));
            revalidate();
            repaint();
        }

    }

    public class SubMenuPane extends JPanel {

        public SubMenuPane(String name) {
            setLayout(new GridLayout(0, 1));
            setBorder(new LineBorder(Color.DARK_GRAY));
            add(new JLabel(name, JLabel.CENTER));
        }

        public SubMenuPane addAction(MenuAction action) {
            JButton btn = new JButton(action);
            add(btn);
            return this;
        }

        public void pop() {
            Container parent = getParent();
            if (parent != null) {
                parent.remove(this);
                parent.revalidate();
                parent.repaint();
            }
        }

    }

}

Примечание: это неполное решение, предназначенное для продвижения «другого способа мышления» при решении подобных проблем

0 голосов
/ 30 августа 2018

"constraints.weightx" - ваш друг.

Из Javadoc для " double java.awt.GridBagConstraints.weightx ":

Менеджер макета мешка сетки вычисляет вес столбца, чтобы он был максимальным весом x всех компонентов в столбце. Если получающийся макет меньше по горизонтали, чем область, которую он должен заполнить, дополнительное пространство распределяется по каждому столбцу пропорционально его весу. Столбец с нулевым весом не получает дополнительного пробела.

Это означает, что если вы укажете значение '0', следующий компонент будет распространен рядом с предыдущим компонентом.

После тестирования вашего кода, я смог достичь того, чего вы хотите, манипулируя ограничением.weightx в вашей initialize () функции. Хотя есть хитрость, я смог применить это, только если все MenuPanels видны!

То, что я сделал, было со всеми видимыми панелями меню:

constraints.weightx = secondMenuPanel.isVisible() ? 0.0 : 0.4;
constraints.weighty = 0.4;
constraints.fill = GridBagConstraints.NONE;
frame.getContentPane().add(menuPanel, constraints);
constraints.gridx++;

constraints.weightx = 0.4;
frame.getContentPane().add(secondMenuPanel, constraints);
constraints.gridx++;

Результат: enter image description here

Если вам нужно сделать это со скрытым компонентом (показывать только при нажатии кнопки), вам нужно будет обновить ограничения макета основного фрейма, чтобы они правильно отображали его.

Надеюсь, это вам поможет.

...