在我的第一个程序重绘工作正常,但在第二个程序中我有一个问题。
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...
}
}
}
答案 0 :(得分:1)
在第一种情况下,从主线程调用function()
方法,因此当您调用sleep()时,此线程会休眠,这不会影响GUI的绘制。
在第二种情况下,从ActionListener调用function()
方法。从侦听器执行的所有代码都在事件调度线程(EDT)上调用,该线程负责重新绘制GUI。当你告诉Thread休眠()时,EDT会休眠,所以在循环完成执行之前它不能重新绘制GUI。
在ActionListener代码中,您需要启动一个单独的Thread。一种方法是使用SwingWorker
。
阅读Concurrency上的Swing教程中的部分以获取更多信息。
答案 1 :(得分:-1)
每次需要在JPanel类中使用实现Runnable时移动图像。这个类(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){}
如果您对线程一无所知,请点击链接进行了解:Thread in java tutorial