BufferedImage в JFrame не отображается

пытается получить изображение для печати в окне. Все работает без ошибок, а также работает, если я заменяю drawImage на другой класс графики. Однако в окне отсутствует изображение, и я не уверен, почему. Опять же, материал JFrame и Graphics отлично работают с отрисовкой другой графики, но не рисуют изображение здесь. Спасибо.

import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.imageio.*;
import javax.imageio.stream.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;

public class GraphicsMovement2 extends JApplet{
    BufferedImage image = null;

    public static void main(String args[]){
        BufferedImage image = null;
        try {
            File file = new File("C:\\Users/Jonheel/Google Drive/School/10th Grade/AP Computer Science/Junkbin/MegaLogo.png");
            ImageInputStream imgInpt = new FileImageInputStream(file);
            image = ImageIO.read(file);
        }
        catch(FileNotFoundException e) {
            System.out.println("x");
        }
        catch(IOException e) {
            System.out.println("y");
        }


        JApplet example = new GraphicsMovement2();
        JFrame frame = new JFrame("Movement");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(example);
        frame.setSize(new Dimension(1366,768));       //Sets the dimensions of panel to appear when run
        frame.setVisible(true);
    }
    public void paint (Graphics page){
    page.drawImage(image, 100, 100, 100, 100, Color.RED, this);
  }
}

person Jonheel    schedule 02.11.2012    source источник


Ответы (3)


Вы определили image дважды...

BufferedImage image = null;

