Изображения в апплетах

Я написал этот код для отображения простой картинки на экране апплета, но изображение не отображается, пока я не изменю размер окна апплета. Что я могу сделать, чтобы это преодолеть?

public class Test extends JApplet {
    public void init () {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGUI();
            }
        });
    }
    public void start() {
    }
    public void createGUI() {
        getContentPane().add(new GUIThing(getImage(getCodeBase(), "gladiator.gif")));
    }
}

public class GUIThing extends JPanel {
    Image image;
    public GUIThing(Image i2) {
        image=i2;
    }
    public void paintComponent(Graphics g) {
        Graphics2D g2=(Graphics2D) g;
        g2.drawImage(image,100,100,100, 100, null);
    }
}

person Ofek Ron    schedule 25.07.2012    source источник
comment
Попробуйте добавить repaint(); в конец createGUI()?   -  person tskuzzy    schedule 25.07.2012
comment
пробовал это уже, это не работает ... Я думаю, что причина того, что он не работает, связана с getImage (getCodeBase (), gladiator.gif), я также пробовал использовать repaint (10), который ждал 10 нс перед перерисовкой ...   -  person Ofek Ron    schedule 25.07.2012
comment
Попробуйте использовать метод блокировки, чтобы получить изображение, например ImageIO.read(...). Кроме того, я считаю, что для JApplet вы должны использовать SwingUtilities.invokeAndWait(...), а не SwingUtilities.invokeLater(...)   -  person Hovercraft Full Of Eels    schedule 25.07.2012
comment
@hovercraftfullofeels Надеюсь, вы не предлагаете блокировать EDT? Потому что так это читается. Я также давно не играл с аппетами, но разве методы init и start не вызываются в EDT?   -  person MadProgrammer    schedule 26.07.2012
comment
@MadProgrammer: Да, но он не хочет запускать апплет, пока изображение не будет прочитано и не будет готово к рендерингу.   -  person Hovercraft Full Of Eels    schedule 26.07.2012
comment
@HovercraftFullOfEels После некоторого тестирования, к моему удивлению, методы init и start НЕ вызываются в EDT. Я никогда не должен был принимать это как должное: P   -  person MadProgrammer    schedule 26.07.2012


Ответы (1)


Попробуйте передать контекст апплета методу drawImage, это позволяет приложению получать уведомления о загрузке изображения и перерисовывать себя.

g2.drawImage(image,100,100,100, 100, this);

И, если вы действительно в отчаянии, вызовите invalidate() repaint() в методе start

ОБНОВЛЕНИЕ ПРИМЕРОМ

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

public class TestApplet extends JApplet {

    public void init() {

        System.out.println("Init..." + EventQueue.isDispatchThread());

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createGUI();
            }
        });

    }

    public void start() {

        System.out.println("Start..." + EventQueue.isDispatchThread());

    }

    public void createGUI() {

        URL documentBase = getDocumentBase();

        System.out.println(documentBase);
        System.out.println(getCodeBase());

//        file:.../build/TestApplet.html
//        file:.../build/classes/        
        Image image = getImage(documentBase, "MT-vol-6-STOP-image-Kogumiko-megatokyo-11434773-1559-1852.jpg");

        System.out.println("image = " + image);

        getContentPane().add(new GUIThing(image));
    }

    public class GUIThing extends JPanel {

        Image image;

        public GUIThing(Image i2) {
            image = i2;
        }

        public void paintComponent(Graphics g) {

            super.paintComponent(g);

            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(image, 0, 0, this);

            g2.setColor(Color.RED);
            g2.drawLine(0, 0, getWidth(), getHeight());

        }
    }

}

Ух ты, с апплетами давно не играл. Я изменил ваш код с использования базы кода на базу документов, которая, похоже, сработала. Я загружал изображение размером 1559x1852 пикселей практически без задержки (локально)

Дважды проверьте свой тег апплета в HTML-файле. Я использовал

<APPLET codebase="classes" code="stack/TestApplet.class" width=350 height=200></APPLET>

Через программу просмотра апплетов. Обратите внимание, что база кода отличается от базы документа !!

Мое изображение находилось в том же месте, что и HTML-файл

person MadProgrammer    schedule 25.07.2012
comment
Вы можете взглянуть на документы ImageObserver API .oracle.com / javase / 7 / docs / api / java / awt / image /, это позволит вам ответить перерисовкой после загрузки изображения. - person MadProgrammer; 26.07.2012
comment
Я попытался переопределить updateImage (Image img) с помощью repaint (), но он все еще не работает, можете ли вы заставить этот пример работать? - person Ofek Ron; 26.07.2012
comment
+1 для многих вещей, но особенно для использования изображения с megatokyo в названии. :) - person Andrew Thompson; 27.07.2012