我想要一个带有4个象限的矩形GUI。 JFrame的高度与宽度的比率(不包括最小/最大化/关闭按钮)应为phi的1,其中phi等于黄金比率(约1.62)。



现在,对于JFrame中的四个象限。 JFrame具有水平分隔线,可将高度分为上下两部分。鞋帮的高度与鞋帮的高度之间的比率也应为phi到1。最后,JFrame具有垂直分隔线,可将宽度分为左右两部分。左侧和右侧之间的比例也应为phi的一。参见上图。

现在,这是困难的部分。我希望这四个组件始终遵循比率,无论将哪个Swing组件(JScrollPane,JList,JTextArea,JPanel,JTree或JButton)放入相应的网格位置。例如,我希望能够从四个网格位置中的四个JButton开始,然后将其中一个JPanel与一个包含JList的JScrollPane交换,而内部组件不会更改外部组件的相对比率,即使内部组件中包含一些文本或数据或其他内容。参见下图。



无论我多么努力地实现它(使用GridBadLayout和一组约束),我都无法保持网格线不变。如何使网格线保持原位?

到目前为止,我的源代码如下所示:

public static final double GOLDEN_RATIO = 1.6180339887498948482;
public static final double RELATIVE_LENGTH_OF_LONGER_SIDE = 1 / GOLDEN_RATIO;
public static final double RELATIVE_LENGTH_OF_SHORTER_SIDE = 1 - (1/GOLDEN_RATIO);

// ...

    // make GridBagLayout
    pane.setLayout(new GridBagLayout());
    final GridBagConstraints c = new GridBagConstraints();

    // Make 4 components to put in the four grid spaces.
    JButton filler1 = new JButton();
    c.fill = GridBagConstraints.BOTH;
    c.weightx = RELATIVE_LENGTH_OF_SHORTER_SIDE;
    c.weighty = RELATIVE_LENGTH_OF_LONGER_SIDE;
    c.gridx = 0;
    c.gridy = 0;
    filler1.setMinimumSize(new Dimension(0,0));
    filler1.setPreferredSize(new Dimension(0,0));
    pane.add(filler1, c);

    JButton filler2 = new JButton();
    c.fill = GridBagConstraints.BOTH;
    c.weightx = RELATIVE_LENGTH_OF_LONGER_SIDE;
    c.weighty = RELATIVE_LENGTH_OF_LONGER_SIDE;
    c.gridx = 1;
    c.gridy = 0;
    filler2.setMinimumSize(new Dimension(0,0));
    filler2.setPreferredSize(new Dimension(0,0));
    pane.add(filler2, c);

    JButton filler3 = new JButton();
    c.fill = GridBagConstraints.BOTH;
    c.weightx = RELATIVE_LENGTH_OF_SHORTER_SIDE;
    c.weighty = RELATIVE_LENGTH_OF_SHORTER_SIDE;
    c.gridx = 0;
    c.gridy = 1;
    filler3.setMinimumSize(new Dimension(0,0));
    filler3.setPreferredSize(new Dimension(0,0));
    pane.add(filler3, c);

    JButton filler4 = new JButton();
    c.fill = GridBagConstraints.BOTH;
    c.weightx = RELATIVE_LENGTH_OF_LONGER_SIDE;
    c.weighty = RELATIVE_LENGTH_OF_SHORTER_SIDE;
    c.gridx = 1;
    c.gridy = 1;
    filler4.setMinimumSize(new Dimension(0,0));
    filler4.setPreferredSize(new Dimension(0,0));
    pane.add(filler4, c);

    // Set the size of the enclosing panel.
    this.setPreferredSize(new Dimension(
            (int)(screen_height_*RELATIVE_LENGTH_OF_LONGER_SIDE),
            (int)(screen_height_*RELATIVE_LENGTH_OF_SHORTER_SIDE))
    );


另外,无论我将尺寸变小,它都永远不会像这样:

最佳答案

您可以使用GroupLayout为您完成工作。

编辑:添加了交换按钮

