【问题标题】:GUI Text AlignmentGUI 文本对齐
【发布时间】:2014-08-06 22:14:56
【问题描述】:

我正在研究一个战舰计划,我遇到了一个小事故。我想标记两个网格(用户和计算机),所以我使用 GridBagLayout 来控制组件的大小。现在,当我将文本居中放置在它所在标签的中间时,它什么也不做,它停留在同一个地方。这是我的代码:

package buttongrid;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;

public class ButtonGrid {

        JFrame frame=new JFrame(); //creates frame
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        JPanel panel3 = new JPanel();
        JPanel panel4 = new JPanel();
        JPanel panel5 = new JPanel();
        JPanel panel6 = new JPanel();
        JLabel label1 = new JLabel();
        JLabel label2 = new JLabel();
        JLabel[][] grid; //names the grid of buttons
        JLabel[][] enemyGrid;
        String COLS = "ABCDEFGHIJK";
        GridBagConstraints c = new GridBagConstraints();
        Border border = BorderFactory.createLineBorder(Color.BLACK, 1);

        public ButtonGrid() throws MalformedURLException{ //constructor
            URL urlPic = new URL("http://i47.tinypic.com/14wswi9.gif");
            ImageIcon waterPic = new ImageIcon(urlPic);

                frame.setLayout(new GridBagLayout()); //set layout
                frame.setResizable(false);

                //ADDING TOP LEFT PANEL
                label1.setText("Your Grid");
                label1.setHorizontalTextPosition(SwingConstants.CENTER);
                label1.setVerticalTextPosition(SwingConstants.CENTER);
                panel4.add(label1);
                panel4.setBorder(border);
                c.gridx = 0;
                c.gridy = 0;
                c.ipady = 10;
                frame.add(panel4, c);

                //ADDING TOP MIDDLE PANEL
                panel5.setBorder(border);
                c.gridx = 1;
                c.gridy = 0;
                c.ipady = 10;
                frame.add(panel5, c);

                //ADDING TOP MIDDLE PANEL
                label2.setText("Enemy Grid");
                label2.setHorizontalTextPosition(SwingConstants.CENTER);
                label2.setVerticalTextPosition(SwingConstants.CENTER);
                panel6.add(label2);
                panel6.setBorder(border);
                c.gridx = 2;
                c.gridy = 0;
                c.ipady = 10;
                frame.add(panel6, c);

                //USER GRID
                c.gridx = 0;
                c.gridy = 1;
                panel1.setLayout(new GridLayout(11,11));
                grid=new JLabel[11][11]; //allocate the size of grid
                for(int y=0; y<11; y++){
                        for(int x=0; x<11; x++){
                            ImageIcon icon2 = new ImageIcon(new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB));
                                grid[x][y]= new JLabel(icon2);
                                grid[x][y].setBorder(border);
                                panel1.add(grid[x][y]); 
                        }
                }

                frame.add(panel1, c);

                for(int y=1; y<11; y++){
                    grid[y][0].setText(Integer.toString(y));
                    grid[y][0].setHorizontalTextPosition(SwingConstants.CENTER);
                        for(int x=1; x<11; x++){
                            grid[x][y].setIcon(waterPic);
                        }
                }

                for(int x = 1; x < 11; x++){
                    grid[0][x].setText(COLS.substring(x - 1, x));
                    grid[0][x].setHorizontalTextPosition(SwingConstants.CENTER);
                }

                //EMPTY SPACE IN BETWEEN GRIDS
                c.fill = GridBagConstraints.VERTICAL;
                c.gridx = 1;
                c.gridy = 1;
                c.ipadx = 10;
                panel2.setBorder(border);
                frame.add(panel2, c);

