【问题标题】:Anchor constraint in GridBagLayout not workingGridBagLayout 中的锚定约束不起作用
【发布时间】:2020-10-27 07:34:19
【问题描述】:
import java.awt.*;
import javax.swing.*;

public class GBLClumpingExample extends JFrame{

    GBLClumpingExample(){
        GridBagLayout g = new GridBagLayout();
        GridBagConstraints gv = new GridBagConstraints();

        GridBagLayout b = new GridBagLayout();
        GridBagConstraints gc = new GridBagConstraints();

        setVisible(true);
        setSize(720,720);
        setLayout(g);

        JPanel p = new JPanel();
        p.setLayout(b);
        gv.fill = GridBagConstraints.BOTH;
        add(p,gv);
        
        Label l1 = new Label("Label 1");
        Label l2 = new Label("Label 2");
        Label l3 = new Label("Label 3");
        Label l4 = new Label("Label 4");
        Label l5 = new Label("Label 5");
        
        gc.weightx =1.0;
        gc.weighty = 1.0;
        gc.gridx= 1;
        gc.gridy= 1;
        gc.anchor = GridBagConstraints.PAGE_START;
        gc.gridx= -1;
        gc.gridy= 0;
        p.add(l1,gc);
        gc.anchor = GridBagConstraints.SOUTH;
        p.add(l2,gc);
        gc.anchor = GridBagConstraints.EAST;
        p.add(l3,gc);
        gc.anchor = GridBagConstraints.WEST;
        p.add(l4,gc);
        gc.anchor = GridBagConstraints.CENTER;
        p.add(l5,gc);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args){
        GBLClumpingExample e = new GBLClumpingExample();
    }
}

我尝试使用GridBagLayout,但它可能无法正常工作。

这是我的代码,我不知道有什么问题,但 GridBagConstraints 的锚约束不起作用,它们都只是聚集在一起。

【问题讨论】:

  • anchor 会将组件限制在单元格内的该位置,但单元格将处理为组件的首选大小,因此您可能没有“看到”结果 - 因为@987654328 @ 不会扩展以填充框架
  • BTW 1) 举个例子better name than example。对于所有这样的短代码,我只有一个包,每个人和他的狗都想调用那里的示例代码example。使其更具体,例如GBLClumpingExample。 2) 在提供提示的同时:请学习常见的 Java 命名法(命名约定 - 例如EachWordUpperCaseClassfirstWordLowerCaseMethod()firstWordLowerCaseAttribute,除非它是 UPPER_CASE_CONSTANT)并始终如一地使用它。 ..
  • .. 3) Label l1 = new Label("Label 1"); 应该是 JLabel l1 = new JLabel("Label 1");(其他的等等)- 不要混合 Swing 和 AWT 组件。
  • 只有三个有用的锚GridBagConstraints; GridBagConstraints.LINE_START、GridBagConstraints.CENTER 和 GridBagConstraints.LINE_END。您必须使用 gridx 和 gridy 参数在页面上定位 Swing 组件。此外,组织您的代码,以便对每个 Swing 组件的方法调用进行分组。它使人们更容易理解您的代码。这是 Oracle 的教程,如何使用 GridBag 布局。 docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
  • @AndrewThompson -1 for gridxGridBagConstraints.RELATIVE 相同,这意味着将添加的组件放置在先前添加的组件的右侧。它甚至是默认值。当然,最好使用命名常量来避免这种混淆。

标签: java swing layout-manager gridbaglayout


【解决方案1】:

您将组件添加到面板p,然后使用add(p,gv); 添加到框架(到其内容窗格)。 gv 中的约束已使用 gv.fill = GridBagConstraints.BOTH; 进行了初始化,但其 weightxweighty 保留为初始零。因此,此面板将保持其首选大小并且不会获得额外空间,因此它没有额外空间来分配给自己的内容。

