Почему мой холст не рисуется после добавления его в мой JFrame? - PullRequest
2 голосов
/ 19 ноября 2011

Я пишу небольшую игру, в которой для рисования используется экземпляр Canvas (на случай, если он мне знаком; я использую библиотеку игр LWJGL).Теперь я создал главное меню для своей игры, которое состоит из одного JPanel, который я затем добавляю в свою основную игру JFrame в начале игры;

Canvas canvas = new Canvas();
JFrame frame = new JFrame("Puzzler");
this.canvas = canvas;
this.jframe = frame;
canvas.setIgnoreRepaint(true);
frame.setSize(640, 480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

Далее я создаю главное меню:

this.mainMenuPanel = new MainMenuPanel(this.main);
this.jframe.setSize(500, 170);
this.jframe.getContentPane().add(mainMenuPanel);
this.jframe.validate();

Наконец, когда главное меню хочет запустить игру, я пытаюсь заменить JPanel главного меню на экземпляр Canvas:

this.jframe.setVisible(false);
this.jframe.invalidate();
this.jframe.removeAll();
this.jframe.getContentPane().add(canvas);
this.jframe.setVisible(true);
this.jframe.pack();
this.jframe.setSize(640, 480);
this.jframe.validate();

И когда этот последний бит кодавыполняется, вызов метода Display.create () в LWJGL возвращает ошибку о невозможности рисования Canvas.Я перепробовал целую кучу комбинаций (например, добавление JPanel в качестве контейнера Canvas, не повезло), и довольно много возился с порядком вызовов validate () и repaint (), поскольку это иногда помогает в колебании.Кто-нибудь имеет какие-либо идеи, в чем может быть проблема здесь?

РЕДАКТИРОВАТЬ Я решил проблему.Проблема оказалась в том, что поток обработки событий Java застрял при запуске основного цикла, потому что я вызвал run () в моем основном потоке, а не start ().Дурак я.: P

Ответы [ 2 ]

3 голосов
/ 19 ноября 2011

кроме правила не смешивания, я предполагаю, что вы получите аналогичное исключение в чистом контексте awt - из учебника LWJGL Basic Basic :

Теперь, когда мыу нас есть базовый шаблон, который нам нужен, чтобы прикрепить к нему собственный дисплей LWJGL.Для этого мы просто используем метод Display.setParent (Canvas).Однако прежде чем мы сможем создать дисплей, мы должны убедиться, что холст готов для рисования.Чтобы убедиться в этом, мы будем использовать метод addNotify () холста awt, чтобы сообщить нам, когда холст готов и что мы можем создать Display.Точно так же мы будем использовать removeNotify (), чтобы сообщить нам, что холст собирается быть уничтоженным, и мы должны очистить и закрыть собственный дисплей.

Редактировать

(все еще нет IDE под рукой, только с макушки головы; -)

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

 display_parent = new Canvas() {
    public final void addNotify() {
       super.addNotify();
       startLWJGL();
    }
    public final void removeNotify() {
      stopLWJGL();
      super.removeNotify();
    }
 };
 frame.add(display.parent);

Кроме того, убедитесь, что все изменения происходят в EDT - что может быть реальной проблемой, не знаю, что на самом деле делает Displayв этих методах:

 public void gameLoop() {
     while(running) {
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                 Display.sync(60);
                 Display.update();
             }
         });
    }

    Display.destroy();
 }      

Edit 2

просто запустите пример (в приведенном выше учебнике) в JFrame, без изменений в существующем коде, простодобавлен основной:

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Gears AWT");

        final JPanel intro = new JPanel();
        Action action = new AbstractAction("Start Gears") {

            @Override
            public void actionPerformed(ActionEvent e) {
                GearsApplet gears = new GearsApplet();
                gears.init();
                frame.remove(intro);
                frame.add(gears);
                frame.getRootPane().revalidate();
            }
        };
        JButton button = new JButton(action);
        intro.add(button);
        frame.add(intro); //.display_parent);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

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

3 голосов
/ 19 ноября 2011

Не смешивайте компоненты Swing и AWT.Холст тт.Используйте метод переопределения JPanel paintComponent Graphics g).

http://java.sun.com/products/jfc/tsc/articles/mixing/

http://www.devx.com/tips/Tip/14718

...