2015-03-11 4 views
-4

В моей первой программе repaint работают по-разному, но во второй программе у меня есть проблема с ней.Почему 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.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... 
     } 

    } 

} 
+2

Добро пожаловать в StackOverflow. Не могли бы вы уточнить свою проблему? Что вы хотите сделать? Что он делает? Дополнительную информацию см. В [ask]. – Aify

+0

Это информация, которая должна идти в вопросе, а не комментарии. Пожалуйста, обновите свой вопрос. – Aify

+0

Не читайте изображения в методе рисования. Непросто постоянно читать изображение. Вы хотите, чтобы код рисования был как можно быстрее. – camickr

ответ

1

В первый случай метод function() вызывается из основного потока, поэтому, когда вы вызываете sleep(), этот Thread спит, что не влияет на рисование графического интерфейса.

Во втором случае ваш метод function() вызывается из ActionListener. Весь код, выполняемый из прослушивателя, вызывается в потоке отправки событий (EDT), который отвечает за перерисовку графического интерфейса. Когда вы сообщаете Thread to sleep(), EDT спит, поэтому он не может перерисовать GUI, пока цикл не завершит выполнение.

В коде ActionListener вам необходимо создать отдельную тему. Один из способов сделать это - использовать SwingWorker.

Для получения дополнительной информации ознакомьтесь с разделом из учебника Swing по телефону Concurrency.

-1

Чтобы переместить ваше изображение каждый раз, когда вам нужно использовать инструменты Runnable в классе 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){} 

Если вы не имеете ни малейшего представления о теме просто перейдите по ссылке, чтобы узнать его: Thread in java tutorial

+0

-1, Да, требуется отдельная тема. Однако не используйте метод getGraphics() для выполнения пользовательской раскраски. Пользовательская покраска выполняется путем переопределения метода paintComponent() и использования объекта Graphics, переданного методу. Метод run() должен ссылаться на repaint(). – camickr

+0

Я использовал getGraphics() для рисования пользовательской картины в методе run(), и моя программа была запущена/выполнена точно, и при этом я не сталкивался с какой-либо проблемой. –

+0

Код рисунка, который не выполнен в методе paintComponent(), не является стабильным. Возможно, он работает, пока Swing не решит, что ему нужно перекрасить() компонент. Например, попробуйте изменить размер вашего фрейма после завершения анимации. – camickr

Смежные вопросы