Как я могу отобразить два JPanels с изображениями на JFrame, и оба img должны быть видны? - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь установить в качестве фона аквариум (который является классом, который расширяет JPanel и содержит аквариум img), и поверх рыбы (который также является классом, который расширяет JPanel и содержит рыбу) IMG).

Проблема в том, что в верхней части аквариума отображается только одно изображение вместо рыбы (или аквариума, или рыбы, в зависимости от того, какая из них добавлена ​​в JFrame).

Main

public class Core {
    JFrame window;
    JLabel label;
    ImageIcon img;      
    Aquarium aquarium = new Aquarium();
    JavaFish javaFish = new JavaFish();

    public void start() {
        window = new JFrame();
        window.setPreferredSize(new Dimension(600, 400));
        window.setVisible(true);
        window.setTitle("Java Game");
        aquarium.add(javaFish);
        window.add(aquarium);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        Core c = new Core();
        c.start();
    }
}

Аквариум

public class Aquarium extends JPanel {

    private BufferedImage img;
    //Initiate aquarium width 
    public int width;
    //Initiate aquarium height
    public int height;

    @Override
    protected void paintComponent(Graphics g) {
        width = getSize().width;
        height = getSize().height;

        try {
            img = ImageIO.read(new File("img/AquariumBackground.png"));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Image not fount!");
        }

        g.drawImage(img, 0, 0, width, height, this);
    }               
}

Рыба

public class JavaFish extends JPanel {
    BufferedImage img;
    int xPos = 50;
    int yPos = 50;

    public JavaFish() {
        this.setOpaque(false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        BufferedImage JavaFish = LoadImage("img/JavaFish.png");
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(JavaFish, xPos, yPos, 100, 100, null);
        repaint();
    }

    BufferedImage LoadImage(String FileName) {
        img = null;
        try {
            img = ImageIO.read(new File (FileName));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return img;
    }
}

1 Ответ

0 голосов
/ 12 сентября 2018

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

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

По умолчанию JFrame использует BorderLayout, и если вы не задаете ограничение,Компонент добавляется к CENTER из BorderLayout, что означает, что размер компонента автоматически изменяется, чтобы заполнить пространство кадра.

Таким образом, компонент, который вы добавляете в кадр, будет иметь размер, чтобы заполнить кадр,Компонент, добавляемый на панель, будет иметь размер (0, 0), поэтому рисовать нечего.

Итак, некоторые пользовательские советы по рисованию:

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

  2. Вызовите super.paintComponent (..) в качестве первого оператора, чтобы убедиться, чтофон очищается.

  3. Не читать изображение в методе paintComponent ().Этот метод можно вызывать всякий раз, когда Swing определяет, что компонент должен быть перекрашен, поэтому неэффективно продолжать чтение изображения.Вместо этого изображение следует прочитать в конструкторе класса.

  4. Не вызывайте repaint () в методе рисования.Это приведет к бесконечному циклу рисования.

Кроме того, компоненты должны быть добавлены в рамку, ДО того, как вы сделаете рамку видимой.

Сказав все вышесказанное, Алеррапредложение в комментарии нарисовать оба изображения на одной панели - хорошая идея.Это упрощает рисование, и вы даже можете легко рисовать несколько рыб, сохраняя ArrayList изображений, которые вы хотите нарисовать.Затем вы просто рисуете фон, а затем перебираете ArrayList, чтобы нарисовать отдельную рыбу.

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

...