我想要一个带有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/