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?哪一个更好