由于所有标签的大小相同,因此在没有额外空间时,它们的锚点无效。

换行时

gv.fill = GridBagConstraints.BOTH;

gv.fill = GridBagConstraints.BOTH;
gv.weightx = 1;
gv.weighty = 1;

您将看到锚点的效果。或者,您可以摆脱附加面板。还有其他冗余操作。您可以将代码简化为:

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

public class GBAnchorExample extends JFrame{
    GBAnchorExample() {
        Container c = super.getContentPane();
        c.setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.weightx = gc.weighty = 1.0;

        JLabel l1 = new JLabel("Label 1");
        JLabel l2 = new JLabel("Label 2");
        JLabel l3 = new JLabel("Label 3");
        JLabel l4 = new JLabel("Label 4");
        JLabel l5 = new JLabel("Label 5");

        gc.anchor = GridBagConstraints.PAGE_START;
        c.add(l1,gc);
        gc.anchor = GridBagConstraints.SOUTH;
        c.add(l2,gc);
        gc.anchor = GridBagConstraints.EAST;
        c.add(l3,gc);
        gc.anchor = GridBagConstraints.WEST;
        c.add(l4,gc);
        gc.anchor = GridBagConstraints.CENTER;
        c.add(l5,gc);
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        GBAnchorExample e = new GBAnchorExample();
        e.setSize(720,720);
        e.setVisible(true);
    }
}

要可视化锚点的实际效果,您可以将main 方法更改为

public static void main(String[] args){
    GBAnchorExample e = new GBAnchorExample();
    Component grid = new JComponent() {
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.GREEN);
            int w = getWidth(), h = getHeight();
            for(int i = 1; i < 5; i++) {
                int x = (int)(w/5.0*i);
                g.drawLine(x, 0, x, h);
            }
        }
    };
    e.setGlassPane(grid);
    grid.setVisible(true);
    e.setSize(720,720);
    e.setVisible(true);
}

这将绘制一个绿色网格以显示包含标签的逻辑单元格,因此锚点如何影响标签在其单元格中的位置变得显而易见。

【讨论】:

    【解决方案2】:

    如果我正确理解此布局的意图(我不确定确定我知道),那么这可以使用BorderLayout 来完成。

    这里有更多的宽度和高度:

    带标题的边框仅用于提供对用于放置组件的约束的快速视觉参考。 (spacer) 仅添加到中间行的 3 个标签中,以允许完整的 TitledBorder 出现!

    代码如下:

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    
    public class BLNotClumpingExample {
    
        private JComponent ui = null;
    
        BLNotClumpingExample() {
            initUI();
        }
    
        public void initUI() {
            if (ui!=null) return;
    
            ui = new JPanel(new BorderLayout(10,10));
            ui.setBorder(new EmptyBorder(4,4,4,4));
            
            ui.add(getLabel("Label 1", "PAGE_START"), BorderLayout.PAGE_START);
            ui.add(getLabel("Label 2", "PAGE_END"), BorderLayout.PAGE_END);
            ui.add(getLabel("Label 3 (spacer)", "LINE_END"), BorderLayout.LINE_END);
            ui.add(getLabel("Label 4 (spacer)", "LINE_START"), BorderLayout.LINE_START);
            ui.add(getLabel("Label 5 (spacer)", "CENTER"), BorderLayout.CENTER);
        }
        
        private JLabel getLabel(String text, String constraint) {
            JLabel l = new JLabel(text, SwingConstants.CENTER);
            l.setBorder(new TitledBorder(constraint));
            return l;
        }
    
        public JComponent getUI() {
            return ui;
        }
    
        public static void main(String[] args) {
            Runnable r = () -> {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                BLNotClumpingExample o = new BLNotClumpingExample();
                
                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);
                
                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());
                
                f.setVisible(true);
            };
            SwingUtilities.invokeLater(r);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2018-12-30
      • 2015-03-13
      相关资源
      最近更新 更多