Как мне вывести изображения JFrame на передний план моего окна в Java? - PullRequest
0 голосов
/ 28 апреля 2018

Так что в настоящее время у меня есть проблема, что большое изображение будет закрывать меньшие изображения в моей программе, когда я пытаюсь графически отобразить их в Java. Я хотел бы знать, как вывести определенные изображения в переднюю часть окна, чтобы большое фоновое изображение оставалось на заднем плане. Кроме того, я не верю, что в моей программе есть возможность просто реализовать изображения в обратном порядке.

Вот код, который я использовал: мой класс менеджера изображений с методом, который я использую для реализации изображений в окне,

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

public class ImageManager extends JFrame {

    private ImageIcon image1;
    private JLabel label1;

    private ImageIcon image2;
    private JLabel label2;

    private ImageIcon image3;
    private JLabel label3;

    public ImageManager() {

    }

    public void addBackground() {
        image3 = new ImageIcon(getClass().getResource("background.png"));
        label3 = new JLabel(image3);
        add(label3);
    }

    public void addSeaweed() {

        image1 = new ImageIcon(getClass().getResource("seaweed.png"));
        label1 = new JLabel(image1);
        add(label1);

    }

    public void addUnderwatervolcano() {
        image2 = new ImageIcon(getClass().getResource("underwatervolcano.png"));
        label2 = new JLabel(image2);
        add(label2);
    }

}

и вот где я использую методы из ImageManager: метод отображения изображения морских водорослей с использованием метода grow (),

public Seaweed() {

        setLayout(new FlowLayout());
        World.gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        World.gui.setVisible(true);
        World.gui.pack();
        World.gui.setTitle("seaweed and underwatervolcano");
        carbon = 0;
    }


    public void grow() {

        if(World.getOceanCarbon() >= 10) {
            addCarbon(10);
            World.addOceanCarbon(-10);



            World.gui.addSeaweed();
            World.gui.pack();
        }
    }

и вот метод в другом классе, который использует метод grow () из класса Seaweed и gui.addBackground () из класса ImageManager,

public static void runWorld() {

        gui.addBackground();

        UnderwaterVolcano volcano = new UnderwaterVolcano();
        Seaweed seaweed = new Seaweed();

        volcano.erupt();
        seaweed.grow();



        gui.setMinimumSize(new Dimension(905, 560));

    }
}

Я хотел бы знать, как мне сделать так, чтобы gui.addBackground () не закрывал изображение морской водоросли из gui.addSeaweed () (которая была вызвана в методе seaweed.grow ()), все еще вызывая графический интерфейс. addBackground () перед вызовом gui.addSeaweed (). Можно ли в любом случае манипулировать при вызове метода порядком, в котором изображения отображаются в окне? Я не очень хорошо понимаю JFrame, поэтому, пожалуйста, будьте очень объяснительными с вашими ответами, вся помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2018

Ну ваша текущая логика добавляет все изображения в кадр. Swing фактически рисует последний компонент, добавленный первым. То есть компоненты окрашиваются на основе самого высокого ZOrder, который рисуется первым. По умолчанию ZOrder компонента - это просто количество компонентов на момент добавления компонента на панель. Так что да, основываясь на вашей текущей логике, фон закрасит поверх других изображений.

Пара простых решений:

1) Управление ZOrder ваших компонентов.

После добавления компонента в кадр вы можете сбросить ZOrder, чтобы компонент был окрашен последним. Итак, основной код

add(aComponent);
setComponentZOrder(aComponent, 0);

2) Добавьте дочерние изображения к фоновому изображению вместо того, чтобы добавлять все изображения в рамку. Итак, у вас есть такая структура:

- frame
    - background image
        - seaweed
        - volcano

Таким образом, базовая логика будет выглядеть примерно так:

frame.add( background );
background.add( seaweed );
background.add( volcano );

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

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

Этот подход я бы использовал, поскольку он лучше описывает структуру вашего приложения. То есть ваш фрейм содержит фон, а фон содержит другие дочерние компоненты. Вложение компонентов является общим для получения желаемой компоновки кадра.

0 голосов
/ 28 апреля 2018

Вы должны использовать LayeredPane. Вот мой рабочий пример. Вам нужно только заменить использованные изображения на некоторые из ваших.

Основной класс:

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;


public class Main{

