java - Swing:垂直堆叠组件,无需 MigLayout

标签 java swing layout-manager

我终于得到了我想要的垂直堆叠组件的行为,这些组件具有随时间变化的首选高度。但我需要使用 MigLayout。

有没有办法在不使用 MigLayout 的情况下做到这一点? (这是针对图书馆的,除非必须,否则我不想强制依赖)

这是我正在寻找的行为(我的测试程序实现了):

enter image description here

按垂直顺序,有一个调整大小按钮、“空白空间”(好吧,一个 JLabel 如此标记)、一个红色矩形和一个绿色正方形。调整大小按钮具有固定高度。红色方 block 的大小是随机的,可以在任意时间改变。绿色方 block 设置其首选高度以匹配其宽度,我想扩展其宽度以填充容器。空白空间水平和垂直扩展以填充容器中的剩余空间。

什么可以代替 MigLayout?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;

public class AutoResizeDemo extends JPanel
{   
    static private class ResizingPanel extends JPanel
    {
        final private Color color;

        private Dimension dpref = new Dimension(100,100);

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int w = getWidth();
            int h = getHeight();
            g.setColor(this.color);
            g.fillRect(0, 0, w, h);
            g.setColor(Color.BLACK);
            g.drawRect(0, 0, w-1, h-1); 
            String s = this.dpref.width+"x"+this.dpref.height;
            FontMetrics fm = g.getFontMetrics();
            g.drawString(s, 0, fm.getHeight());
        }

        public ResizingPanel(Color color, boolean isSquare)
        {
            this.color = color;
            if (isSquare)
            {
                addComponentListener(new ComponentAdapter() {
                    @Override public void componentResized(ComponentEvent e) {
                        doResize(getWidth(), getWidth());
                    }               
                });
            }
        }

        @Override public Dimension getPreferredSize() {
            return this.dpref;
        } 

        public void doResize(int w, int h)
        {
            this.dpref = new Dimension(w, h);
            revalidate();
        }
    }

    public AutoResizeDemo()
    {
        super(new MigLayout("","[grow]",""));
        setPreferredSize(new Dimension(200, 800));

        final ResizingPanel resizingPanelRandom = new ResizingPanel(Color.RED, false);
        ResizingPanel resizingPanelSquare = new ResizingPanel(Color.GREEN, true);
        JPanel buttonPanel = new JPanel(new FlowLayout());

        final Random rand = new Random();
        addButton(buttonPanel, "resize",new Runnable() {
            @Override public void run() {
                resizingPanelRandom.doResize(
                        rand.nextInt(100)+100,
                        rand.nextInt(100)+100
                        );
            }           
        });
        add(buttonPanel, "wrap");
        JLabel spaceLabel = new JLabel("empty space");
        spaceLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        add(spaceLabel, "push, grow, wrap");
        add(resizingPanelRandom, "wrap");
        add(resizingPanelSquare,"pushx, growx, wrap");
    }

    private void addButton(JPanel panel, String title, final Runnable r) {
        JButton button = new JButton(title);
        button.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                r.run();
            }           
        });
        panel.add(button);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame(AutoResizeDemo.class.getSimpleName());
        frame.setContentPane(new AutoResizeDemo());
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }

}

最佳答案

使用 BoxLayout。

您可以使用 Box.createVerticalGlue() 来填充空白区域。

BoxLayout 尊重组件的最大尺寸,因此您可能需要重写 getMaximumSize() 方法以返回红色和绿色框的首选尺寸。

对于绿色框,您还需要重写 getPreferredSize() 以保持高度与宽度同步。

关于java - Swing:垂直堆叠组件,无需 MigLayout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6346259/

相关文章:

java - JAXB 无法将接口(interface)作为参数和返回类型处理

java - 是否可以在基于 Spring 的控制台应用程序中使用 @Valid 注释?

java - GLPK-Java 解决 MILP 类型问题

java - 在 SwingWorker 中运行 ExecutorService 是一个好习惯吗?

Java 使标签移动?

java - Gui 的按钮布局问题

java - 正则表达式适用于在线 validator ,但在 java checkstyle 中失败

java - BorderLayout 和 JPanel 与 JLabel

java - 如何在 Java GUI 中创建类似表的结构

java - 我应该使用哪个布局管理器来实现以下目标?