在实例化我修改过的JPanel
类时,我通过构造函数传入一个文件。后来在paint
方法中读取了文件(XML)并使用了数据。但是,在我解析数据之后,我同时调用repaint()
和revalidate()
,但我的GUI看起来完全一样。我在扩展JFrame
的主类和扩展JPanel
的面板类中调用这些方法。
当我从JFileChooser
中选择一个xml文件时,drawPanel
类会被其他构造函数实例化,接收文件并解析它,然后调用repaint
和{{1 }}。我省略了大部分代码以节省您的时间。
这里是主要班级'代码:
revalidate
这是我的drawPanel类:
public class myCode extends JFrame {
public myCode() {
super("Roadway Simulator");
setSize(800, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
drawie = new drawPanel();
drawie.setSize(new Dimension(width - 200, height));
drawie.setMinimumSize(new Dimension(width - 200, height));
drawie.setMaximumSize(new Dimension(width - 200, height));
drawie.setLocation(0, 0);
add(drawie);
setVisible(true);
try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}
}
public static void main(String[] args){new myCode();}
}
我的代码与上面相同,只是有更多细节。为什么我的JFrame重新粉刷?
答案 0 :(得分:4)
下面:
try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}
了解在Swing事件线程上调用时,Thread.sleep(...)
对Swing GUI的作用 - 它将恰好是Swing事件线程的当前线程(负责所有绘图和用户交互的线程)置于睡眠状态。换句话说,您将整个应用程序完全置于睡眠状态。
解决方案 - 不要在事件线程上调用永远。
顺便说一句,将每个方法调用放在自己的行上是没有成本的,没有理由你发布的那条长行没有任何目的,除了混淆。
答案 1 :(得分:4)
try{Thread.sleep(500);revalidate();repaint();}catch(InterruptedException eeee){}
最有可能阻止事件调度线程,阻止处理事件队列并使其看起来像程序已挂起。
有关详细信息,请参阅Concurrency in Swing ...
建议不要覆盖paint
的Swing组件,而是使用paintComponent
,有关详细信息,请参阅Performing Custom Painting
在您的情况下,我建议您使用javax.swing.Timer
代替Thread.sleep
,有关详细信息,请参阅How to use Swing Timers
<强>更新强>
我没有看到代码中的任何位置会将drawRoad
从false
更改为true
,因此您的paint
方法正在绘制...没有... 。所以我猜你的画框就像你告诉它的那样......
您可能还想看一下Initial Threads,您可能希望阅读Code Conventions for the Java TM Programming Language,这样可以让人们更轻松地阅读您的代码并让您阅读其他人< / p>
<强>更新强>
鉴于您的示例不完整且无法编译,当我重建它时,这将有效...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.w3c.dom.Document;
public class TestDraw extends JFrame {
public TestDraw() {
super("Roadway Simulator");
setSize(800, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel drawie = new DrawPanel(null);
add(drawie);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
new TestDraw();
}
});
}
class DrawPanel extends JPanel {
boolean drawRoad = false;
public DrawPanel() {
super();
}
public DrawPanel(Document doc) {
super();
drawRoad = true;
revalidate();
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (drawRoad) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
}
}
如果我将DrawPanel drawie = new DrawPanel(null);
更改为DrawPanel drawie = new DrawPanel();
,它仍然会进行绘制,但不会执行自定义绘画。
正如已经强调的那样,另一个问题是使用null
布局
避免使用null
布局,像素完美布局是现代ui设计中的一种幻觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的结束,您将花费越来越多的时间来纠正。
查看Why is it frowned upon to use a null layout in SWING?了解更多详情......
现在,说到这一点,当你添加drawie
时,你永远不会给它一个大小,Swing很聪明,不会画出0x0
大小的组件......