【问题标题】:paintComponent method not being called by repaint重绘未调用paintComponent方法
【发布时间】:2015-06-10 17:30:34
【问题描述】:

我正在尝试使用 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 Frame 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);
    (new Thread(new Frame())).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("repaint");
}

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

}

Repaint 被多次调用,但从不调用paint。为什么重绘没有调用paintComponent方法?

【问题讨论】:

    标签: java graphics jframe jpanel repaint


    【解决方案1】:

    我没有创建新框架,而是传入现有框架,我在下面的行中注释了:

    public void createFrame(){
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setBounds(30, 30, 700, 500);
        window.setFocusable(true);
        window.setFocusTraversalKeysEnabled(false);
        window.setVisible(true);
        (new Thread(new Frame())).start(); <--- instead of creating a new frame, pass in the existing frame
    }
    

    您还应该真正考虑以下改进:

    1) 不要将您的班级命名为 Frame,因为它会与 Frame 冲突

    2) 移动createFrame的正文以及以下三行:

    JFrame window = new JFrame("Frame");
    int i = 0;
    Canvas myCanvas = new Canvas();
    

    进入构造函数,并将这些局部变量(如Canvas)放入成员字段中。

    3) 从构造函数中删除创建线程的最后一行,并将其公开为方法(例如“startAnimation”)并在创建对象后调用它。

    编辑:

    试试这个:

    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
        public class Frame implements Runnable, ActionListener
        {
            final JFrame window;
            final Canvas myCanvas;
    
            public Frame(){
                this.window = new JFrame("Frame");
                this.myCanvas = new Canvas();
                this.window.add(this.myCanvas);
                this.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                this.window.setBounds(30, 30, 700, 500);
                this.window.setFocusable(true);
                this.window.setFocusTraversalKeysEnabled(false);
                this.window.setVisible(true);
            }
    
            public void startApp() {
                final Thread t = new Thread(this);
                t.start();
            }
    
            public void run(){
                final Timer timer = new Timer (1000,this);
                timer.start();
            }
    
            public void actionPerformed(ActionEvent e){
                myCanvas.updateGame();
                window.repaint();
            }
    
            public static void main(String[] args) {
                final Frame f = new Frame();
                f.startApp();
            }
        }
    
        class Canvas extends JPanel {
            int x = 10;
            int y = 10;
            public void updateGame() {
                x++;
            }
    
            @Override
            protected void paintComponent(Graphics g){
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;
                g.drawString("hi", this.x, this.y);
                System.out.println("paint");
            }
        }
    

    【讨论】:

    • 我改变了 (new Thread(new Frame())).start();到线程 t = new Thread(this); t.start();但是repaint方法仍然没有调用paintComponent,你知道为什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多