Невозможно нарисовать простое изображение с помощью JComponent

Я использую IDE netbeans, чтобы попрактиковаться в базовом коде Java. Но мне не удается нарисовать изображение PNG. Ниже мой код,

package JavaApplication1;

import javax.swing.*;
import java.awt.*;

class MyCanvas extends JComponent
{
    Image img;
    public MyCanvas(){
        img = Toolkit.getDefaultToolkit().createImage("pengbrew.png");
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(img, 0, 0, null);
    }
}

public class JavaGame
{
    public static void main(String args[]){
        JFrame window = new JFrame("Image demo");
        window.getContentPane().add( new MyCanvas() );
        window.setSize(400,400);
        window.setVisible(true);
    }
}

Я добавил изображения в проект netbeans.

Пожалуйста, порекомендуйте.

Большое спасибо.


person domlao    schedule 30.07.2011    source источник
comment
Это может быть связано с местом, где вы сохранили изображение PNG.   -  person Raze    schedule 30.07.2011
comment
Raze, вероятно, резюмирует вашу проблему. Где ваши изображения по отношению к файлам вашего класса? Где они находятся по отношению к вашему пользовательскому каталогу (где Java в настоящее время ищет изображения)?   -  person Hovercraft Full Of Eels    schedule 30.07.2011


Ответы (2)


Самый простой способ — найти JLabel, который лучше JComponents для Icon/ImageIcon примеры здесь

person mKorbel    schedule 30.07.2011

Чтобы загрузить изображение, используйте ImageIO.read(File file). Это более новый API, более простой в использовании и лучше поддерживаемый. Учебник по загрузке изображений находится здесь http://docs.oracle.com/javase/tutorial/2d/images/loadimage.html, если вам нужны дополнительные указатели.

Вместо этого ваш код будет выглядеть так:

Image img;
public MyCanvas(){
    try {
        img = ImageIO.read(new File("pengbrew.png"));
    } catch (IOException e) {
        // Handle exception if there is one.
    }
}

Для длинного ответа о том, почему метод, который вы использовали, не работал, вероятно, из-за следующего...

Ваше изображение может находиться в правильном месте, и вместо этого Toolkit.createImage() не закончил загрузку изображения до того, как кадр подойдет для рисования. Toolkit.createImage() возвращает управление вашему приложению до того, как базовое изображение фактически завершит загрузку. Обычно вы можете проверить, является ли это проблемой, изменив размер вашего приложения, чтобы заставить его перерисовать. Если после нескольких секунд попытки изменить размер приложения появляется изображение, это происходит из-за того, что изображение не загружается во время первых вызовов рисования.

Чтобы убедиться, что изображение загружено, прежде чем продолжить, вам нужно использовать MediaTracker. Вот пример кода, чтобы убедиться, что загрузка изображения завершена перед его использованием.

Component component = new Component() {};
MediaTracker TRACKER = new MediaTracker(component);

...

Image image = Toolkit.getDefaultToolkit().createImage("imageToLoad.png");
synchronized(TRACKER) {
   int id = ++mediaTrackerID;
   TRACKER.addImage(image, id);
   try {
       TRACKER.waitForID(id, 0);
   } catch (InterruptedException ex) {
       image = null;
   }
   TRACKER.removeImage(image, id);
}
// Now you can use your image.

Вы увидите подобный код в классе ImageIcon в методе loadImage(Image image).

person Joshua    schedule 01.08.2011
comment
Также рассмотрите ImageIO.read(), упомянутый здесь. - person trashgod; 12.10.2012
comment
Помните, что между этими двумя методами существует разница в производительности. ImageIO медленнее, чем использование MediaTracker, но ImageIO — более новый API, делает НАМНОГО больше и лучше в использовании. Я просто хочу, чтобы Oracle улучшила его производительность. - person Joshua; 12.10.2012
comment
IIUC, ImageIO имеет фиксированную задержку; это тоже медленнее? - person trashgod; 12.10.2012
comment
@trashgod Я написал простой тест для загрузки jpeg из файла и вывода времени загрузки с помощью медиатрекера и ImageIO. Метод медиатрекера как минимум в 2 раза быстрее, когда я загружаю 129k jpg. Я сделал это с файлами меньшего размера несколько лет назад, но у меня нет цифр. Более чем рад опубликовать мой тестовый пример производительности где-нибудь, если вам интересно. - person Joshua; 12.10.2012
comment
Нет необходимости, но рассмотрите возможность обновления своего ответа; +1 ранее, кстати. - person trashgod; 12.10.2012
comment
Сделанный. Я оставил исходный ответ для полноты, но сначала поставил реализацию ImageIO. Если вы считаете, что мне следует удалить часть медиа-трекера, скажите мне. Еще раз спасибо за помощь! - person Joshua; 12.10.2012