Проблемы с перерисовкой в выполняемой JPanel

#java #repaint #paintcomponent

#java #перерисовка #компонент paint

Вопрос:

Я пишу программу, которая будет воспроизводить песню, и во время нее JPanel будет отображать изображения. Песня воспроизводится нормально, первое изображение нарисовано (я предполагаю, что из первоначального вызова paintComponent), но почему-то repaint (), похоже, не вызывается. Мне действительно не помешал бы дополнительный набор глаз. У меня есть приведенный ниже код для класса JPanel, который будет отображать изображения. Большое спасибо!

 class pictures extends JPanel implements Runnable {
private ImageIcon images[];
private Thread imagerunner;
private int currentImage;

pictures() {
    super();
    imagerunner = new Thread(this);
    images = new ImageIcon[6];
    imagerunner = new Thread(this);
    images[0] = new ImageIcon("pic1.jpg");
    images[1] = new ImageIcon("pic2.jpg");
    images[2] = new ImageIcon("pic3.jpg");
    images[3] = new ImageIcon("pic4.jpg");
    images[4] = new ImageIcon("pic5.jpg");
    images[5] = new ImageIcon("pic6.jpg");
    currentImage = 0;
}

public void run() {
    int i = 0;
    System.out.println("starting pics");
    while( i < 100 ) {
        System.out.println("about to repaint()");
        this.repaint();
        System.out.println( "image: "   currentImage );
        waiting( 2000 );
        currentImage  ;
    }
    System.out.println("done");
}

public void paintComponent( Graphics g ) {
    super.paintComponent( g );
    System.out.println("repainting");
    images[ currentImage ].paintIcon(this,g,0,0);
}

public static void waiting (int n) {
    long t0, t1;
    t0 =  System.currentTimeMillis();
    do{
        t1 = System.currentTimeMillis();
    }
    while (t1 - t0 < n);
}
}
  

Комментарии:

1. как вы вызываете код этого класса? Где вы вызываете start () в своем потоке?

2. Чтобы быстрее получить более качественную помощь, отправьте SSCCE . Кстати — что, по вашим ожиданиям, произойдет, когда currentImage счетчик достигнет 6?

Ответ №1:

  1. Вы никогда не запускаете поток imagerunner .
  2. Он назначается дважды (без причины).
  3. Вы не можете изменить графический интерфейс из другого потока. Используйте для этого утилиты Swing.

Ответ №2:

waiting() Метод, похоже, блокирует EDT. Было бы лучше использовать Swing Timer для планирования обновлений.

Комментарии:

1. Я не уверен, что это блокирует EDT, поскольку он, кажется , вызывается в отдельном потоке (метод Runnable run), но мы никогда не видим, как он запускает поток, поэтому трудно сказать, правильно ли он это делает.

2. @Судно на воздушной подушке, полное угрей: Возможно, вы правы, я еще немного подумаю, как только OP опубликует SSCCE.

3. Вы правы! От Java у меня болит голова, и я не совсем уверен, почему вы правы, но замена ее на Таймер устранила проблему. Однако я надеялся, что задержки будут переменной длины, а таймер имеет фиксированную задержку. Есть ли какой-либо способ сделать его переменным? На данный момент я просто собираюсь установить короткую задержку и заставить изображения повторяться, но я полагаю, что, вероятно, есть более гибкое решение. * редактировать: да, и, кстати, СПАСИБО.

4. @John M — не забудьте «принять» ответ, когда предложения решат проблему.

Ответ №3:

Вам нужно будет выполнить следующее:

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

Надеюсь, это поможет. Приветствия!