#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:
- Вы никогда не запускаете поток
imagerunner
. - Он назначается дважды (без причины).
- Вы не можете изменить графический интерфейс из другого потока. Используйте для этого утилиты Swing.
Ответ №2:
waiting()
Метод, похоже, блокирует EDT. Было бы лучше использовать Swing Timer
для планирования обновлений.
Комментарии:
1. Я не уверен, что это блокирует EDT, поскольку он, кажется , вызывается в отдельном потоке (метод Runnable run), но мы никогда не видим, как он запускает поток, поэтому трудно сказать, правильно ли он это делает.
2. @Судно на воздушной подушке, полное угрей: Возможно, вы правы, я еще немного подумаю, как только OP опубликует SSCCE.
3. Вы правы! От Java у меня болит голова, и я не совсем уверен, почему вы правы, но замена ее на Таймер устранила проблему. Однако я надеялся, что задержки будут переменной длины, а таймер имеет фиксированную задержку. Есть ли какой-либо способ сделать его переменным? На данный момент я просто собираюсь установить короткую задержку и заставить изображения повторяться, но я полагаю, что, вероятно, есть более гибкое решение. * редактировать: да, и, кстати, СПАСИБО.
4. @John M — не забудьте «принять» ответ, когда предложения решат проблему.
Ответ №3:
Вам нужно будет выполнить следующее:
1) Фактически создайте экземпляр для запуска. 2) Вам нужно будет регулярно вызывать repaint (), чтобы перекрасить ваш дисплей.
Надеюсь, это поможет. Приветствия!