2015-03-26 3 views
0

Я пытаюсь сделать программу, которая показывает анимацию о том, как цистерна заполняется со временем. Проблема в том, что я не могу заставить его обновляться каждый раз ... Вот код: It Works, но он не обновляется в цикле, но если я вручную изменю размер окна, я вижу, что в панели появилась новая краска:Dynamicically repaint Panel

static class _cistern extends JPanel{ 

    private volatile double _maxCapacity; 
    private double _flux; 
    private volatile double currentStorage = 0.0; 
    private boolean IsStarted = false; 
    private volatile int Up = 1; 

    private Thread Fill = new Thread(new Runnable(){ 
     @Override 
     public void run(){ 
      while(currentStorage < _maxCapacity){ 
       currentStorage += _flux; 
       try{Thread.sleep(500);}catch(Exception ex){} 
       repaint(); 
      } 
     } 
    }); 

    public _cistern(double MaximunCapacity, double Flux, double CurrentStorage){ 
     setPreferredSize(new Dimension(800, 600)); 
     setBackground(Color.BLACK); 
     IsStarted = true; 
     Fill.start(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(Color.WHITE); 
     g2.drawOval(getWidth()/20, getHeight()/15, getWidth() - getWidth()/10, getHeight() - getHeight()+20); 
     g2.drawLine(getWidth()/20, getHeight()/15+10, getWidth()/20, (getHeight() - getHeight()/15)-10); 
     g2.drawOval(getWidth()/20, (getHeight() - getHeight()/15 - 20), getWidth() - getWidth()/10, getHeight() - getHeight()+20); 
     g2.drawLine(getWidth() - getWidth()/20, getHeight()/15 +10, getWidth() - getWidth()/20, (getHeight() - getHeight()/15)-10); 

     if(IsStarted){ //I know I have some drawings wrong here 
         //I can fix them but I just want this to refresh dinamically. The problema is the REFRESH PAINT. 
         //If you test code and see bad drawing, that's not the problema, I want to see it refreshing :P, that's the question. Don't fix this 
      g2.setColor(Color.BLUE); 
      g2.drawOval(getWidth()/20, (getHeight() - getHeight()/15 - 20) - Up++, getWidth() - getWidth()/10, getHeight() - getHeight()+20 - Up++); 

      g2.drawLine(getWidth()/20, (getHeight() - getHeight()/15)-10, getWidth()/20, (getHeight() - getHeight()/15)-10); 
      g2.drawLine(getWidth() - getWidth()/20, getHeight()/15 +10, getWidth() - getWidth()/20, (getHeight() - getHeight()/15)-10); 

      g2.drawOval(getWidth()/20, (getHeight() - getHeight()/15 - 20), getWidth() - getWidth()/10, getHeight() - getHeight()+20); 
     } 

    } 

} 

спасибо: P

+1

использование Swing 'Timer' вместо' Thread', это безопаснее ... – MadProgrammer

+0

Вам может понравиться прочитать [Условные обозначения для Jav язык программирования TM] (http://www.oracle.com/technetwork/java/codeconvtoc-136057.html), это упростит для людей возможность читать ваш код и читать дальше. – MadProgrammer

+1

Не изменяйте состояние вашего компонента из метода 'paintComponent', живопись - для рисования. 'paintComponent' может быть вызван по нескольким причинам, что приводит к непредсказуемым результатам. – MadProgrammer

ответ

0

Через некоторое время, глядя на мой код, я вспомнил, я использую тему позвонить и EDT ... Так что я просто должен был добавить это:

private Thread Fill = new Thread(new Runnable(){ 
     @Override 
     public void run(){ 
      while(currentStorage < _maxCapacity){ 
       currentStorage += _flux; 
       try{Thread.sleep(500);}catch(Exception ex){} 
       SwingUtilities.invokeLater(new Runnable(){ 
       public void run(){ 
       revalidate(); 
       repaint(); 
       } 
       }); 
      } 
     } 
    }); 
+0

'repaint' является, одним из немногих, потокобезопасных методов в Swing. 'revalidate' не имеет значения в вашем случае, это вы не пытаетесь обновить макет иерархии контейнеров. – MadProgrammer

+0

@MadProgrammer Возможно. Мне нужно было использовать Thread, а не таймер, потому что это была простая домашняя работа. Мне не нравится java, но мне все равно нужно это узнать, полезно узнать немного всего, что вы можете. Я знаю, что «плохо» использовать перерисовку, но, как сказано, перерисовка лучше в постоянных и быстрых обновлениях (мой цикл ORIGINAL делает 10 обновлений в секунду, а не 500 мс в этом примере), я должен использовать его вместо Обновить(). Спасибо в любом случае^_^!! –