public static void main(String args[]){
    BufferedImage image = null;

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

Другая проблема, с которой вы столкнетесь, заключается в том, что вы пытаетесь загрузить изображение из статической ссылки, но image не объявлено как static. Лучше перенести эту логику в конструктор или метод экземпляра.

Не используйте JApplet в качестве контейнера при добавлении к JFrame, лучше использовать что-то вроде JPanel. Это поможет, когда дело доходит до добавления вещей в контейнер.

ВЫ ДОЛЖНЫ ВЫЗВАТЬ super.paint(g)... на самом деле, НЕ переопределять метод paint контейнеров верхнего уровня, таких как JFrame или JApplet. Используйте что-то вроде JPanel и вместо этого переопределите метод paintComponent. Контейнеры верхнего уровня не буферизуются дважды.

Методы paint выполняют много важной работы, и JComponent#paintComponent проще использовать... но не забудьте вызвать super.paintComponent

ОБНОВЛЕНО

Вам нужно определить image в том контексте, в котором он будет использоваться.

Поскольку вы объявили image полем экземпляра GraphicsMovement2, вам потребуется экземпляр GraphicsMovement2, чтобы ссылаться на него.

Однако в вашем методе main, то есть static, вы также объявили переменную с именем image.

Метод paint из GraphicsMovement2 не может видеть переменную, которую вы объявили в main, только поле экземпляра (то есть null).

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

public GraphicsMovement2() {
    try {
        File file = new File("C:\\Users/Jonheel/Google Drive/School/10th Grade/AP Computer Science/Junkbin/MegaLogo.png");
        ImageInputStream imgInpt = new FileImageInputStream(file);
        image = ImageIO.read(file);
    }
    catch(FileNotFoundException e) {
        System.out.println("x");
    }
    catch(IOException e) {
        System.out.println("y");
    }
}

Два приведенных ниже примера дадут один и тот же результат...

введите здесь описание изображения

Легкий способ

public class TestPaintImage {

    public static void main(String[] args) {
        new TestPaintImage();
    }

    public TestPaintImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ImagePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ImagePane extends JPanel {

        public ImagePane() {
            setLayout(new BorderLayout());
            ImageIcon icon = null;
            try {
                icon = new ImageIcon(ImageIO.read(new File("/path/to/your/image")));
            } catch (Exception e) {
                e.printStackTrace();
            }
            add(new JLabel(icon));
        }

    }
}

Трудный путь

public class TestPaintImage {

    public static void main(String[] args) {
        new TestPaintImage();
    }

    public TestPaintImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ImagePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ImagePane extends JPanel {

        private BufferedImage background;

        public ImagePane() {
            try {
                background = ImageIO.read(new File("/path/to/your/image"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                int x = (getWidth() - background.getWidth()) / 2;
                int y = (getHeight() - background.getHeight()) / 2;
                g.drawImage(background, x, y, this);
            }
        }
    }
}

Потратьте время, чтобы прочитать учебники

person MadProgrammer    schedule 02.11.2012
comment
Этот ответ был немного выше меня, поставить ли «BufferedImage image = null;» в основном методе или нет? Я пытался не делать этого раньше, но, как вы сказали, у меня были проблемы с объявлением его статическим. - person Jonheel; 02.11.2012
comment
Спасибо за подробные исправления для обоих. Увидев оба, мое отношение к этому определенно изменилось. Мой последний вопрос, прежде чем я смогу отметить его как решенный, заключается в том, должен ли я помещать класс ImagePane в новый файл .java. Все остальное, по крайней мере, строится прямо сейчас и выглядит лучше. - person Jonheel; 03.11.2012
comment
@Jonheel ImagePane в моем примере должен быть полностью независимым, и с точки зрения повторного использования, да, он может быть в собственном исходном файле. - person MadProgrammer; 03.11.2012
comment
Спасибо, это как раз то, что я хотел. Графика все еще немного выше меня, даже после этого, поэтому, когда я вернусь к графике, я обязательно вернусь к этому. - person Jonheel; 03.11.2012

Ваш класс не должен расширять JApplet, если вы даже не используете апплеты — это не имеет смысла. Вместо

  • Пусть ваш класс рисования расширяет JPanel
  • Нарисуйте в методе paintComponent JPanel
  • Добавьте эту JPanel в панель содержимого JFrame.
  • Прочтите руководства по рисованию Swing. Вы не можете догадываться об этом и ожидать, что это сработает, а учебные пособия покажут вам, как это делается правильно.
person Hovercraft Full Of Eels    schedule 02.11.2012
comment
Нет ли способа избежать этого? Опять же, даже если это может быть не лучший способ сделать что-то, он выполняет свою работу, плюс я не расширяю эту программу после того, как она отображает буферизованное изображение. - person Jonheel; 02.11.2012
comment
@ user1793082: зачем пытаться делать что-то неправильно без уважительной причины? Опять же, это не имеет смысла. Вы можете использовать тиски, чтобы забивать гвозди, и это вроде как сработает, но зачем продолжать это делать, если молоток гораздо лучше подходит для этой работы? - person Hovercraft Full Of Eels; 02.11.2012
comment
@user1793082 user1793082 Ударяюсь головой о стену, и стена рухнет, но зачем страдать от боли... - person MadProgrammer; 02.11.2012
comment
Я полностью согласен, но я пытаюсь пересечь финишную черту, хромая. Я не собираюсь долго возвращаться к графике после этой программы, поэтому я не ищу сейчас хорошо написанную программу. - person Jonheel; 02.11.2012
comment
@user1793082 Я не собираюсь возвращаться к графике еще долго не ограничивайте себя, вы не знаете, куда жизнь затащит вас, брыкаясь и крича ;) - person MadProgrammer; 02.11.2012
comment
@jonheel: "so i'm not looking for a well written program right now": Не очень хорошее отношение. Мне почти хочется задаться вопросом, почему мы должны тратить время, пытаясь помочь вам, когда вместо этого мы можем провести время со студентом, которому не все равно. Просто надеюсь, что у вашего доктора не было такого отношения, когда он изучал медицину. - person Hovercraft Full Of Eels; 02.11.2012
comment
@MadProgrammer Поймите, я потратил более 10 часов на изучение руководств по Java Swing Class. - person Jonheel; 03.11.2012

Не смешивайте разделители файлов,

File file = new File("C:\\Users/Jonheel/Google Drive/School/10th Grade/AP Computer Science/Junkbin/MegaLogo.png");

следует заменить на:

File file = new File("C:/Users/Jonheel/Google Drive/School/10th Grade/AP Computer Science/Junkbin/MegaLogo.png");

person Mordechai    schedule 02.11.2012
comment
Хорошо, что спас меня один персонаж, но не более того. Это не помогло, и у меня была программа для чтения файлов, которая работала по-другому. - person Jonheel; 02.11.2012