如何使四象限Java Swing GUI的侧面始终符合黄金比例?
我想要一个有4个象限的矩形GUI。JFrame的高度与宽度之比(不包括最小化/最大化/关闭按钮)应为1:phi,其中phi等于黄金比例(约为1.62) 现在,对于JFrame中的四个象限。JFrame有一条水平分界线,将高度分为上下两部分。上部和下部高度之间的比率也应为φ1。最后,JFrame有一条垂直分界线,将宽度分成两部分,一部分是左侧,另一部分是右侧。左侧和右侧之间的比率也应为1:phi。见上图 现在,困难的部分来了。我希望这四个组件始终遵守比率,无论将哪个Swing组件(JScrollPane、JList、JTextArea、JPanel、JTree或JButton)放入相应的网格位置。例如,我希望能够从四个网格位置的四个JButton开始,然后将其中一个JPanel与一个JScrollPane交换,该JScrollPane中有一个JList,而内部组件不会更改外部组件的相对比率,即使内部组件中有一些文本或数据或其他内容。见下图 无论我如何努力实现它(使用GridBadLayout和一组约束),我都无法使网格线保持不变。如何使网格线保持在原位 到目前为止,我有如下的源代码:如何使四象限Java Swing GUI的侧面始终符合黄金比例?,java,swing,user-interface,layout,Java,Swing,User Interface,Layout,我想要一个有4个象限的矩形GUI。JFrame的高度与宽度之比(不包括最小化/最大化/关闭按钮)应为1:phi,其中phi等于黄金比例(约为1.62) 现在,对于JFrame中的四个象限。JFrame有一条水平分界线,将高度分为上下两部分。上部和下部高度之间的比率也应为φ1。最后,JFrame有一条垂直分界线,将宽度分成两部分,一部分是左侧,另一部分是右侧。左侧和右侧之间的比率也应为1:phi。见上图 现在,困难的部分来了。我希望这四个组件始终遵守比率,无论将哪个Swing组件(JScroll
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))
);
此外,无论我的尺寸有多小,它都不应该是这样:
您应该创建自己的。我认为您真正需要实现的唯一方法是layoutContainer。在此方法中,您可以使用指定的比率设置子组件(应为4)您可以使用
GroupLayout
为您完成工作
编辑:添加了交换按钮
例如:
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.event.ActionListener;
导入javax.swing.GroupLayout;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTree;
导入javax.swing.WindowConstants;
公共类测试扩展了JFrame{
公共静态最终双黄金分割率=1.618033987498948482;
公共静态最终双相对长度长边=1/黄金比例;
公共静态最终双相对长度(短边)=1-(1/黄金比例);
专用静态最终整数屏幕高度=500;
专用静态最终整型长度(长边的)整型长度(长边的)整型比率=(int)(屏幕高度*长边的相对长度);
私有静态最终整型长度(较短边的长度),对于整型比率=(int)(屏幕高度*较短边的相对长度);
专用静态最终int最小长度(长边的长度)(长边的相对长度);
私有静态最终int最小长度(短边的长度)(短边的相对长度);
公开考试(){
buildGUI();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(空);
}
私有void buildGUI(){
JPanel窗格=新的JPanel();
//制作网格布局
GroupLayout=新的GroupLayout(窗格);
窗格。设置布局(布局);
//制作4个组件以放置在四个网格空间中。
JButton filler1=新JButton(“按此处交换”);
JButton filler2=新JButton(“按此处交换”);
JButton filler3=新JButton(“按此处交换”);
Object[]objects=新对象[50];
对于(int i=0;i<50;i++){
对象[i]=“测试”+i;
}
JTree JTree=新的JTree(对象);
JScrollPane scrollPane=新的JScrollPane(jTree);
JButton button=新JButton(“按下此处进行交换”);
JPanel filler4=新的JPanel(新的BorderLayout());
填充4.添加(按钮);
ActionListener l=(e)->{
if(filler4.getComponents()[0]JButton实例){
填充物4.移除(按钮);
filler4.add(滚动窗格,BorderLayout.CENTER);
}否则{
填充4.移除(滚动窗格);
填充4.添加(按钮、边框布局、中心);
}
filler4.repaint();
filler4.revalidate();
};
filler1.addActionListener(l);
filler2.addActionListener(l);
filler3.addActionListener(l);
按钮addActionListener(l);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(填充1,长边的最小长度,长边的长度,短最大值)
.addComponent(填充物2,长边的最小长度,长边的长度,短最大值)
)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(填充物3,短边的最小长度,短边的长度,短边的最大值)
.addComponent(填充器4,较短侧的最小长度,较短侧的长度,较短侧的长度,较短最大值)
));
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(填充1,较短边的最小长度,较短边的长度,较短边的长度,最大值)
.addComponent(填充物3,短边的最小长度,短边的长度,短边的最大值)
)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
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);
});
}
}