Images In JFrame are overwriting each other not displaying both images over eachother [duplicate]

匿名 (未验证) 提交于 2019-12-03 02:39:01

问题:

This question already has an answer here:

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);           } }

I've been having some trouble with my code

when i add the knight image the background image will disappear and only the knight image appears. How would i make the images overlap or make the background image act like a background

回答1:

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

I'm guessing what you really want is have the knight displayed on top (on the z axis) so you need to do something like:

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);

That is you need to follow a parent/child hierarchy:

  1. add the background to the frame
  2. add the knight to the background


回答2:

JFrame uses BorderLayout by default, which means only one image is managed at the default/CENTER position.

See How to Use Borders for more details.

The solution is actually difficult, because you need to be able to make guarantees about the size of the layout, the images and the board

You might be able to use a GridLayout or GridBagLayout, but you'd need to have "empty" filler components to allow the layout to correctly expand, which could be come troublesome

Maybe a better solution might be to use a custom painting approach, which give you control over where the images are placed.

Painting in AWT and Swing and Performing Custom Painting for more detals

The following example simply makes use of GridBagLayout, which allows you to overlay components (in a variety of different ways). This example makes the boardLabel the container for all the other pieces, but, because the way GridBagLayout works, this isn't an absolute requirement

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;         }      }  }

With a setup like this, you can simply use GridBagConstraint's gridx and gridy values as direct cell address (no need to calculate the pixel position).

Because of the way the layout manager works, you are required to provide an empty cell component as well



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!