Как я могу использовать GridBayLayout в Java (Swing) для генерации этого конкретного изображения в моем кадре?

Desired main GUI

В основном, как мне сгенерировать это? Я уверен, что это работа дляGridBagLayout, но я не могу обернуть голову, как правильно выбрать размер «Панели действий»; по сравнению с «Menubar». Красный & amp; черные линии указывают на сетку, которую, я полагаю, вы будете использовать в этом случае (3x3), но я могу быть совершенно неправ, и может быть способ сделать это в другой конфигурации. Я пытался возиться сweightx, weighty, gridheight, gridwidth значения вGridBagConstraints, но я не могу достичь своих целей здесь.

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

Это моя последняя попытка: использовать сетку 3x6 (c - это объект GridBagConstraints, characterPortraits содержит все портреты, а currentScreen - это «Панель действий»):

c.fill = GridBagConstraints.BOTH;
    c.weightx = 0.25;
    c.weighty = (1/6);
    c.gridx = 0;
    c.gridy = 0;
    c.gridheight = 3;
    pane.add(characterPortraits.get(0), c);  

    c.gridx = 2;        
    pane.add(characterPortraits.get(1), c);          

    c.gridx = 0;
    c.gridy = 3;
    c.gridheight = 3;
    pane.add(characterPortraits.get(2), c);  

    c.gridx = 2;        
    pane.add(characterPortraits.get(3), c);

    //c.fill = GridBagConstraints.NONE;
    c.weightx = 1.0;
    c.weighty = 1.0;
    c.gridx = 1;
    c.gridy = 0;
    c.gridheight = 3;
    pane.add(currentScreen, c);    

Вместо этого создается каждый портрет в нижней трети его квадранта, а панель действий занимает 5/6 центрального столбца вместо 4/6, как я этого хочу. Любые идеи помогут; Спасибо! -B.

РЕДАКТИРОВАТЬ: я проектирую это приложение, чтобы иметь фиксированный размер окна; люди могут сказать, что это плохой дизайн, но я просто пытаюсь почувствовать компоненты Swing и убедиться, что они, по крайней мере, ведут себя в фиксированном окне так, как я хочу. Я думаю, что я могу позволить максимально изменить правильное изменение размера, но это об этом.

 Hovercraft Full Of Eels23 июн. 2012 г., 01:49
Посмотрите на Miglayout. Это легче использовать для этого, чем gridbaglayout.
 arcy23 июн. 2012 г., 01:45
Вы пытались использовать сетку 3x3, установить все веса на 1, установить размеры для ActionPane и MenuBar, чтобы ActionPane, Portrait2 и Portrait4 занимали две ячейки по вертикали? Если вы ориентируетесь на окно фиксированного размера, настройка размеров двух компонентов (или даже 6) вас беспокоит ...
 arcy23 июн. 2012 г., 01:26
Если окно растягивается, какие компоненты вы хотите занять доступное пространство (горизонтальное и вертикальное)?
 mKorbel23 июн. 2012 г., 01:30
все элементы изменяемого размера ???
 Billy M.23 июн. 2012 г., 01:31
Спасибо за вопросы; обратился к ним в редактировании, которое я только что сделал.

Ответы на вопрос(2)

Решение Вопроса

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

Instead, this produces each portrait in the bottom third of its quadrant, and the 
Action Pane taking 5/6 of the center column instead of 4/6, like I want it to.

это добавить одинJPanel в этом месте и положить вашActionPane а такжеJmenuBar к этому добавленоJPanel, чтобы достичь желаемого результата. Итак, я добавилcenterPanel в этом месте, чтобы продемонстрировать, как этого можно достичь.

Я надеюсь, что это то, что вы так хотели:

OUTPUT

И вот код, ответственный за этот вывод:

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

public class GridBagPanelLayout
{
    private JPanel portrait1;
    private JPanel portrait2;
    private JPanel portrait3;
    private JPanel portrait4;
    private JPanel centerPanel;

