【问题标题】:Java repaint() not calling paintComponentJava repaint() 没有调用paintComponent
【发布时间】:2015-08-26 10:13:28
【问题描述】:

我正在尝试使用 repaint 来调用我的 paintComponent 方法,但它从未被调用过。这是我的第一堂课:

public class start
    {
    public static void main(String[] args){
        Frame f = new Frame();
        f.createFrame();
    }
}  

这是我希望调用paintComponent方法的类,但所发生的只是出现一个空白框:

import javax.swing.JButton;
import javax.swing.JComponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.Timer;

 public class newFrame implements Runnable,ActionListener
 {
JFrame window = new JFrame("Frame");
int i = 0;
Canvas myCanvas = new Canvas();
public void createFrame(){
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBounds(30, 30, 700, 500);
    window.setFocusable(true);
    window.setFocusTraversalKeysEnabled(false);
    window.setVisible(true);
    Thread t = new Thread(this);
    t.start();
}

public void run(){
    Timer timer = new Timer (17,this);
    timer.start();
}

public void actionPerformed(ActionEvent e){
    myCanvas.updateGame();
    myCanvas.render();
    window.add(myCanvas);
}
}

class Canvas extends JPanel{
int x = 10;
int y = 10;
public void updateGame(){
    x++;
}

public void render(){
    repaint();
    System.out.println("Output1");
}

@Override
protected void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g.drawString("hi",x,y);
    System.out.println("Output1");
}
}

Output1 打印多次,但 Output2 从未打印。为什么重绘没有调用paintComponent方法?

【问题讨论】:

  • 看起来你在这两个地方都有"Output1"...
  • 不太可能是您的问题,但是启动一个新线程只是为了创建一个摇摆计时器并在其上安排一个工作是非常奇怪的。只需在 createFrame 方法中创建并启动计时器。摆脱 Thread/Runnable 接口。
  • @River 是对的。这是正确的答案。你需要做的就是解决这个问题
  • 将 window.add(canvas) 移动到构造函数中,你不需要每秒执行 60 次
  • 您可以尝试在x=100y=100 上绘制您的String。有时左上角是看不见的。

标签: java graphics jframe jpanel repaint


【解决方案1】:

核心问题在于你的ActionListener...

public void actionPerformed(ActionEvent e){
    myCanvas.updateGame();
    myCanvas.render();
    window.add(myCanvas);
}

当您调用 window.add 时,JFrame 必须先删除 myCanvas 然后重新添加它,重新验证布局并安排重绘,所有这些都需要时间,同时,您我重复了这个过程,造成了框架根本跟不上你的情况。

相反,将window.add(myCanvas); 添加到构造函数中

public void createFrame() {
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBounds(30, 30, 700, 500);
    window.setFocusable(true);
    window.setFocusTraversalKeysEnabled(false);
    window.setVisible(true);
    window.add(myCanvas);
    Timer timer = new Timer(17, this);
    timer.start();
}

另外,根本不需要使用Thread 来启动Timer,这只是混淆了问题。

请注意,Java 已经有名为 FrameCanvas 的类,这可能会给一些开发人员(尤其是那些无权访问源代码的开发人员)带来额外的困惑

【讨论】:

    【解决方案2】:

    永远只打印了"Ouput1"。任何地方都没有"Output2"

    【讨论】:

    • 我看不到整个代码,我的“怀疑”是他们正在创建多个窗口,但没有显示正确的窗口
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多