    static JFrameWin jFrameWindow;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(runJFrameLater);
    }

    public static class JFrameWin extends JFrame{

        public JFrameWin(){

            // init
            initJFrame(this);

            JPanelSettings jPanelSettings = new JPanelSettings(this.getWidth(), this.getHeight(), this.getX(), this.getY());
            JLayeredPane enclosingJLayeredPane = getEnclosingJLayeredPane(jPanelSettings);

            jPanelSettings = new JPanelSettings(this.getWidth(), this.getHeight(), this.getX(), this.getY(), new File("billard_1.jpg"));
            JPanel backgroundJPanel = getJPanel(jPanelSettings);

            jPanelSettings = new JPanelSettings(this.getWidth()-100, this.getHeight()-100, this.getX()+5, this.getY()+20, new File("billard2.jpg"));
            JPanel firstLayerJPanel = getJPanel(jPanelSettings);

            jPanelSettings = new JPanelSettings(this.getWidth() - 200, this.getHeight() - 200, this.getX() + 60, this.getY() + 60, new File("painter.jpg"));
            JPanel secondLayerJPanel = getJPanel(jPanelSettings);

            // assemble
            enclosingJLayeredPane.add(backgroundJPanel);
            enclosingJLayeredPane.add(firstLayerJPanel);
            enclosingJLayeredPane.add(secondLayerJPanel);

            // adjust layers
            enclosingJLayeredPane.setLayer(backgroundJPanel, 0);
            enclosingJLayeredPane.setLayer(firstLayerJPanel, 1);
            enclosingJLayeredPane.setLayer(secondLayerJPanel, 2);

            // add object to JFrame
            this.add(enclosingJLayeredPane, BorderLayout.CENTER);
        }

    }

    static Runnable runJFrameLater = new Runnable() {
        @Override
        public void run() {
            jFrameWindow = new JFrameWin();
            jFrameWindow.setVisible(true);
        }
    };

    private static void initJFrame(JFrame jFrame) {
        jFrame.setTitle("Boxing Test");
        jFrame.setSize(600, 600);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private static JLayeredPane getEnclosingJLayeredPane(JPanelSettings jPanelSettings){
        JLayeredPane jLayeredPane = new JLayeredPane();
        jLayeredPane.setBounds(jPanelSettings.getXPosition(), jPanelSettings.getYPosition(), jPanelSettings.getWidth(), jPanelSettings.getHeight());
        return jLayeredPane;
    }

    private static JPanel getJPanel(JPanelSettings jPanelSettings){

        BufferedImage bufferedImage = null;

        try {
            bufferedImage = ImageIO.read(jPanelSettings.getImagePath());
        } catch (IOException ex) {
            System.out.println("Error" + ex.toString());
        }

        // fit image to frame size
        Image scaledBufferedImage = bufferedImage.getScaledInstance(jPanelSettings.getWidth(), jPanelSettings.getHeight(), Image.SCALE_DEFAULT);
        JLabel jLabel = new JLabel(new ImageIcon(scaledBufferedImage));

        JPanel jPanel = new JPanel();
        jPanel.setBounds(jPanelSettings.getXPosition(), jPanelSettings.getYPosition(), jPanelSettings.getWidth(), jPanelSettings.getHeight());
        jPanel.add(jLabel);

        return jPanel;
    }

}

класс помощника

import java.io.File;

public class JPanelSettings {

    private int height;
    private int width;
    private int xPosition;
    private int yPosition;
    private File imagePath;

    // Basic constructor
    public JPanelSettings(){ }

    // size and positioning constructor
    public JPanelSettings(int width,int height, int xPosition, int yPosition ){
        setWidth(width);
        setHeight(height);
        setXPosition(xPosition);
        setYPosition(yPosition);
    }

    // Full constructor
    public JPanelSettings(int width,int height, int xPosition, int yPosition, File imagePath ){
        setWidth(width);
        setHeight(height);
        setXPosition(xPosition);
        setYPosition(yPosition);
        setImagePath(imagePath);
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getXPosition() {
        return xPosition;
    }

    public void setXPosition(int xPosition) {
        this.xPosition = xPosition;
    }

    public int getYPosition() {
        return yPosition;
    }

    public void setYPosition(int yPosition) {
        this.yPosition = yPosition;
    }

    public File getImagePath() {
        return imagePath;
    }

    public void setImagePath(File imagePath) {
        this.imagePath = imagePath;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...