【问题标题】:GridBagLayout not applying gridy changesGridBagLayout 不应用网格更改
【发布时间】:2017-05-28 02:51:42
【问题描述】:

我正在尝试创建一个个人 DnD 字符表程序。主要想法是有 4 个大面板,每个面板都包含基本字符表的主要部分之一。我目前正在研究第一个具有统计数据和保存投掷的面板。在制作这个时,我试图让 GridBagLayout 更舒服,但我在设置网格时遇到了问题。我已经访问过不遵守 gridx 和 gridy 的 GridBagLayout 并且(除非我只是愚蠢),这对我没有帮助。我将 GridBagLayout 和 GridBagConstraints 用于 statsPanel() 并且 gridy 工作得很好。

这就是问题所在:每当我在proficinciesAndSkillsPanel() 中将gridy 设置为下一个网格时,它都会被视为我刚刚更改了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;
}

【问题讨论】:

    标签: java swing user-interface layout-manager gridbaglayout


    【解决方案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 而实际上它不是,它使用 JPanel 的默认 FlowLayout

    一个令人困惑的地方:你有许多 JPanel 变量被赋予了相同的名称,结果。在您的代码中,您实际上调用了result.setLayout(new GridBagLayout()),但不是针对我上面显示的JPanel,这可能会让您感到困惑。我建议您避免在代码中使用相同的变量名,以避免这种混淆。

    如果您需要更具体的帮助,请先告诉我们更多详细信息,并将您的相关代码显示为有效的minimal example program or MCVE。如果您站在我们的立场上,并试图理解其他人令人困惑的代码,那么如果他们努力使该代码对我们来说可编译和可运行,那将产生巨大的不同。

    【讨论】:

    • 天哪,非常感谢。我将开始使用不同的变量名,不敢相信我忽略了这个简单的错误!
    • @NateCowley:不客气。有时需要一组新的眼球才能找到这些东西。另请检查我对创建和发布minimal reproducible example 代码的回答所做的编辑。感谢您在以后的问题中关注此问题。
    • @AndrewThompson:您的评论是指@Nate 吗?谢谢。
    • @HovercraftFullOfEels "..你的意思是 @Nate 在你的评论中吗?" 是的,不是的。问题是,考虑到提出问题的人会被通知所有关于问题或任何答案的 cmets,这是多余的。碰巧的是,您在这个问题上的通知也是毫无意义的,因为您会根据自己的答案收到所有 cmets 的通知。我只是很傻。 :P
    • 啊,我不知道提问者会自动收到答案中的 cmets 通知。所以我猜就不需要@NateCowley。
    猜你喜欢
    • 2012-01-12
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    相关资源
    最近更新 更多