2013-03-26 2 views
1

У меня есть проект пинг-понга (типа), и он работает, но есть проблема в функции run(). если я нарисую кадр с функциями, которые я написал на панели (они работают, я проверял), это создает проблему с графикой, и если я использую перерисовку (как я ее довожу), она рисует кадр и немедленно удаляет его, каждое решение поможет (лучше просто один на уровне моего кода):repaint - сразу же покраска и удаление

import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JPanel; 
import java.util.Random; 
import javax.swing.*; 
import sun.org.mozilla.javascript.internal.Kit; 



public class Picture extends JPanel implements MouseListener, Runnable{ 

    private int k = 0; 
    Thread MyThread; 
    private DrawPic img; 

    private Rectangle r1, r3; 

    public Picture(DrawPic img, Rectangle rect1, Rectangle rect3) { 
     super(); 
     this.setLocation(0, 85); 
     this.setLayout(new FlowLayout()); 
     this.setSize(1280, 1024); 

     this.addMouseListener(this); 
     this.setFocusable(true); 

     this.r1 = rect1; 

     this.r3 = rect3; 
     this.img = img; 
     this.MyThread = new Thread(this); 
     MyThread.start(); 
     this.setVisible(true); 

    } 




    public void paintRectangleL(Rectangle rect, Graphics g) { 
     k = 3; 

     rect.DrawRectangle(g); 
     rect.FillRectangle(g); 


    } 
    public void paintRectangleR(Rectangle rect, Graphics g) { 
     k = 1; 

     rect.DrawRectangle(g); 
     rect.FillRectangle(g); 

    } 
    public void paintImage(DrawPic img, Graphics g) { 
     k = 2; 

     //g.clearRect(0, 0, this.getWidth(), this.getHeight()); 
     img.DrawImg(g, this); 



    } 
    public void changeK(int k1){ 
     k = k1; 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     // throw new UnsupportedOperationException("Not supported yet."); 



    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     //throw new UnsupportedOperationException("Not supported yet."); 

      Point p = r3.FindCenter(); 
      double dx, dy; 

      dy = e.getY() - p.getY(); 
      r3.Move(0, dy); 
       this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight()); 
      this.paintRectangleL(r3, this.getGraphics()); 
      this.paintRectangleR(r1, this.getGraphics()); 
      this.paintImage(img, this.getGraphics()); 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     //throw new UnsupportedOperationException("Not supported yet."); 

    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
     //throw new UnsupportedOperationException("Not supported yet."); 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     // throw new UnsupportedOperationException("Not supported yet."); 
    } 
    public void animate(){ 
     double dx = 0, dy = 2; 
     if ((this.img.getX() + 160 + this.r1.RightPoint().getX() - this.r1.LeftPoint().getX() > this.getWidth() || this.img.getX() < this.r3.RightPoint().getX() - this.r3.LeftPoint().getX())) { 
        dx = -1 * dx; 


       } 
       if (this.img.getY() + 120> this.getHeight() || this.img.getY() < 0) { 
        dy = -1 * dy; 
       } 
       img.Move(dx, dy); 
      // this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight()); 
       // this.paintImage(img, this.getGraphics()); 
       // this.paintRectangleL(r3, this.getGraphics()); 
       // this.paintRectangleR(r1, this.getGraphics()); 
       repaint();    
    } 

    @Override 
    public void run() { 

     Color col; 
     while (true) { 
       animate(); 

       try { 
        MyThread.sleep(35); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(Picture.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
     // throw new UnsupportedOperationException("Not supported yet."); 
    } 
+1

Возможно, вам захочется переопределить 'paintComponent()' и добавить туда всю свою картину. 'paintComponent' будет иметь аргумент Graphics, который вы можете использовать (вместо вызова' getGraphics() '), и он будет автоматически вызван из' repaint() '. – SeKa

ответ

5

Вы не должны использовать getGraphics() для пользовательских живописи, как это временный буфер, который возвращают на следующий перекрашивать. Вы рисуете в paintComponent().

Для получения дополнительной информации и примеров см. Performing Custom Painting. Раздел A Closer Look at the Paint Mechanism имеет хорошее резюме методов paint() и paintComponent(). Также см. Painting in AWT and Swing.

EDIT:

Логика и структура вашей программы не подходит процесс окраски Свинг. Вам нужно реорганизовать свою программу, чтобы она могла подключаться к этому процессу и рисовать нужные вещи в нужное время. Обычно вы настраиваете компонент, переопределяя его paintComponent(). В этом методе происходит вся картина. Этот метод должен быть как можно более быстрым, избегая использования какой-либо/слишком большой логики приложения.

Вы должны поддерживать какое-то состояние окрашенных объектов (то есть координат, цветов и т. Д.), Как только состояние изменяет вопрос repaint(). Это будет запланировать перерисовку, и в итоге Swing выполнит paint() на компоненте, который будет вызывать paintComponent().

В этом случае у вас есть таймер, который периодически срабатывает. Вы можете переопределить paintComponent из JPanel, который вы используете. У вас уже есть логика, которая выполняет вычисления координат. Храните эти координаты в переменных-членах. Затем введите repaint(). В paintComponent нарисуйте изображение на основе вычисленных координат.

EDIT:

Еще одно замечание на нитях. Swing имеет модель с одной резьбой. Все взаимодействие и живопись UI ведется на Swing's Event Dispatch Thread (EDT). Посмотрите на Concurrency in Swing для получения дополнительной информации об EDT. Обратите внимание, что метод animate() не выполнен на EDT. Вы не показали, что делает img.Move(dx, dy), но, вероятно, это небезопасно, чтобы быть выполненным таким образом. invokeLater может помочь здесь, чтобы код был выполнен на EDT. Однако в этом конкретном случае может быть проще использовать Swing timers, которые гарантируют, что действия будут выполняться по EDT.

+0

Например, см. Пример [this] (http://stackoverflow.com/a/12336475/1048330), который перемещает изображение по таймеру. – tenorsax

+0

Извините за незнание java, но не могли бы вы дать что-нибудь более ясное? – TJR

+0

@ user2213455 см. Edit, также см. Связанный пример. – tenorsax

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

  • Нет связанных вопросов^_^