GridBagLayout不符合椭圆形状请求

时间:2014-07-09 23:11:31

标签: java swing layout-manager gridbaglayout

我正在使用swing来试图建立一个垄断板。我试图将板上的属性/空间作为单独的JPanels,可以有自己的实现,信息等,但我在空间的形状有一些麻烦。我正在使用GridBagLayout(我对这个布局管理器相当新),我正在尝试将面板放置出来,以便对于JPanels,gridwidth = 4,gridheight = 3(参见附加代码)。但是,当我运行它并查看它时,面板是方形的。当我将gridheight更改为2或1时,我确认这不起作用,它仍然显示正方形(我期望JPanels更加椭圆形)。

原谅命名方案,我只是在Eclipse中的一个单独的临时项目文件中尝试这种布局,然后才在我的主要垄断程序中实现gui。

import static java.awt.GridBagConstraints.*;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.*;

public class MainFrame extends JFrame {

    private static final long serialVersionUID = 1L;




    public MainFrame() {
        super();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Dimension screenSize = getToolkit().getScreenSize();
        setSize(screenSize.height, screenSize.height);

        setLocationRelativeTo(null);

        setLayout(new GridBagLayout());

        addCorners();

        addEdges();
        setVisible(true);

        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                System.out.println("Component resized");
                int width = getWidth();
                int height = getHeight();
                System.out.println(width + " " + height);
                super.componentResized(e);
            }
        });
    }

    private int startingColRow = 4;
    private int endingColRow = 28;

    private int bigWidth = 4;
    private int smallWidth = 3;

    private int startingEdge = 0;
    private int endingEdge = 31;




    private void addEdges() {
        addLeftEdge();
        addTopEdge();
        addBottomEdge();
        addRightEdge();
    }




    private void addCorners() {
        addTopLeftCorner();
        addBottomLeftCorner();
        addTopRightCorner();
        addBottomRightCorner();

    }




    private void addCorner(int anchor, int gridx, int gridy) {
        add(getWhiteJPanel(), getGridBagConstraints(anchor, gridx, gridy, bigWidth, bigWidth));
    }




    private void addBottomRightCorner() {
        addCorner(SOUTHEAST, endingEdge, endingEdge);
    }




    private void addTopRightCorner() {
        addCorner(NORTHWEST, endingEdge, startingEdge);
    }




    private void addBottomLeftCorner() {
        addCorner(SOUTHWEST, startingEdge, endingEdge);
    }




    private void addTopLeftCorner() {
        addCorner(NORTHEAST, startingEdge, startingEdge);
    }




    public void addLeftEdge() {
        for (int row = startingColRow; row <= endingColRow; row += smallWidth) {
            add(getWhiteJPanel(), getGridBagConstraints(WEST, startingEdge, row, bigWidth, smallWidth));
        }
    }




    public void addRightEdge() {
        for (int row = startingColRow; row <= endingColRow; row += smallWidth) {
            add(getWhiteJPanel(), getGridBagConstraints(EAST, endingEdge, row, bigWidth, smallWidth));
        }
    }




    public void addBottomEdge() {
        for (int col = startingColRow; col <= endingColRow; col += smallWidth) {
            add(getWhiteJPanel(), getGridBagConstraints(SOUTH, col, endingEdge, smallWidth, bigWidth));
        }
    }




    public void addTopEdge() {
        for (int col = startingColRow; col <= endingColRow; col += smallWidth) {
            add(getWhiteJPanel(), getGridBagConstraints(NORTH, col, startingEdge, smallWidth, bigWidth));
        }
    }




    private static JPanel getWhiteJPanel() {
        JPanel panel = new JPanel();
        panel.setBackground(Color.WHITE);
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        return panel;
    }




    private GridBagConstraints getGridBagConstraints(int anchor, int gridx, int gridy, int gridwidth, int gridheight) {
        GridBagConstraints c = new GridBagConstraints();
        c.fill = VERTICAL;
        c.weightx = c.weighty = 1;

        c.anchor = anchor;
        c.gridx = gridx;
        c.gridy = gridy;
        c.gridwidth = gridwidth;
        c.gridheight = gridheight;

        return c;
    }




    public static void main(String[] args) {
        new MainFrame();
    }
}

