Java 为什么repaint()不总是有效?

Java 为什么repaint()不总是有效?,java,swing,repaint,Java,Swing,Repaint,在我的第一个程序中,重新绘制工作正常,但在第二个程序中,我有一个问题 import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing

在我的第一个程序中,重新绘制工作正常,但在第二个程序中,我有一个问题

    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;

    public class repaint1 {

        public static void main(String[] args) {
            JFrame win = new JFrame("");
            test1 content = new test1();
            win.setContentPane(content);
            win.setSize(600, 400);
            win.setLocation(100, 100);
            win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            win.setResizable(false);
            win.setVisible(true);
            content.function();

        }

    }

    class test1 extends JPanel {

        private BufferedImage img;

        public int x = 50;
        public int y = 50;

        public test1() {

        }

        public void function() {

            try {

                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }

            for (int i = 50; i < 150; i++) {
                x = i;
                y = i;

                try {

                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }

                repaint();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            try {
                img = ImageIO.read(new File("images.jpg"));
                g.drawImage(img, x, y, null); 

            } catch (IOException ex) {
                // handle exception...
            }

        }

    }



import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class repaint2 {

    public static void main(String[] args) {

        JFrame f = new JFrame("JFrame");
        test2 content = new test2();
        f.setContentPane(content);
        f.setSize(600, 400);
        f.setLocation(100, 100);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setResizable(false);
        f.setVisible(true);

    }

}

class test2 extends JPanel {

    private BufferedImage img;

    public int x = 50;
    public int y = 50;

    public test2() {

        JButton button = new JButton("Start !");
        button.setBounds(458, 24, 122, 23);
        button.setVisible(true);
        add(button);

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                // Execute when button is pressed

                function();

            }

        });

    }

    public void function() {

        for (int i = 50; i < 150; i++) {

            x = i;
            y = i;

            repaint();

            try {

                Thread.sleep(10);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }

        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        try {
            img = ImageIO.read(new File("images.jpg"));
            g.drawImage(img, x, y, null);

        } catch (IOException ex) {
            // handle exception...
        }

    }

}
导入java.awt.Graphics;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类重新绘制1{
公共静态void main(字符串[]args){
JFrame win=新JFrame(“”);
test1 content=newtest1();
win.setContentPane(内容);
win.setSize(600400);
win.setLocation(100100);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setresizeable(false);
win.setVisible(true);
content.function();
}
}
类test1扩展了JPanel{
专用缓冲图像img;
公共整数x=50;
公共int y=50;
公共测试1(){
}
公共空间功能(){
试一试{
睡眠(1000);
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}
对于(int i=50;i<150;i++){
x=i;
y=i;
试一试{
睡眠(10);
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}
重新油漆();
}
}
@凌驾
受保护组件(图形g){
超级组件(g);
试一试{
img=ImageIO.read(新文件(“images.jpg”);
g、 绘图图像(img,x,y,null);
}捕获(IOEX异常){
//处理异常。。。
}
}
}
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.FocusEvent;
导入java.awt.event.FocusListener;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.Timer;
公共类重新绘制2{
公共静态void main(字符串[]args){
JFrame f=新JFrame(“JFrame”);
test2 content=newtest2();
f、 setContentPane(内容);
f、 设置大小(600400);
f、 设置位置(100100);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 可设置大小(假);
f、 setVisible(真);
}
}
类test2扩展了JPanel{
专用缓冲图像img;
公共整数x=50;
公共int y=50;
公共测试2(){
JButton按钮=新JButton(“开始!”);
按钮.立根(458,24,122,23);
按钮。设置可见(真);
添加(按钮);
addActionListener(新建ActionListener()){
已执行的公共无效操作(操作事件e){
//按下按钮时执行
函数();
}
});
}
公共空间功能(){
对于(int i=50;i<150;i++){
x=i;
y=i;
重新油漆();
试一试{
睡眠(10);
}捕获(中断异常例外){
Thread.currentThread().interrupt();
}
}
}
@凌驾
公共组件(图形g){
超级组件(g);
试一试{
img=ImageIO.read(新文件(“images.jpg”);
g、 绘图图像(img,x,y,null);
}捕获(IOEX异常){
//处理异常。。。
}
}
}

每次需要在JPanel类中使用可运行的实现时移动图像。在这里,这个类(
MyJPanleClass
)的行为类似于JPanel和Thread

public class MyJPanleClass extends JPanel implements Runnable{

   public MyJPanleClass(){
      //constractor
   }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        //do your staff with g
    }

    @Override
    public void run(){
       repaint();
    }

}
要从主类执行它,只需编写以下代码:

MyJPnaleClass jp=new MyJPanelClass();
Thread t1=new Thread(jp);
t1.start();//this will call run class
try{
t1.join();//running the thread until it finish. 
}catch(Exception ex){}

如果您对线程没有任何概念,只需按照链接学习即可:

在第一种情况下,从主线程调用
函数()
方法,因此当您调用sleep()时,此线程将休眠,这不会影响GUI的绘制

在第二种情况下,将从ActionListener调用
函数()
方法。从侦听器执行的所有代码都在事件调度线程(EDT)上调用,该线程负责重新绘制GUI。当您告诉线程sleep()时,EDT将休眠,因此在循环完成执行之前,它无法重新绘制GUI

在ActionListener代码中,您需要启动一个单独的线程。一种方法是使用
SwingWorker


有关更多信息,请阅读上Swing教程的部分。

欢迎使用StackOverflow。关于你的问题,你能更具体一点吗?你想让它做什么?它在干什么?有关更多信息,请参阅。这是问题中应该包含的信息,而不是评论。请更新您的问题。不要使用绘画方法阅读图像。持续读取图像不是很有效。您希望绘制代码尽可能快。-1,是的,需要单独的线程。但是,不要使用getGraphics()方法进行自定义绘制。自定义绘制是通过重写paintComponent()方法并使用传递给该方法的图形对象来完成的。run()方法应该调用repaint()。我使用getGraphics()在run()方法中绘制自定义绘制,并且我的程序运行/执行得很好,在执行此操作时没有遇到任何问题。在paintComponent()方法中未完成的绘制代码不稳定。在Swing决定需要重新绘制()组件之前,它可能会一直工作。例如,在动画完成后尝试调整帧的大小。所以,我需要在run()方法中执行repaint(),在paintComponent()方法中执行所有人员?或者在我的图形项目中使用SwingUtilities.invokeLater?哪一个更好