为什么 super.repaint() 不调用 paint 方法?
Why does super.repaint() not call paint method?
解决方案:我需要将 JPanel 添加到 JFrame 中。 paint 方法的调用与 JFrame 的可见性绑定。 感谢@matt
这是我的第一个问题,如有遗漏,我深表歉意。
我的问题:
我想创建一个扩展 JPanel 的 class,以便我可以在我的 JFrame 上绘制内容。我也希望它能够重新粉刷自己。到目前为止,运行 方法有效,但 super.repaint() 无效。正在打印“test1”而“test2”没有。
提前致谢:)
public class Main {
public static GUI gui;
public static void main(String[] args) {
gui = new GUI();
}
}
public class GUI extends JFrame{
public Draw draw;
public Thread drawT;
public GUI() {
draw = new Draw();
drawT = new Thread(draw);
drawT.start();
}
}
public class Draw extends JPanel implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("test1");
super.repaint();
}
}
@Override
public void paint(Graphics graphics) {
System.out.println("test2");
Graphics2D g = (Graphics2D)graphics;
}
}
repaint
安排要绘制的组件。 如果组件不可见,则不会调用绘制。
一种简化的查看方式。 Swing/AWT 有 EventDispatchThread,它持续 运行s,处理事件和绘制组件。当您调用“repaint”时,它会告诉 swing 为您的组件安排一个绘制事件。它不叫油漆。当 EDT 找到它时,它会绘制您的组件。
在您的 'run' 方法中,您有一个循环将语句打印到终端“test1”,然后调用 repaint(),然后重复。这里最慢的是 System.out.println
.
你有一个非常快的循环淹没 AWT 重绘请求,但该循环 运行 比 EDT 循环 运行 绘制事件快。因此,在 EDT 实际执行一次绘制之前,您可能打印 test1 并调用 repaint 100 次。我怀疑如果你仔细观察,test2 被埋在你的输出中的某个地方。
import java.awt.*;
public class MainS{
int paints = 0;
int tags = 0;
public void runGui(){
JFrame frame = new JFrame("testing");
JPanel panel = new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
paints++;
}
};
frame.add(panel, BorderLayout.CENTER);
JLabel label = new JLabel("times painted ...");
frame.add(label, BorderLayout.NORTH);
frame.setSize(200, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Timer t = new Timer( 1000, evt->{
label.setText(paints + "/" + tags);
paints = 0;
tags = 0;
});
t.start();
new Thread( ()->{
while(true){
tags++;
panel.repaint();
}
}).start();
}
public static void main(String[] args){
EventQueue.invokeLater( new MainS()::runGui );
}
}
这是一个简单的示例,其中组件实际被重新绘制。它会在帧的顶部显示paintComponent被调用的次数和repaint被调用的次数。
解决方案:我需要将 JPanel 添加到 JFrame 中。 paint 方法的调用与 JFrame 的可见性绑定。 感谢@matt
这是我的第一个问题,如有遗漏,我深表歉意。
我的问题: 我想创建一个扩展 JPanel 的 class,以便我可以在我的 JFrame 上绘制内容。我也希望它能够重新粉刷自己。到目前为止,运行 方法有效,但 super.repaint() 无效。正在打印“test1”而“test2”没有。
提前致谢:)
public class Main {
public static GUI gui;
public static void main(String[] args) {
gui = new GUI();
}
}
public class GUI extends JFrame{
public Draw draw;
public Thread drawT;
public GUI() {
draw = new Draw();
drawT = new Thread(draw);
drawT.start();
}
}
public class Draw extends JPanel implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("test1");
super.repaint();
}
}
@Override
public void paint(Graphics graphics) {
System.out.println("test2");
Graphics2D g = (Graphics2D)graphics;
}
}
repaint
安排要绘制的组件。 如果组件不可见,则不会调用绘制。
一种简化的查看方式。 Swing/AWT 有 EventDispatchThread,它持续 运行s,处理事件和绘制组件。当您调用“repaint”时,它会告诉 swing 为您的组件安排一个绘制事件。它不叫油漆。当 EDT 找到它时,它会绘制您的组件。
在您的 'run' 方法中,您有一个循环将语句打印到终端“test1”,然后调用 repaint(),然后重复。这里最慢的是 System.out.println
.
你有一个非常快的循环淹没 AWT 重绘请求,但该循环 运行 比 EDT 循环 运行 绘制事件快。因此,在 EDT 实际执行一次绘制之前,您可能打印 test1 并调用 repaint 100 次。我怀疑如果你仔细观察,test2 被埋在你的输出中的某个地方。
import java.awt.*;
public class MainS{
int paints = 0;
int tags = 0;
public void runGui(){
JFrame frame = new JFrame("testing");
JPanel panel = new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
paints++;
}
};
frame.add(panel, BorderLayout.CENTER);
JLabel label = new JLabel("times painted ...");
frame.add(label, BorderLayout.NORTH);
frame.setSize(200, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Timer t = new Timer( 1000, evt->{
label.setText(paints + "/" + tags);
paints = 0;
tags = 0;
});
t.start();
new Thread( ()->{
while(true){
tags++;
panel.repaint();
}
}).start();
}
public static void main(String[] args){
EventQueue.invokeLater( new MainS()::runGui );
}
}
这是一个简单的示例,其中组件实际被重新绘制。它会在帧的顶部显示paintComponent被调用的次数和repaint被调用的次数。