Ошибка с таймером и JFrame

Я делаю игру с таймером и JFrame (и многими другими вещами, но только эти 2 вызывают проблемы), и после запуска сегментов ниже я получил странную ошибку. По крайней мере для меня, который никогда не использовал эти классы до этого.

Начните выполнять это

private static GameView window;
private static Timer time;
public static void main(String args[])
{
    window = new GameView(800,600);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);

    time = new Timer();
    time.schedule( new TimerTask(){
        public void run(){GameState.update(); 
        window.paintComponents(null);}
        },0, 40);

}

который вызывает это:

public void paintComponents (Graphics g)
{

    for(Bullet j : GameState.getEnBullets()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    for(Enemy j : GameState.getEnemies()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    for(Bullet j : GameState.getPlayBullets()){
        g.drawImage(j.getImage(),j.getX(), j.getY(), null);}
    this.paint(g);
}

И вот ошибка:

Exception in thread "Timer-0" java.lang.NullPointerException
    at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
    at java.awt.Container.paint(Unknown Source)
    at java.awt.Window.paint(Unknown Source)
    at Game.GameView.paintComponents(GameView.java:59)
    at Game.GameController$1.run(GameController.java:39)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)

Я также получаю пустое окно JFrame (GameView расширяет JFrame).


person Will    schedule 07.06.2011    source источник
comment
пожалуйста, проверьте все комментарии Эндрю Томпсона в вашей предыдущей теме   -  person mKorbel    schedule 07.06.2011
comment
@mKorbel: ITYM Рисование Graphics2D в JFrame. ;) @Will: Чтобы быстрее получить помощь, опубликуйте SSCCE.   -  person Andrew Thompson    schedule 07.06.2011
comment
@Эндрю Томпсон, @Буду ли я захватывать оба потока вместе с ... Graphics2d в jframe"> stackoverflow.com/questions/6260436/   -  person mKorbel    schedule 07.06.2011
comment
@Andrew Thompson: если я попытаюсь опубликовать SSCCEE, никто не захочет его читать, так как для этого мне потребуется опубликовать 9 классов, каждый из которых содержит около 200 строк кода. Если люди захотят это сделать что мне помочь, то я это сделаю.   -  person Will    schedule 08.06.2011
comment
это не SSCCE, поскольку SSCCE будет одним файлом и будет содержать не более 100 строк кода. Пожалуйста, прочитайте ссылку Андрея, прежде чем отвечать. Создание SSCCE потребует значительных усилий с вашей стороны, но эти усилия того стоят, поскольку они часто приведут вас к самостоятельному решению вашей проблемы, а если нет, то позволят вам опубликовать код, который мы можем протестировать, проанализировать и изменить, чтобы помочь вам. получить решение.   -  person Hovercraft Full Of Eels    schedule 08.06.2011


Ответы (3)


Вы получаете NPE, потому что вы передаете null как графику в window.paintComponents(null); А затем вы вызываете g.drawImage(j.getImage(),j.getX(), j.getY(), null);, где g равно нулю.

person Harry Joy    schedule 07.06.2011

Вы вообще не должны рисовать непосредственно в JFrame, а скорее в JPanel или JComponent, который удерживается JFrame. Вы должны переопределить метод paintComponent JPanel, как указано выше (не JFrame, поскольку у него даже нет этого метода) и рисовать там. Другое дело, используйте не java.util.Timer, а javax.swing.Timer, более известный как Swing Timer, поскольку это Swing-приложение. Кроме того, вы не должны вызывать paint/paintComponent напрямую, а скорее иметь поля класса обновления вашего графического интерфейса, а затем вызывать repaint() на JPanel, на котором вы рисуете, а затем paintComponent будет (обычно) вызываться JVM. Здесь, на этом форуме, есть много примеров Swing-анимации, и я предлагаю вам поискать эти примеры и учиться на них, так как я думаю, что они могут вам помочь.

Редактировать: черт возьми, вам уже сказали все это в ваших предыдущих темах. Почему мы должны помогать вам, если вы игнорируете наши советы?

person Hovercraft Full Of Eels    schedule 07.06.2011
comment
В чем проблема с использованием утилиты Timer? Вы можете это поддержать? Я использовал их неоднократно без проблем. Убийственное программирование игр на Java показано в гл. 2, что они обеспечивают очень хороший отклик, в отличие от Swing Timer, который может засорить EDT, если он срабатывает слишком часто. Кроме того, рисование может происходить в JFrame, если вы управляете панелями, и в некоторых случаях это может быть более уместно, чем добавление другого компонента. - person Phil Freihofner; 23.06.2011
comment
@Phil: можно использовать утилиту Timer, если позаботиться о том, чтобы вызовы Swing выполнялись только в EDT. Swing Timer позаботится об этом за вас и поэтому более удобен, но не абсолютно необходим. Любая задача с интенсивным использованием ресурсов ЦП должна выполняться в фоновом потоке независимо от того, какой таймер используется. - person Hovercraft Full Of Eels; 23.06.2011
comment
@Hover ... Я не думаю, что даже возможно сделать вызов Swing, который не будет автоматически перенаправляться в EDT. Или, может быть, мое понимание параллелизма Java на практике, глава 9, неверно. - person Phil Freihofner; 24.08.2011
comment
@Phil: да, твое понимание главы 9 неверно. На самом деле слишком легко сделать вызовы Swing вне EDT, и поэтому необходимо позаботиться о том, чтобы предотвратить это. - person Hovercraft Full Of Eels; 25.08.2011

Метод переопределения — это paintComponent(), а не «paintComponents» (с буквой s).

Вы никогда не должны вызывать метод paintComponent() напрямую. Вместо этого вы вызываете метод repaint() для компонента.

person camickr    schedule 07.06.2011