GridBagLayout не применяет сеточные изменения

Я пытаюсь создать личную программу листа персонажей DnD. Основная идея состоит в том, чтобы иметь 4 большие панели, каждая из которых содержит один из основных разделов основного листа персонажа. Сейчас я работаю над первой панелью, в которой есть статистика и спасброски. Я пытаюсь освоиться с GridBagLayout при этом, но у меня возникла проблема с настройкой сетки. Я уже посетил GridBagLayout, не подчиняясь gridx и gridy, и (если только я не дурак) это мне не помогло. Я использовал GridBagLayout с GridBagConstraints для statsPanel (), и сетка работала нормально.

Вот проблема: всякий раз, когда я устанавливаю gridy для следующей сетки в proficinciesAndSkillsPanel (), это обрабатывается так, как будто я только что изменил gridx. Моя цель - иметь один столбец с множеством строк, а не одну строку с множеством столбцов. Спасибо за уделенное время

//this builds the jframe and sets the primary jpanel
private void buildComponents()
{
    setSize(800, 600);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel mp = (JPanel)getContentPane();
    mp.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.BOTH;

    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.weightx = 1.0;
    gbc.weighty = 1.0;
    gbc.gridheight = 1;
    gbc.gridwidth = 1;
    gbc.gridx = 0;
    gbc.gridy = 0;

    mp.add(panelA(), gbc);



    gbc.gridx = 1;

    mp.add(new JButton("test"), gbc);

    createMenuBar();
    setVisible(true);
}

//this creates the first real panel that i'm currently working with
private JPanel panelA()
{
    JPanel result = new JPanel();
    result.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();

    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.fill = GridBagConstraints.BOTH;

    gbc.gridx = 0;
    gbc.gridy = 0;

//I left out the code for statsPanel() because that works fine
    result.add(statsPanel(), gbc);

    gbc.gridx = 1;

    result.add(proficinciesAndSkillsPanel(), gbc);

    return result;
}

//this builds the second half of the upper portion of panel A
private JPanel proficinciesAndSkillsPanel()
{
    JPanel result = new JPanel();
    GridBagConstraints gbc = new GridBagConstraints();

    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.weightx = 1;
    gbc.weighty = 1;

    result.add(labeledTextField("Inspiration", inspirationField = new JTextField(2), null, 1), gbc);

    gbc.gridx = 0;
    gbc.gridy = 1;

    result.add(labeledTextField("Proficiency bonus", proficiencyField = new JTextField(2), null, 1),gbc);

    gbc.gridx = 0;
    gbc.gridy = 2;

    result.add(labeledRadioField("Strength", strSTField = new JTextField(2), strRB = new JRadioButton()),gbc);

    return result;
}

//this creates a JTextField with the appropriate label and a sub-JTextField
private JPanel labeledTextField(String str, JTextField jtf, JTextField bonjtf, int space)
{
    JPanel result = new JPanel();
    JPanel subResult = new JPanel();
    result.setLayout(new FlowLayout());
    result.add(new JLabel(str));
    result.add(Box.createHorizontalStrut(space));
    subResult.add(jtf);
    jtf.setHorizontalAlignment(JTextField.CENTER);
    try
    {
        subResult.add(bonjtf);
        bonjtf.setHorizontalAlignment(JTextField.CENTER);
        bonjtf.setEditable(false);
        bonjtf.setText("+0");
    }catch(NullPointerException e){}
    jtf.addKeyListener(new JTF_Listener(){
        public void update() {
            String str2 = "";
            try
            {
                int result = (Integer.parseInt(jtf.getText())-10)/2;
                if(result >=0)
                {
                    str2 += "+"+Integer.toString(result);
                }
                else
                {
                    str2 += Integer.toString(result);
                }
            }catch(NumberFormatException nfe){}
            bonjtf.setText(str2);
        }
    });
    result.add(subResult);
    return result;
}

//this does the same as labeledTextField, just with a radioButton
private JPanel labeledRadioField(String str, JTextField jtf, JRadioButton jrb)
{
    JPanel result = new JPanel();
    result.setLayout(new FlowLayout());
    result.add(jrb);
    result.add(jtf);
    result.add(new JLabel(str));
    jtf.setHorizontalAlignment(JTextField.CENTER);
    jtf.setText("+0");
    jtf.addKeyListener(new JTF_Listener(){
        public void update(){
            String str2 = "";
            try
            {
                int result = Integer.parseInt(jtf.getText());
                str2+= "+" + Integer.toString(result);
            }catch(NumberFormatException nfe){}
            jtf.setText(str2);
        }
    });

    return result;
}

person Nate Cowley    schedule 12.01.2017    source источник


Ответы (1)


Не уверен, что это ваша проблема, поскольку вы не разместили действительный MCVE (пожалуйста, исправьте это!), Но здесь:

private JPanel proficinciesAndSkillsPanel()
{
    JPanel result = new JPanel();  // ******** here *********
    GridBagConstraints gbc = new GridBagConstraints();

    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.weightx = 1;
    gbc.weighty = 1;

    result.add(labeledTextField("Inspiration", inspirationField = new JTextField(2), null, 1), gbc);

    gbc.gridx = 0;
    gbc.gridy = 1;

    result.add(labeledTextField("Proficiency bonus", proficiencyField = new JTextField(2), null, 1),gbc);

    gbc.gridx = 0;
    gbc.gridy = 2;

    result.add(labeledRadioField("Strength", strSTField = new JTextField(2), strRB = new JRadioButton()),gbc);

    return result;
}

Вы обрабатываете этот результат JPanel так, как если бы он использовал GridBagLayout, хотя на самом деле это не так, он использует FlowLayout по умолчанию JPanel

Один запутанный момент: у вас есть много переменных JPanel с одинаковыми именами, result. Фактически в вашем коде вы вызываете result.setLayout(new GridBagLayout()), но не для JPanel, который я показываю выше, и это может вас сбить с толку. Я предлагаю вам избегать использования тех же имен переменных в вашем коде, что и вы, чтобы избежать этой путаницы.

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

person Hovercraft Full Of Eels    schedule 12.01.2017
comment
О, черт возьми, большое тебе спасибо. Я начну использовать разные имена переменных, не могу поверить, что упустил эту простую ошибку! - person Nate Cowley; 13.01.2017
comment
@NateCowley: пожалуйста. Иногда требуется свежий взгляд на вещи, чтобы найти эти вещи. Также проверьте изменения к моему ответу относительно создания и публикации минимального воспроизводимого примера кода. Спасибо за внимание к этому вопросу в будущих вопросах. - person Hovercraft Full Of Eels; 13.01.2017
comment
@AndrewThompson: вы имели в виду @Nate в своем комментарии? И спасибо. - person Hovercraft Full Of Eels; 14.01.2017
comment
@HovercraftFullOfEels .. вы имели в виду @Nate в своем комментарии? Да и нет. Дело в том, что это было лишним, учитывая, что человек, задающий вопрос, уведомляется обо всех комментариях либо к вопросу, либо к любым ответам. Как оказалось, уведомление о вас по этому вопросу также было бессмысленным, учитывая, что вы уведомлены обо всех комментариях к вашему собственному ответу. Я просто вел себя глупо. :П - person Andrew Thompson; 14.01.2017
comment
ах, я не знал, что спрашивающий будет автоматически уведомлен о комментариях, сделанных в ответах. Так что, думаю, @NateCowley не понадобится. - person Hovercraft Full Of Eels; 14.01.2017