java - 使 BorderLayout 中的项目占用正确的大小
问题描述
我正在尝试制作一个简单的交通灯框架。这是由主框架制作的TrafficBox
:
public class TrafficBox extends JFrame {
public TrafficBox() {
setLayout(new BorderLayout(100,100));
add(new TrafficLight(Color.GREEN), BorderLayout.NORTH);
add(new TrafficLight(Color.ORANGE), BorderLayout.CENTER);
add(new TrafficLight(Color.RED), BorderLayout.SOUTH);
setBounds(100, 100, 800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TrafficBox();
}
});
}
然后如图所示,添加了 3 个TrafficLight
基于 的组件JPanel
,并具有以下代码:
public class TrafficLight extends JPanel {
private final int BALL_DIAMETER = 100;
private Color color;
public TrafficLight(Color color) {
//setSize(BALL_DIAMETER, BALL_DIAMETER);
this.color = color;
new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
}).start();
}
public void paintComponent(Graphics g) {
g.setColor(color);
g.fillOval(0, 0, BALL_DIAMETER, BALL_DIAMETER);
}
这确实是我想要的,它按预期绘制了所有 3 个圆圈,尽管大部分北(绿色)和南(红色)灯都被切断了。我认为这是因为北/南点比中心小得多。
我尝试使用setSize();
将面板的大小设置为圆圈的大小,但这不起作用。有没有办法可以使整个圆圈可见?
解决方案
因此,大多数布局管理器需要组件提供一些“提示”,以便了解它们想要如何布局。
您将需要覆盖getPreferredSize
并返回最符合您需求的尺寸,例如...
public class TrafficLight extends JPanel {
private final int BALL_DIAMETER = 100;
//...
public Dimension getPreferredSize() {
return new Dimension(BALL_DIAMETER, BALL_DIAMETER);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent();
g.setColor(color);
g.fillOval(0, 0, BALL_DIAMETER, BALL_DIAMETER);
}
此外,paintComponent
不需要public
任何人都应该调用它,并且您应该super.paintComponent()
在执行任何自定义绘画之前调用它。
我也建议使用GridLayout
这个
我还认为TrafficLight
不需要Timer
它自己的,应该从外部控制,但这就是我
setBounds(100, 100, 800, 600);
最好避免,用于pack()
将窗口大小调整为内容的首选大小并setLocation
定位它
推荐阅读
- database - F# - 依赖管理
- flutter - 如何在 SfCalendar 中同时允许范围选择和单一选择日期以及如何为不同颜色的日期着色?
- javascript - 如何在 Java Web 应用程序中阻止远程访问连接
- python - 如何处理剪影算法中的舍入问题?
- c# - Unity3D 新输入系统在行走时运行
- android - 图片未从 recyclerview 列表中过滤
- node.js - 快递应用程序中没有“访问控制允许来源”
- sympy - sympy:一个简单的符号方程解,然后用数字替换
- javascript - 为什么这两条等待线并行执行?
- c# - 保留来自“for循环”的用户输入的数据