【问题标题】:FlowLayout not displaying components while GridLayout does?FlowLayout 不显示组件而 GridLayout 显示?
【发布时间】:2012-06-17 12:53:06
【问题描述】:

我正在制作一个应用程序来充当某种中心,用户可以在其中存储他们喜爱的应用程序的快捷方式并轻松启动它们。不过,FlowLayout 有一些问题。当我使用GridLayout 时,组件显示完美。当我使用FlowLayout 时,什么都没有显示。

网格布局:

流式布局:

我改变的只是LayoutManager。当我打电话给getComponentCount 时,他们都回复了 9。

我认为这篇文章很长,所以我将我的code 的 sn-p 放在 Code Tidy(来自 Pastebin)上

提前感谢您的帮助!

【问题讨论】:

  • 当你写return new Dimension(getWidth(), getHeight());时,考虑到谁的WidthHeight?如果它是 JComponent 本身,那么如果您扩展 JComponent/JPanel ,那么对于大多数布局来说,它的大小是 (0, 0)。因此,您必须提供一些具体的 Dimension(一些非零值),以便组件出现。

标签: java swing layout-manager


【解决方案1】:

1) FlowLayout 非常接受来自JComponentPreferredSize,每个JComponents 可以在屏幕上得到不同的Dimension

示例(取消注释 getMinimumSizegetMinimumSize

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

public class CustomComponent extends JFrame {

    private static final long serialVersionUID = 1L;

    public CustomComponent() {
        setTitle("Custom Component Test / BorderLayout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
    }

    public void display() {
        add(new CustomComponents0(), BorderLayout.NORTH);
        add(new CustomComponents0(), BorderLayout.CENTER);
        add(new CustomComponents0(), BorderLayout.SOUTH);
        add(new CustomComponents0(), BorderLayout.EAST);
        pack();
        // enforces the minimum size of both frame and component
        setMinimumSize(getMinimumSize());
        setPreferredSize(getPreferredSize());
        setVisible(true);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                CustomComponent main = new CustomComponent();
                main.display();
            }
        };
        javax.swing.SwingUtilities.invokeLater(r);
    }
}

class CustomComponents0 extends JLabel {

    private static final long serialVersionUID = 1L;

    /*@Override
    public Dimension getMinimumSize() {
    return new Dimension(200, 100);
    }

    @Override
    public Dimension getPreferredSize() {
    return new Dimension(300, 200);
    }*/
    @Override
    public void paintComponent(Graphics g) {
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
    }
}

2)GridLayout 为每个JComponents 创建比例区域,然后只接受来自DimnesionJComponent 更大的Dimnesion 来自PreferredSize

3)对于GridLayout我说的是方法pack(),不是JFrame#setSize(),对于FLowLayout没关系,

【讨论】:

  • 我是个菜鸟,但是在测试您的代码时,IDE 无法编译它,因为CustomComponents0。我做错了吗?
【解决方案2】:

嗯,我知道这已经得到解答,但只是补充一下,如果您查看下面的代码并运行它,它将创建 9 个标签和 4 个按钮并使用流布局添加它们,但与下面的示例一样使用setSize(int width,int height)设置帧大小

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class FlowLayoutTest extends JFrame {

    private JPanel NorthPanel, SouthPanel;
    private JLabel[] labels;
    private JButton[] buttons;

    public FlowLayoutTest() {
        createAndShowUI();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                FlowLayoutTest flowLayoutTest = new FlowLayoutTest();
            }
        });
    }

    private void createAndShowUI() {
        setTitle("Flow layout");
        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        initializeComponents();
        addComponents(this.getContentPane());

        //pack();

        setVisible(true);
    }

    private void initializeComponents() {

        labels = new JLabel[9];
        for (int i = 0; i < labels.length; i++) {
            labels[i] = new JLabel("Label " + (i+1));
        }
        buttons = new JButton[4];
        for (int i = 0; i < buttons.length; i++) {
            buttons[i] = new JButton("Button " + (i+1));
        }

        NorthPanel = new JPanel(new FlowLayout(5));
        SouthPanel = new JPanel(new FlowLayout(5));
    }

    private void addComponents(Container contentPane) {

        for (int i = 0; i < buttons.length; i++) {
            SouthPanel.add(buttons[i]);
        }

        for (int i = 0; i < labels.length; i++) {
            NorthPanel.add(labels[i]);
        }

        contentPane.add(NorthPanel, BorderLayout.NORTH);
        contentPane.add(SouthPanel, BorderLayout.SOUTH);
    }
}

但是,当您运行应用程序时,您会注意到一个标签(数字 9)已经离开屏幕,这是因为使用了 setSize(),但是如果我们在设置框架之前调用(或者在这种情况下取​​消注释)pack()可见,您将能够看到框架上的所有组件。

【讨论】:

  • +1 赌永远不会返回 setSize(),而是 PreferredSize(),因为自定义 LayoutManagers 的一部分可能会以错误的方式缩小尺寸
  • 嗯,从来没有这样想过是吧? +1。每天学习新东西
  • 是否也可以将不适合下一行的标签包裹起来?
猜你喜欢
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 2014-12-06
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
相关资源
最近更新 更多