例:






import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.WindowConstants;

public class Test extends JFrame {

    public static final double GOLDEN_RATIO = 1.6180339887498948482;
    public static final double RELATIVE_LENGTH_OF_LONGER_SIDE = 1 / GOLDEN_RATIO;
    public static final double RELATIVE_LENGTH_OF_SHORTER_SIDE = 1 - (1 / GOLDEN_RATIO);
    private static final int screenHeight = 500;
    private static final int LENGTH_OF_LONGER_SIDE_FOR_RATIO = (int) (screenHeight * RELATIVE_LENGTH_OF_LONGER_SIDE);
    private static final int LENGTH_OF_SHORTER_SIDE_FOR_RATIO = (int) (screenHeight * RELATIVE_LENGTH_OF_SHORTER_SIDE);
    private static final int MIN_LENGTH_OF_LONGER_SIDE_FOR_RATIO = (int) (50 * RELATIVE_LENGTH_OF_LONGER_SIDE);
    private static final int MIN_LENGTH_OF_SHORTER_SIDE_FOR_RATIO = (int) (50 * RELATIVE_LENGTH_OF_SHORTER_SIDE);

    public Test() {
        buildGUI();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void buildGUI() {
        JPanel pane = new JPanel();
        // make GridBagLayout
        GroupLayout layout = new GroupLayout(pane);
        pane.setLayout(layout);

        // Make 4 components to put in the four grid spaces.
        JButton filler1 = new JButton("Press here to swap");
        JButton filler2 = new JButton("Press here to swap");
        JButton filler3 = new JButton("Press here to swap");
        Object[] objects = new Object[50];
        for (int i = 0; i < 50; i++) {
            objects[i] = "Test" + i;
        }
        JTree jTree = new JTree(objects);
        JScrollPane scrollPane = new JScrollPane(jTree);
        JButton button = new JButton("Press here to swap");
        JPanel filler4 = new JPanel(new BorderLayout());
        filler4.add(button);
        ActionListener l = (e) -> {
            if (filler4.getComponents()[0] instanceof JButton) {
                filler4.remove(button);
                filler4.add(scrollPane, BorderLayout.CENTER);
            } else {
                filler4.remove(scrollPane);
                filler4.add(button, BorderLayout.CENTER);
            }
            filler4.repaint();
            filler4.revalidate();
        };
        filler1.addActionListener(l);
        filler2.addActionListener(l);
        filler3.addActionListener(l);
        button.addActionListener(l);
        layout.setVerticalGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(filler1, MIN_LENGTH_OF_LONGER_SIDE_FOR_RATIO, LENGTH_OF_LONGER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                        .addComponent(filler2, MIN_LENGTH_OF_LONGER_SIDE_FOR_RATIO, LENGTH_OF_LONGER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                )
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(filler3, MIN_LENGTH_OF_SHORTER_SIDE_FOR_RATIO, LENGTH_OF_SHORTER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                        .addComponent(filler4, MIN_LENGTH_OF_SHORTER_SIDE_FOR_RATIO, LENGTH_OF_SHORTER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                ));
        layout.setHorizontalGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(filler1, MIN_LENGTH_OF_SHORTER_SIDE_FOR_RATIO, LENGTH_OF_SHORTER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                        .addComponent(filler3, MIN_LENGTH_OF_SHORTER_SIDE_FOR_RATIO, LENGTH_OF_SHORTER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                )
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(filler2, MIN_LENGTH_OF_LONGER_SIDE_FOR_RATIO, LENGTH_OF_LONGER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                        .addComponent(filler4, MIN_LENGTH_OF_LONGER_SIDE_FOR_RATIO, LENGTH_OF_LONGER_SIDE_FOR_RATIO, Short.MAX_VALUE)
                ));
        add(pane);
        setSize(new Dimension(200, 200));
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new Test().setVisible(true);
        });
    }

}

关于java - 如何制作4个象限的Java Swing GUI,使其侧面始终符合黄金分割率?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30195185/

10-12 03:21