4

如果我有一个带有多个子组件的 JPanel,我将如何制作它以便 JPanel 仍然是一个正方形,尽管它的父级是如何调整大小的?我尝试了以下代码的变体,但它不会导致子组件也是方形的。

public void paint(Graphics g){
    if(this.isSquare()){
        Dimension d = this.getSize();
        if(d.height > d.width){
            this.setSize(d.width, d.width);
        } else {
            this.setSize(d.height, d.height);
    }
    super.paint(g);
}

这是一个SSCCE。

包含的父级:

import javax.swing.JFrame;

public class TestFrame extends JFrame{

    public TestFrame(){
        this.add(new TestPanel());
    }

    public static void main(String[] args){
        TestFrame tf = new TestFrame();

        tf.setSize(500, 500);
        tf.setVisible(true);
    }
}

什么应该是方形JPanel:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;


public class TestPanel extends JPanel{
    private boolean isSquare;

    public TestPanel(){
        this.setSquare(true);
        this.setLayout(new BorderLayout());

        JLabel panel1 = new JLabel();
        panel1.setBorder(new LineBorder(Color.RED, 4));
        panel1.setBackground(Color.CYAN);

        JLabel panel2 = new JLabel();
        panel2.setBorder(new LineBorder(Color.BLUE, 4));
        panel2.setBackground(Color.CYAN);


        this.setBorder(new LineBorder(Color.GREEN, 4));
        this.setBackground(Color.CYAN);

        this.add(panel1, BorderLayout.WEST);
        this.add(panel2, BorderLayout.EAST);
    }

    public void paint(Graphics g){
        if(this.isSquare()){
            Dimension d = this.getSize();
            if(d.height > d.width){
                this.setSize(d.width, d.width);
            } else {
                this.setSize(d.height, d.height);
            }
            super.paint(g);
        }
    }

    private boolean isSquare() {
        return isSquare;
    }

    private void setSquare(boolean isSquare) {
        this.isSquare = isSquare;
    }
}
4

2 回答 2

8
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class SoSquare {

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

            @Override
            public void run() {
                // the GUI as seen by the user (without frame)
                // A single component added to a GBL with no constraint
                // will be centered.
                JPanel gui = new JPanel(new GridBagLayout());

                gui.setBackground(Color.WHITE);

                SquarePanel p = new SquarePanel();
                p.setBackground(Color.red);
                gui.add(p);

                JFrame f = new JFrame("Demo");
                f.add(gui);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                f.setSize(400,100);
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

/**
 * A square panel for rendering. NOTE: To work correctly, this must be the only
 * component in a parent with a layout that allows the child to decide the size.
 */
class SquarePanel extends JPanel {

    @Override
    public Dimension getPreferredSize() {
        Dimension d = super.getPreferredSize();
        Container c = getParent();
        if (c != null) {
            d = c.getSize();
        } else {
            return new Dimension(10, 10);
        }
        int w = (int) d.getWidth();
        int h = (int) d.getHeight();
        int s = (w < h ? w : h);
        return new Dimension(s, s);
    }
}
于 2013-04-18T06:25:13.953 回答
4

利用尊重组件的首选/最小/最大尺寸的布局管理器。覆盖getPreferred/Minimum/MaximumSize方法以返回所需的大小。

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class SqaurePaneTest {

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

    public SqaurePaneTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            add(new JLabel("Look ma, I'm a square", JLabel.CENTER));
            setBorder(new LineBorder(Color.GRAY));
        }

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

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

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

}

或者,创建您自己的布局管理器,做同样的事情(使所有组件方形)

于 2013-04-18T05:26:51.617 回答