2 个答案:

答案 0 :(得分:5)

我对c.fill = VERTICAL感到有些困惑,我假设BOTH。除此之外,如果窗口是方形的,则棋盘将具有方形字段;如果窗口是椭圆形的,则将具有长方形字段。网格宽度和grigheight在这里完全无关紧要。相反,如果您想要在其中一个轴上重叠区域的对象,则可以使用它们。最好将网格袋布局视为大网格。然后gridwidth和gridheight告诉布局给定对象应占用多少列或行。但没有什么可说的,列应该与行高一样宽。事实上,没有什么可以说行或列具有相同的大小。所以我会说你对GridBagLayout的运作方式有一些不正确的想法。

如果要修复宽高比,则应为各个窗格设置首选尺寸,然后将整个电路板打包到滚动视图中。这将确保所有内容都以首选尺寸显示。不过,不确定滚动是否适合您的情况。如果没有,你可以尝试一个具有一些合适布局的外部容器,这将允许内部容器增长到其首选尺寸,而不是更大。

答案 1 :(得分:1)

您确定要使用GridBagLayout吗?也许如果你看一下 MigLayout's解决方案,你会改变主意。

package com.zetcode;

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;

/*
 * This program creates a Monopoly board using
 * the MigLayout manager.
 *
 * Author Jan Bodnar
 * Website zetcode.com
 * Last modified: July 2014
 */

public class MigLayoutMonopoly extends JFrame {

    public MigLayoutMonopoly() {

        initUI();

        setTitle("Monopoly");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void initUI() {

        setLayout(new MigLayout("fill, gap 2 2"));

        // top row of panels
        add(createPanel2());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel2(), "wrap");

        // left column of panels
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel3(), "wrap");
        add(createPanel2());

        // bottom row of panels
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel1());
        add(createPanel2());

        // right column of panels
        add(createPanel3(), "cell 10 1");
        add(createPanel3(), "cell 10 2");
        add(createPanel3(), "cell 10 3");
        add(createPanel3(), "cell 10 4");
        add(createPanel3(), "cell 10 5");
        add(createPanel3(), "cell 10 6");
        add(createPanel3(), "cell 10 7");
        add(createPanel3(), "cell 10 8");
        add(createPanel3(), "cell 10 9");

        // center panel
        add(createPanel2(), "cell 1 1 9 9, grow");

        pack();
    }

   public JPanel createPanel1() {
        JPanel pnl = new JPanel(){ 

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(40, 60);
            }

            @Override
            public Dimension getMinimumSize() {
                return getPreferredSize();
            }            

        };

        pnl.setBorder(BorderFactory.createEtchedBorder());
        return pnl;
    }    

   public JPanel createPanel2() {
        JPanel pnl = new JPanel(){ 

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(60, 60);
            }

            @Override
            public Dimension getMinimumSize() {
                return getPreferredSize();
            }                  

        };

        pnl.setBorder(BorderFactory.createEtchedBorder());
        return pnl;
    }   

   public JPanel createPanel3() {
        JPanel pnl = new JPanel(){ 

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(60, 40);
            }

            @Override
            public Dimension getMinimumSize() {
                return getPreferredSize();
            }                  

        };

        pnl.setBorder(BorderFactory.createEtchedBorder());
        return pnl;
    }      


    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutMonopoly ex = new MigLayoutMonopoly();
                ex.setVisible(true);
            }
        });
    }
}

MigLayout具有强大的网格结构,我们可以相对放置组件 或使用绝对单元格。

这取决于要求,但我认为电路板不应缩小 因为它们要包含位图。 (也许容器应该有固定的尺寸。)因此,我已经将面板的首选尺寸设置为最小尺寸 - 面板不会缩小,而是从面板上切割下来。此外,当容器生长时,面板不会 增长但面板之间的差距。所有这些都可以满足一个人的需求。

Monopoly board