java - 为什么我必须在每个paintComponent 上设置我的JLabel 的位置?
问题描述
我想在一个非常简单的环境中使用 JLabel,但我想知道为什么我必须在每次重绘时设置位置。
代码:
public class Example {
public static void main(String[] args) {
JFrame frame = buildFrame();
TestPane pane = new TestPane();
frame.add(pane);
while (true) {
pane.repaint();
frame.setVisible(true);
}
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(480, 272);
frame.setVisible(true);
return frame;
}
}
public class TestPane extends JPanel {
JLabel testLabel = new JLabel("TEST");
TestPane() {
super();
add(testLabel);
testLabel.setLocation(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
testLabel.setLocation(200, 200); // without this line, the label will always be at the top center
}
}
基于循环的布局来自我正在做的各种带有图像的动画。为什么重绘总是重置所有标签的位置,所以我必须在每个paintComponent上设置位置?
解决方案
为什么我必须在每次重绘时设置位置。
你没有。实际上,您永远不应该在paintComponent
方法内部设置组件的位置或任何类型的约束。paintComponent
方法仅用于绘画,不适用于定位或其他任何东西。
当你jpanel.add(myComponent, constraints)
的组件的位置将由容器当前的LayoutManager决定。(当您jpanel.add(myComponent);
没有任何约束时,将发生默认约束,每个布局管理器都有自己的默认值)。
标签放在面板的顶部是因为你没有设置面板的布局,所以它有它的默认值,即FlowLayout。为了改变它,你将不得不使用另一个具有适当约束的布局管理器。
例如,要将其放置在面板的中心,您必须执行以下操作:
jpanel.setLayout(new BorderLayout());
jpanel.add(myLabel,BorderLayout.CENTER);
最后在while(true)
运行 GUI 的线程内执行,它将挂起线程,这意味着 GUI 将被“冻结”,因为事件无法发生。
推荐阅读
- spring-data-jpa - 将特定查询转换为 JPQL 或 Criteria Builder 查询
- php - 将数据从 Excel 导入 MySQL,以不同语言显示文本
- java - 创建可以验证用户登录凭据请求的远程数据库
- html - 为什么我无法将“卡片”移动到屏幕中央
- python - float(export_entry.get()) AttributeError: 'NoneType' 对象没有属性 'get'
- ruby-on-rails - Heroku成功部署后如何自动运行Rails命令?
- angular - 如何在 Angular 7 的路由保护子句中访问路由参数?
- xamarin.android - OnCreateContextMenu 不适用于 webview
- c++ - 如何将内容数组写入文本文件?
- python - 如何在数据类上创建非字段实例级变量?