2011-01-09 3 views
5

У меня есть JPanel внутри рамки. Содержимое JPanel должно быть обновлено при каждом вызове paintComponent (который вызывается repaint()), но когда я делаю это, как показано ниже, я просто вижу белое окно. (Пожалуйста, простите за искаженные отступы, Eclipse делает все виды странных вещей с закладками.)Перекрашивание JPanel внутри рамки

private static void handleGUI() 
{  
    JFrame frame = new JFrame("Animation"); 
    frame.setPreferredSize(new Dimension(100, 100)); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    Board b = new Board(); 

    frame.getContentPane().add(b); 

    frame.pack(); 
    frame.setVisible(true); 

    while(true) 
    { 
     System.out.println("Repainting panel"); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
     } 
     b.repaint(); 
    } 
} 

public class Board extends JPanel 
{ 
public Board() { t=0; } 

    private int t; 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 

    ++t; 

    /* Variables snipped */ 

    g.setColor(Color.white); 
    g.drawOval(0, 0, width, height); 

    BufferedImage image = ImageIO.read(new File(imagePath)); 
    g.drawImage(image, x(t), y(t)); 
    /* There's some more image and rectangle drawing ahead */ 
} 

}

+2

На самом деле, Eclipse делает все виды классных вещей с вкладками. :-) Просто нажмите CTRL-SHIFT-F, чтобы автоматически форматировать исходный текст. Он будет создавать последовательное форматирование и отступы для вас, освобождая вас от бремени сделать это самостоятельно. – harschware

+0

Каковы значения для x (0), y (0)? Изображение может быть вне вашей панели. Запускаете ли вы его в отладчике? Код может генерировать исключение в потоке графического интерфейса, если ваш образ не найден. – josefx

ответ

6

У вас есть несколько проблем с кодом, упомянутый выше (1+ rep - хотя он выглядит так, как будто у вас есть код в вашем методе paintComponent, который выполняет рисование), ваш метод paintComponent ошибочен, но не только это, у вас есть цикл while (true) и Thread.sleep в главном потоке Swing, EDT, который заставит Swing и весь ваш графический интерфейс спать. Лучше использовать таймер Swing. Кроме того, вы заявляете,

Содержимое JPanel должны обновляться при каждом вызове paintComponent (который вызывается перекрашивать()),

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

Кроме того, вы никогда не хотите читать файл внутри метода paintComponent, так как это замедлит вашу картину до щелчка.

Я рекомендовал бы эти изменения:

1) Создание Свинг таймера с периодом 1000, а в методе actionPerformed ActionListener, читайте в изображении (желательно в фоновом потоке, если изображение имеет какие-либо существенное размер) и изображение читается в поле класса, например, называемое изображение.

2) В том же методе действия TimerPerformed, increment t.

3) После того, как изображение было прочитано, вызовите перерисовку на чертеже JPanel и нарисовате JPanel с помощью переменной изображения, чтобы нарисовать изображение. Будьте осторожны, если вы используете фоновый поток для чтения на изображении, так как вам нужно, чтобы этот поток уведомлял GUI, когда изображение было полностью прочитано. Если вы используете SwingWorker для этого, вы можете добавить PropertyChangeListener, который прослушивает на значение состояния SwingWorker и триггеры, когда это изменяется на StateValue.DONE.

Если что-либо из этого неясно или смущает, просьба уточнить.

Редактировать: если изображения не слишком велики, вы можете прочитать их все в одно время или сделать чтение партии, когда требуется связка. Нет абсолютно никакой необходимости читать изображения непосредственно перед их использованием.

1

ваш paintComponent просто вызывает super.paintComponent. Таким образом, JPanel, пока он нарисован сам, который будет светло-серым или белым или светло-коричневым или что-то в зависимости от вашего внешнего вида.

+0

Это, вероятно, белый, потому что его приложение заперлось, когда ложилось спать и не закончило все перекраски. – harschware

2

Не делайте нить спать. Используйте таймер качания, чтобы настроить события перерисовки.

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