【问题标题】:Images In JFrame are overwriting each other not displaying both images over eachother [duplicate]JFrame中的图像相互覆盖,而不是相互显示两个图像[重复]
【发布时间】:2016-06-13 03:15:18
【问题描述】:
public class Board extends JFrame
{
     public void bd()
{


    JFrame frame=new JFrame();
    JLabel background1 = new JLabel(new ImageIcon("background.png"));
    JLabel knight=new JLabel(new ImageIcon("knight.jpg"));
    frame.add(background1);
    frame.add(knight);
    frame.pack();
    frame.setResizable(false);     
    frame.setVisible(true); 





    }
}

我的代码遇到了一些问题

当我添加骑士图像时,背景图像将消失,只有骑士图像出现。 我如何使图像重叠或使背景图像像背景一样

【问题讨论】:

  • 只是为了澄清骑士图像将在背景1图像的前面
  • @Andrew Thompson 可以打开这个问题吗?我有一些解决方案可能有助于 OP 实际想要做的事情......
  • @user3437460 鉴于 2 个好的答案、1 个已接受和重复状态,最好发布您的答案以回应您提出的新(更具体)问题。 (就像我问/回答并用作副本的问答一样。)
  • 顺便说一句 - 给定 knight 模糊地暗示着国际象棋,另见 Making a robust, resizable Swing Chess GUI。它不是使用“背景图像”而是使用组件创建棋盘。
  • @AndrewThompson 嗯,我会按照你的建议去做。我只是担心一些用户可能会认为我在为获得声誉做噱头。

标签: java swing user-interface jframe


【解决方案1】:

JFrame默认使用BorderLayout,即默认/CENTER位置只管理一张图片。

更多详情请见How to Use Borders

解决方案实际上很困难,因为您需要能够保证布局、图像和电路板的大小

您也许可以使用GridLayoutGridBagLayout,但您需要有“空”填充组件以允许布局正确展开,这可能会很麻烦

也许更好的解决方案是使用自定义绘画方法,它可以让您控制图像的放置位置。

Painting in AWT and SwingPerforming Custom Painting 了解更多详情

以下示例仅使用GridBagLayout,它允许您覆盖组件(以各种不同的方式)。此示例使 boardLabel 成为所有其他部分的容器,但是,由于 GridBagLayout 的工作方式,这不是绝对要求

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Chess {

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

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

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() throws IOException {
            BufferedImage board = ImageIO.read(getClass().getResource("/board.png"));
            BufferedImage knight = ImageIO.read(getClass().getResource("/Knight.png"));
            setLayout(new BorderLayout());
            JLabel boardLabel = new JLabel(new ImageIcon(board));
            add(boardLabel);

            boardLabel.setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            for (int row = 0; row < 8; row++) {
                gbc.gridy = row;
                for (int col = 0; col < 8; col++) {
                    gbc.gridx = col;
                    boardLabel.add(filler(), gbc);
                }
            }

            JLabel knightLabel = new JLabel(new ImageIcon(knight));

            gbc.gridx = 3;
            gbc.gridy = 4;
            boardLabel.add(knightLabel, gbc);
        }

        protected JComponent filler() {
            JLabel filler = new JLabel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(50, 50);
                }
            };
            return filler;
        }

    }

}

通过这样的设置,您可以简单地使用GridBagConstraintgridxgridy 值作为直接单元格地址(无需计算像素位置)。

由于布局管理器的工作方式,您还需要提供一个空单元格组件

【讨论】:

    【解决方案2】:
    JLabel background1 = new JLabel(new ImageIcon("background.png"));
    JLabel knight=new JLabel(new ImageIcon("knight.jpg"));
    frame.add(background1);
    frame.add(knight);
    

    我猜你真正想要的是将骑士显示在顶部(在 z 轴上),所以你需要执行以下操作:

    JLabel background1 = new JLabel(new ImageIcon("background.png"));
    background.setLayout( new BorderLayout() );
    JLabel knight=new JLabel(new ImageIcon("knight.jpg"));
    background1.add(knight);
    frame.add(background1);
    

    也就是说,您需要遵循父/子层次结构:

    1. 为框架添加背景
    2. 将骑士添加到背景中

    【讨论】:

    • 只是为了澄清我是否希望多个图像位于层次结构的同一级别,我会将它们添加到 background1.add(additionalIamgae)l
    • @thebigone,是的,但是您会在背景标签上使用不同的布局管理器(可能是 FlowLayout)。这是所有 Swing 组件的基础。他们遵循父母/孩子的关系。因此,只要您想在一个面板上使用多个组件,您就可以将所有组件添加到同一个面板。然后布局管理器会根据布局管理器的规则来排列组件。
    • 您还可以查看Background Panel,它为背景的绘制提供了更大的灵活性。
    猜你喜欢
    • 2017-05-04
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    相关资源
    最近更新 更多