                //ENEMY GRID
                c.gridx = 2;
                c.gridy = 1;
                panel3.setLayout(new GridLayout(11,11));
                enemyGrid=new JLabel[11][11]; //allocate the size of grid
                for(int y=0; y<11; y++){
                        for(int x=0; x<11; x++){
                            ImageIcon icon2 = new ImageIcon(new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB));
                                enemyGrid[x][y]= new JLabel(icon2); //  
                                enemyGrid[x][y].setBorder(border);
                                panel3.add(enemyGrid[x][y]); //
                        }
                }

                frame.add(panel3, c);

                for(int y=1; y<11; y++){
                    enemyGrid[y][0].setText(Integer.toString(y));
                    enemyGrid[y][0].setHorizontalTextPosition(SwingConstants.CENTER);
                        for(int x=1; x<11; x++){
                            enemyGrid[x][y].setIcon(waterPic);
                        }
                }

                for(int x = 1; x < 11; x++){
                    enemyGrid[0][x].setText(COLS.substring(x - 1, x));
                    enemyGrid[0][x].setHorizontalTextPosition(SwingConstants.CENTER);
                }

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack(); //sets appropriate size for frame
                frame.setVisible(true); //makes frame visible
        }
        public static void main(String[] args) throws MalformedURLException{
                new ButtonGrid();//makes new ButtonGrid with 2 parameters
        }
}

我在框架中的每个组件周围都添加了一个边框,只是为了让事情变得更容易。

【问题讨论】:

    标签: java swing alignment layout-manager


    【解决方案1】:

    根据 Mad 的建议,即问题出在面板的布局管理器上,我会更进一步说您甚至不需要 JPanel 来保存标签。只需将标签直接添加到网格,然后您甚至需要担心面板。

    您可以通过在每个标签上使用边框来控制所需的间距。例如,您可以创建一个边框,如:

    Border labelBorder = BorderFactory.createEmptyBorder(5, 10, 5, 10);
    

    那么将标签添加到网格的代码是:

    label1.setBorder(labelBorder);
    //panel4.add(label1);
    //panel4.setBorder(border);
    c.gridx = 0;
    c.gridy = 0;
    //c.ipady = 10;
    //frame.add(panel4, c);
    frame.add(label1, c);
    

    对于中间组件,您可以只创建一个不带文本的 JLabel。然后边框将占据整个空间,这将控制两个网格之间的水平空间。

    此外,无需创建 BufferedImages 即可将它们用作图标。网格的大小将由“水”图像的大小决定。

    要使网格中的文本居中,您应该使用以下方法:

    label.setHorizontalAlignment(SwingConstants.CENTER);
    

    垂直对齐的默认值为 CENTER,因此您无需担心。

    【讨论】:

    • 对于 BufferedImages 的事情,我认为我确实需要它,因为数字行和字母列会比我需要的小,所以我将网格中的所有内容都设置为默认大小否则会改变。
    • @user3741402,GridLayout 中所有单元格的单元格大小相同。添加到网格中的最大组件决定了网格中所有单元格的大小。
    【解决方案2】:

    我假设你的意思是标题标签...

    这是由布局管理器而不是标签本身引起的。 JPanel 默认使用 FlowLayout。考虑使用不同的布局管理器,例如GridBagLayout

    JPanel panel4 = new JPanel(new GridBagLayout());
    JPanel panel6 = new JPanel(new GridBagLayout());
    

    如果您想要更多关于标签的填充,您可以使用 CompoundBorder 并将当前边框与 EmptyBorder 混合,或者使用 GridBagConstraints 定义额外的插图...

    例如...

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.insets = new Insets(8, 8, 8, 8);
    
    //...
    panel4.add(label1, gbc);
    //...
    panel6.add(label2, gbc);
    

    不过,您可能会得到更好的结果,您将 UI 分解为多个部分。网格是可重复的组件,所以首先要让网格成为它自己的组件。

    您可以使用BorderLayout 来定位标题和网格本身,然后使用另一个容器,使用GridLayout 添加GridPanels 以将它们并排放置,例如...

    【讨论】:

    • +1,用于将面板的布局管理器识别为问题。
    • 啊,好的,我知道了,我一定会试试看它是否有效,谢谢!
    猜你喜欢
    • 2017-08-10
    • 2020-07-12
    • 2015-02-12
    • 2020-05-23
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    相关资源
    最近更新 更多