Java中以相同比例调整框架和控件





0/5 (0投票)
本文介绍如何在Java中自动调整框架及其控件的大小,使其保持相同的比例。
引言
我在布局管理器中缺失的一点是,让控件能够自动调整大小,并且调整比例与框架调整大小的比例相同。这意味着如果用户将框架的宽度加倍,那么所有控件的宽度,甚至它们之间的距离,都将变为初始宽度的两倍。我为此创建了一个快速可移植的解决方案。虽然它可能不完美,但我认为它作为一个起点是“足够好的”。无论如何,我只是一个业余爱好者,我认为发布它不会有坏处,因为有人可能会觉得它有用。
背景
我创建了一个 HierarchyBoundsListener 类,执行自动调整大小的过程。然后应该将该类添加到面板以使其生效。
使用代码
关于这个类没什么好说的,代码可以直接复制粘贴到名为“test”的应用程序中。
/* Warning! This listener should be added AFTER the panel with all
its components have been created and added.
Note: Several successive resizings may change significantly the sizes of the
components due to the accumulated rounding errors. */
package test;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import javax.swing.JPanel;
/**
*
* @author Bilal Gharib
*/
public class ResizeComponentsListener implements HierarchyBoundsListener {
private int InitialPaneWidth;
private int InitialPaneHeight;
private double InitialArea;
private final boolean ResizeFont;
public ResizeComponentsListener(
int InitialPaneWidth, int InitialPaneHeight, boolean ResizeFont) {
this.InitialPaneWidth = InitialPaneWidth;
this.InitialPaneHeight = InitialPaneHeight;
this.InitialArea = InitialPaneWidth * InitialPaneHeight;
this.ResizeFont = ResizeFont;
}
@Override
public void ancestorMoved(HierarchyEvent e) {
// not used
}
@Override
public void ancestorResized(HierarchyEvent e) {
JPanel Panel = (JPanel)e.getSource();
double RatioX = (double)Panel.getWidth() / InitialPaneWidth;
double RatioY = (double)Panel.getHeight() / InitialPaneHeight;
double CurrentArea = Panel.getWidth() * Panel.getHeight();
double RatioArea = (double)CurrentArea / InitialArea;
double NewX, NewY, NewWidth, NewHeight, NewFontSize;
Font NewFont;
for(Component c : Panel.getComponents()){
NewX = c.getX() * RatioX;
NewY = c.getY() * RatioY;
NewWidth = c.getWidth() * RatioX;
NewHeight = c.getHeight() * RatioY;
c.setLocation((int)Math.round(NewX), (int)Math.round(NewY));
c.setSize((int)Math.round(NewWidth), (int)Math.round(NewHeight));
if (ResizeFont){
NewFontSize = c.getFont().getSize() * RatioArea;
NewFont = c.getFont().deriveFont((float)Math.round(NewFontSize));
c.setFont(NewFont);
}
}
this.InitialPaneWidth = Panel.getWidth();
this.InitialPaneHeight = Panel.getHeight();
this.InitialArea = CurrentArea;
}
}
以下是使用该类的“test”程序的完整代码。它包含一个 JFrame 和一些控件。最后一行将 ResizeComponentsListener 附加到 JFrame。
package test;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.BorderFactory;
import javax.swing.SwingConstants;
public class Test {
public static void main(String[] args) {
JFrame f = new JFrame("Java JFrame!");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(500, 300);
f.setLocation(250, 150);
f.getContentPane().setLayout(null);
Font fnt = new Font("Tahoma", Font.BOLD, 18);
JLabel l1 = new JLabel("L");
l1.setHorizontalAlignment(SwingConstants.CENTER);
l1.setHorizontalAlignment(SwingConstants.CENTER);
l1.setBorder(BorderFactory.createLineBorder(Color.black));
l1.setBounds(10, 10, 100, 70);
l1.setFont(fnt);
JButton b1 = new JButton("B1");
b1.setFont(fnt);
b1.setBounds(120, 10, 100, 70);
JButton b2 = new JButton("B2");
b2.setFont(fnt);
b2.setBounds(390, 10, 100, 70);
JButton b3 = new JButton("B3");
b3.setFont(fnt);
b3.setBounds(390, 90, 100, 70);
f.add(l1);
f.add(b1);
f.add(b2);
f.add(b3);
f.setVisible(true);
f.getContentPane().addHierarchyBoundsListener(
new ResizeComponentsListener(500, 300, true));
}
}
关注点
请注意,调整字体大小是可选的,它作为布尔值传递给构造函数。正如警告所述,应该在创建所有控件并将其添加到 JFrame 后添加此监听器。另请注意,该监听器不适用于 JFrame 内部面板中的控件。
希望这能有所帮助。欢迎提出任何建议。