2017-02-16 3 views
0

Перерисовать не называет PaintComponent.
Я попытался вызвать его из другого метода класса Try, но это не сработало.repaint не вызывает paintComponent

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 

public class Try extends JPanel { 
    int i =0; 

    @Override 
    public void paintComponent(Graphics g){ 
     //super.paintComponent(g); 
     System.out.println("hey"); 
    } 

    public static void main(String[] args) { 
     JFrame f=new JFrame(); 
     Try t = new Try(); 
     f.setSize(500,600);//400 width and 500 height 

     Container contentPane = f.getContentPane(); 
     contentPane.add(new PaintComponent()); 
     f.setVisible(true);//making the frame visible 

     while(true){ 
      t.repaint(); 
     } 
    } 
} 
+5

Возможно, вы имели в виду 'contentPane.add (new Try())'. Кроме того, _don't_ блокирует EDT; _do_ см. [* Параллельность в Swing *] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) и [* Использование таймеров Swing *] (http://docs.oracle.com/ JavaSE/учебник/uiswing/разное/timer.html). – trashgod

+0

И не удаляйте строку 'super.paintComponent()', следуйте инструкциям [Учебное пособие по рисованию Swing] (https://docs.oracle.com/javase/tutorial/uiswing/painting/step1.html), чтобы узнать, как он работает – Frakcool

ответ

0

Существует несколько проблем, некоторые из которых упоминаются в комментариях @trashgod.

  1. Вы звоните перекрашивать на экземпляре, который Вы не добавили к панели контента - у вас есть другой один там (на самом деле, у вас есть что-то совершенно другое там - new PaintComponent()).

  2. Не удаляйте super.paintComponent (g);, если вы не очистите область самостоятельно (достаточно заполнить весь фон компонента, если он непрозрачен), иначе вы получите визуальные сбои на таких компонентах после перерисовки.

  3. Вы занимаетесь рассылкой спама, что очень плохо, сделайте хотя бы некоторую задержку между репайнами, дающими время Swing, чтобы выполнить перекраски. Лучше всего, если вы перекрашиваете компонент только тогда, когда на нем будет отображаться что-то другое визуально. Если вам нужно обновлять представление все время - по крайней мере, ограничивать его до 30-60 кадров (переименование) в секунду. Кроме того, некоторые внутренние оптимизации Swing могут «съесть» некоторые вызовы перерисовки, поэтому ожидайте, что вы можете не увидеть столько звонков paintComponent, сколько количества обращений, которые вы вызываете для компонента.

  4. Вы работаете с компонентами Swing вне темы «Диспетчер событий» (в скором времени EDT), что может вызвать проблемы. Убедитесь, что вы всегда используете его для создания компонентов Swing и вызова любых методов на них. SwingUtilities помогает с этим.

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

Учитывая все сказанное выше, я, это, как ваш пример должен выглядеть следующим образом:

public class Try extends JPanel 
{ 
    @Override 
    public void paintComponent (final Graphics g) 
    { 
     super.paintComponent (g); 

     final Graphics2D g2d = (Graphics2D) g; 
     g2d.drawString (Long.toString (System.currentTimeMillis()), 25, 35); 

     System.out.println ("repainted"); 
    } 

    public static void main (final String[] args) 
    { 
     SwingUtilities.invokeLater (new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       final JFrame f = new JFrame(); 

       final Try t = new Try(); 
       f.getContentPane().add (t); 

       f.setSize (500, 600); 
       f.setVisible (true); 

       new Thread (new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         try 
         { 
          while (true) 
          { 
           t.repaint(); 
           Thread.sleep (25); 
          } 
         } 
         catch (final InterruptedException e) 
         { 
          // 
         } 
        } 
       }).start(); 
      } 
     }); 
    } 
} 

Надеется, что проясняет это немного для вас.

Существует также класс SwingWorker, который помогает выполнять длительные задачи в Swing, но я не использовал его здесь, чтобы привести пример как можно более простым.

Также примечание стороны - вам не нужно звонить repaint() в пределах EDT, потому что он отправляет запрос перерисовки на EDT самостоятельно, поэтому этот метод безопасен для использования в любом потоке (как в примере).

+0

Спасибо за пример @Mikle – kev

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