    private JPanel actionPane;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("GridBag JPanel Layout Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /*
         * This JPanel will serve as the 
         * Content Pane, for the JFrame.
         */
        JPanel contentPane = new JPanel();
        contentPane.setOpaque(true);
        contentPane.setBackground(Color.WHITE);
        contentPane.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.33;
        gbc.weighty = 0.5;
        gbc.gridheight = 2;

        portrait1 = new JPanel();
        portrait1.setOpaque(true);
        portrait1.setBackground(Color.BLUE);
        portrait1.setBorder(
                    BorderFactory.createMatteBorder(
                            2, 2, 2, 2, Color.WHITE));
        contentPane.add(portrait1, gbc);

        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weighty = 1.0;
        gbc.gridheight = 4;

        centerPanel = new JPanel();
        centerPanel.setOpaque(true);
        centerPanel.setBackground(Color.WHITE);
        centerPanel.setLayout(new GridBagLayout());
        GridBagConstraints constCenter = new GridBagConstraints();
        constCenter.anchor = GridBagConstraints.FIRST_LINE_START;
        constCenter.fill = GridBagConstraints.BOTH;
        constCenter.gridx = 0;
        constCenter.gridy = 0;
        constCenter.weightx = 1.0;
        constCenter.weighty = 0.975;

        actionPane = new JPanel();
        actionPane.setOpaque(true);
        actionPane.setBackground(Color.MAGENTA);
        actionPane.setBorder(
                    BorderFactory.createMatteBorder(
                            2, 2, 2, 2, Color.WHITE));
        centerPanel.add(actionPane, constCenter);

        constCenter.gridx = 0;
        constCenter.gridy = 1;
        constCenter.weighty = 0.025;

        centerPanel.add(getMenuBar(), constCenter); 
        contentPane.add(centerPanel, gbc);  

        gbc.gridx = 2;
        gbc.gridy = 0;
        gbc.weighty = 0.5;
        gbc.gridheight = 2;

        portrait3 = new JPanel();
        portrait3.setOpaque(true);
        portrait3.setBackground(Color.BLUE);
        portrait3.setBorder(
                    BorderFactory.createMatteBorder(
                            2, 2, 2, 2, Color.WHITE));
        contentPane.add(portrait3, gbc);

        gbc.gridx = 0;
        gbc.gridy = 2;
        //gbc.weighty = 0.5;
        //gbc.gridheight = 2;

        portrait2 = new JPanel();
        portrait2.setOpaque(true);
        portrait2.setBackground(Color.BLUE);
        portrait2.setBorder(
                    BorderFactory.createMatteBorder(
                            2, 2, 2, 2, Color.WHITE));
        contentPane.add(portrait2, gbc);

        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.weighty = 0.5;
        gbc.gridheight = 2;

        portrait4 = new JPanel();
        portrait4.setOpaque(true);
        portrait4.setBackground(Color.BLUE);
        portrait4.setBorder(
                    BorderFactory.createMatteBorder(
                            2, 2, 2, 2, Color.WHITE));
        contentPane.add(portrait4, gbc);

        frame.setContentPane(contentPane);
        frame.setSize(500, 300);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JMenuBar getMenuBar()
    {
        JMenuBar menuBar = new JMenuBar();

        JMenu fileMenu = new JMenu("File");
        fileMenu.setOpaque(true);
        fileMenu.setBackground(Color.BLACK);
        fileMenu.setForeground(Color.WHITE);
        JMenuItem newItem = new JMenuItem("NEW");
        JMenuItem openItem = new JMenuItem("OPEN");
        fileMenu.add(newItem);
        fileMenu.add(openItem);

        JMenu editMenu = new JMenu("Edit");
        editMenu.setOpaque(true);
        editMenu.setBackground(Color.BLACK);
        editMenu.setForeground(Color.WHITE);
        JMenuItem redoItem = new JMenuItem("Redo");
        JMenuItem undoItem = new JMenuItem("Undo");
        editMenu.add(redoItem);
        editMenu.add(undoItem);

        JMenu viewMenu = new JMenu("View");
        viewMenu.setOpaque(true);
        viewMenu.setBackground(Color.BLACK);
        viewMenu.setForeground(Color.WHITE);
        JMenuItem zInItem = new JMenuItem("Zoom In");
        JMenuItem zOutItem = new JMenuItem("Zoom Out");
        viewMenu.add(zInItem);
        viewMenu.add(zOutItem);

        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        menuBar.add(viewMenu);
        menuBar.setOpaque(true);
        menuBar.setBackground(Color.BLACK);     

        return menuBar;
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new GridBagPanelLayout().createAndDisplayGUI();
            }
        });
    }
}
 Billy M.28 июн. 2012 г., 23:41
