java - 防止自定义 JPanel 扩展

标签 java swing layout-manager gridbaglayout

我想创建一个自定义 JPanel允许我的用户选择 4 个角之一。我已经使用 4 JRadioButton 完成了此操作s 并放置 TitledBorder在面板上。

我希望面板始终尽可能小,以使面板看起来整洁干净。我认为这是可能的,因为布局应该尊重最大和最小尺寸属性。

首先,我尝试使用 setMaximumSize() 将它们设置为最小尺寸和 setPreferredSize()但这没有用。然后我尝试重载 getMaximumSize()getPreferredSize()但这似乎也没有效果。在我的所有布局中,我的面板都会增长以填充其所在布局所决定的空间。我已经在 GridBagLayout 上进行了测试我想将其放置在 BorderLayout 上在一个空的JFrame中创建用于测试。

这是我的代码:

public class OverlayAnchorPanel extends JPanel implements ItemListener{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private AnchorChangeListener anchorListener;
    private JRadioButton rdbtnSouthEast;
    private JRadioButton rdbtnSouthWest;
    private JRadioButton rdbtnNorthWest;
    private JRadioButton rdbtnNorthEast;
    private ButtonGroup radioGroup;

    /**
     * Create the panel.
     */
    public OverlayAnchorPanel() {
        this.radioGroup = new ButtonGroup();
        setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Anchor", TitledBorder.LEADING, TitledBorder.TOP, null, null));
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0, 0};
        gridBagLayout.rowHeights = new int[]{0, 0};
        gridBagLayout.columnWeights = new double[]{0.0, 0.0};
        gridBagLayout.rowWeights = new double[]{0.0, 0.0};
        setLayout(gridBagLayout);

        rdbtnNorthEast = new JRadioButton("");
        GridBagConstraints gbc_rdbtnNorthEast = new GridBagConstraints();
        gbc_rdbtnNorthEast.insets = new Insets(0, 0, 5, 0);
        gbc_rdbtnNorthEast.gridx = 1;
        gbc_rdbtnNorthEast.gridy = 0;
        add(rdbtnNorthEast, gbc_rdbtnNorthEast);
        this.radioGroup.add(rdbtnNorthEast);

        rdbtnNorthWest = new JRadioButton("");
        GridBagConstraints gbc_rdbtnNorthWest = new GridBagConstraints();
        gbc_rdbtnNorthWest.insets = new Insets(0, 0, 5, 5);
        gbc_rdbtnNorthWest.gridx = 0;
        gbc_rdbtnNorthWest.gridy = 0;
        add(rdbtnNorthWest, gbc_rdbtnNorthWest);
        this.radioGroup.add(rdbtnNorthWest);

        rdbtnSouthWest = new JRadioButton("");
        GridBagConstraints gbc_rdbtnSouthWest = new GridBagConstraints();
        gbc_rdbtnSouthWest.insets = new Insets(0, 0, 0, 5);
        gbc_rdbtnSouthWest.gridx = 0;
        gbc_rdbtnSouthWest.gridy = 1;
        add(rdbtnSouthWest, gbc_rdbtnSouthWest);
        this.radioGroup.add(rdbtnSouthWest);

        rdbtnSouthEast = new JRadioButton("");
        rdbtnSouthEast.setSelected(true);
        GridBagConstraints gbc_rdbtnSouthEast = new GridBagConstraints();
        gbc_rdbtnSouthEast.gridx = 1;
        gbc_rdbtnSouthEast.gridy = 1;
        add(rdbtnSouthEast, gbc_rdbtnSouthEast);;
        this.radioGroup.add(rdbtnSouthEast);

        // This was my first attempt and did not work
        //this.setMaximumSize(this.getMinimumSize());
        //this.setPreferredSize(this.getMinimumSize());
    }

    public AnchorChangeListener getAnchorListener() {
        return anchorListener;
    }

    public void setAnchorListener(AnchorChangeListener anchorListener) {
        this.anchorListener = anchorListener;
    }


    @Override
    public void itemStateChanged(ItemEvent arg0) {
        OverlayAnchor newAnchor;
        if(arg0.getSource() == this.rdbtnNorthEast){
            newAnchor = OverlayAnchor.NORTHEAST;
        } else if(arg0.getSource() == this.rdbtnNorthWest){
            newAnchor = OverlayAnchor.NORTHWEST;
        } else if(arg0.getSource() == this.rdbtnSouthEast){
            newAnchor = OverlayAnchor.SOUTHEAST;
        } else{
            newAnchor = OverlayAnchor.SOUTHWEST;
        }
        if(this.anchorListener !=null){
            this.anchorListener.anchorChanged(new AnchorChangeEvent(this, newAnchor));
        }
    }

    public Dimension getPreferredSize(){
        return this.getMinimumSize();
    }

    public Dimension getMaximumSize(){
        return this.getMinimumSize();
    }
}

最佳答案

组件的布局方式取决于很多因素。显然,第一个是父容器布局管理器的选择。

布局管理器可以自由地使用来自 getPreferred/Miniumum/MaximumSize 的信息,也可以自由地忽略它们或根据需要使用它们的组合。

例如,BorderLayout倾向于使用组件的首选大小,但会允许父容器随意扩展和收缩,通常扩展和收缩CENTER 根据需要组成。

在我的测试中,我只是将框架的布局管理器更改为 GridBagLayout 并得到了这个结果...

Anchor

基本上,GridBagLayout 将遵循大小提示,只要它们不与您提供的约束相矛盾。

关于java - 防止自定义 JPanel 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21391557/

相关文章:

java - 为什么将字段从 int 更改为 Integer 会导致对象从 Set 中消失?

java - jpanel 无法很好地显示 jframe 设置为 gridbaglayout

java - 除非我将所有内容都放在一个类中,否则 JMenuBar 不会出现

游戏循环和按钮的 Java 图形问题

java - 单击 Jbutton 后更改 JPanel

java - 如何为嵌套 JPanel 选择最佳布局?

java - 离开页面时运行java函数(HTML)

java - Selenium 网络驱动程序。错误 'org.openqa.selenium.StaleElementReferenceException: Element is no longer valid'

java - CardLayout 从另一个类更改面板

Java,无限循环 - 仅限 2 的倍数