首页 文章

JPanel GridLayout(部分由循环填充)将新值添加到结尾,而不管它们的添加顺序如何

提问于
浏览
2

所以我正在玩Swing和GUI,设计一个程序,其中我有一个包含10x10自定义JButton网格的JPanel . 我有1-10的数字水平索引,以及A-J(两个JLabels)的字母垂直索引 .

我使用带有WEST的垂直索引的BorderLayout,以及嵌套在CENTER中的11x10 GridLayout(为什么?因为这是我能想到的最简单的方法来完善水平索引号在其相应按钮列上方的位置) .

我有110个空间网格的前10个空格,用数字来索引列 - 这很好用 .

然后我使用一个11x1网格将垂直索引上的字母平均分配给WEST,以考虑网格顶部水平索引的额外插槽(见下图) .

我的问题是:每当我去填充垂直网格顶部的空白区域时,它会将新的JLabel放在底部,无论它是放在填充循环之前还是之后 .

结果如下:

enter image description here

这里是我用来填充循环的代码,在填充循环之前和之后添加了一个JLabel,以显示它是如何放置在底部的:

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

public class Test {

 private static void createAndDisplayGUI() {

 // This panel contains the grid layout for the buttons
 JPanel center = new JPanel();
 center.setLayout(new BorderLayout());

 JPanel gridIndexLeft = new JPanel();
 gridIndexLeft.setLayout(new GridLayout(12,1));
 gridIndexLeft.add(new JLabel(" " + 0)); // Added a 0 here before fill loop to show where space should be
 for (int i=0; i<10; i++) {
   gridIndexLeft.add(new JLabel(" " + Character.toString((char)('J' - i))), SwingConstants.CENTER);
 }
 gridIndexLeft.add(new JLabel(" " + 0)); // And again here with same result

 JPanel buttons = new JPanel();
 buttons.setLayout(new GridLayout(11,10));
 for (int i=0; i<10; i++) {
   buttons.add(new JLabel("  " + (10-i)), SwingConstants.CENTER);
 }
 for (int i=0; i<100; i++) {
   buttons.add(new BattleshipButton());
 }

 center.add(gridIndexLeft, BorderLayout.WEST, SwingConstants.CENTER);
 center.add(buttons, BorderLayout.CENTER, SwingConstants.CENTER);

 JPanel content =  new JPanel();
 content.setLayout(new BorderLayout());
 content.add(center, BorderLayout.CENTER);

 JFrame display = new JFrame();
 display.setContentPane(content);
 display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 display.setBackground(Color.GRAY);
 display.setResizable(false);
 display.setSize(300,325);
 display.setLocation(500,190);
 display.setVisible(true);
 }

public static void main(String[] args) {

 try {
   UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );
 } catch (Exception e) {
   e.printStackTrace();
 }

 SwingUtilities.invokeLater(new Runnable() {
   public void run() {
     createAndDisplayGUI();
   }
 }); 
 }
}

我知道间距应该是11x1才能匹配,但我已经做了12x1以显示在循环之前和之后添加新的JLabel时会发生什么 .

任何输入将非常感谢!

1 回答

  • 5

    你问题发生在这里......

    gridIndexLeft.add(new JLabel(" " + Character.toString((char) ('J' - i))), SwingConstants.CENTER);
    

    SwingConstants.CENTER == 0 ,它被中断为“在 0 位置添加此组件”,这意味着您之前添加的任何内容实际上都被按下了,为什么当您使用 GridLayout 时尝试使用它,我不确定(也许你想改变标签的水平/垂直位置?)

    所以,当我将代码更新为类似...

    JPanel gridIndexLeft = new JPanel();
    gridIndexLeft.setLayout(new GridLayout(12, 1));
    gridIndexLeft.add(new JLabel("-" + 0)); // Added a 0 here before fill loop to show where space should be
    for (int i = 0; i < 10; i++) {
        gridIndexLeft.add(new JLabel(" " + Character.toString((char) ('J' - i))));
    }
    gridIndexLeft.add(new JLabel("+" + 0)); // And again here with same result
    

    它产生了......

    GridLayout

    你可以看到 -0 是第一个, +0 是最后一个

    现在,如果您真的感兴趣,可以使用单个容器和 GridLayout

    GridLayout

    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class GridTest {
    
        public static void main(String[] args) {
            new GridTest();
        }
    
        public GridTest() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridLayout(11, 11));
    
                for (int row = 0; row < 11; row++) {
                    if (row > 0) {
                        add(new JLabel(Character.toString((char) (('A' + row) - 1))));
                    } else {
                        add(new JLabel(" "));
                    }
                    for (int col = 0; col < 10; col++) {
                        if (row == 0) {
                            add(new JLabel(Integer.toString(col + 1)));
                        } else {
                            add(new JButton(" "));
                        }
                    }
                }
            }
    
        }
    
    }
    

    是的,您可以更改 JLabel 的水平和垂直属性

相关问题