Любопытно ... если я укажуweightx вначале как 0.33, тогда он работает так, как вы его отобразили, но если я укажу его более точно как (1/3), то портреты будут видны в центре и очень маленькие - почему это так?
 29 июн. 2012 г., 06:12
Или ты можешь написать(double) 1 / 3
 Billy M.29 июн. 2012 г., 18:37
смешно ... я писал(double) (1 / 3) раньше, но я предполагаю, что порядок операций все же сделал его приведенным к целому числу. Еще раз большое спасибо.
 29 июн. 2012 г., 06:06
Извините за поздний ответ, это былоNIGHT время, когда вы отправляете это сообщение. Я думаю, что ответ в основах языка Java, результат деления двухInteger значения такжеIntegerТаким образом, значение идет вresult variable послеCasting который равен нулю, вот почему. Попробуйте что-то вроде1.0/3.0Я думаю, что это разница :-) ОтсюдаMORAL Точный путь0.333 и не1/3 :-)
 Billy M.27 июн. 2012 г., 00:51
@NIcE COw: Спасибо за комментарий и код! Это довольно близко к тому, что я хочу, за исключением того факта, что мой "menubar" не должен бытьJMenuBarВероятно, это моя ошибка, потому что я не могу назвать ее "menubar". На самом деле это просто модная панель меню-лайка с похожими параметрами, но с прикрепленными к ней пользовательскими цветами и мышью. Еще раз спасибо!

Я никогда не был большим поклонником GridBagLayout. Это трудно понять правильно - каждый компонент может иметь до 11 ограничений - это трудно поддерживать, и повторное использование одного и того же объекта ограничений может привести к непредвиденным последствиям.

Вместо этого я предпочитаю вкладывать различные типы макетов. Для меня вы явно имеете:

A BorderLayout, with West, Center, and East panels Inside the West panel, you have a GridLayout - 2 rows, 1 column (Portraits 1 and 2). Inside the East panel, you have a GridLayout - 2 rows, 1 column (Portraits 3 and 4). Inside the Center panel, you have another BorderLayout, with a Center component (Action Pane) and a South component (Menubar).

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

 23 июн. 2012 г., 06:49
+1 заNested Layout, Если вы хотите, чтобы они были почти одинакового размера, вы можете сначала поставитьJPanel наWEST/EAST/LINE_START/LINE_END а затем добавитьportrait JPanel Кроме того, это может привести к тому, что они будут иметь почти равные размеры. Пожалуйста, посмотрите на этот пример, показанныйhere @trashgod и еще одинhere.
 Billy M.27 июн. 2012 г., 04:56
Я хочу принять оба ваших ответа, но я предпочитаю приятные часы выше этого из-за большего контроля и гибкости, чемGridLayout а такжеBorderLayout предоставлять. Здесь очень хорошие вещи - еще раз спасибо.
 23 июн. 2012 г., 06:49
Без сомнения,GridBagLayout не легко справиться, хотя результат, который каждый получает в конце, всегда приятен.

Ваш ответ на вопрос