1

I Have used JPanel to embed two images. One is png image and another is jpeg. I have to overlay png image over jpeg. I have tried out. Please fix me if, I am wrong.

import java.awt.*;
import java.io.IOException;

import javax.swing.*;

public class Test extends JFrame 
{
  public Test()
  {
    super();

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(1366,768);

    onInit();

    setVisible(true);
  }
  private void onInit()
  {

    JPanel panel=new JPanel();
    panel.setLayout(null);
    panel.setBounds(0,0,1366,768);
    panel.setBackground(new Color(0,0,0,0));
    JLayeredPane lp = getLayeredPane();
    lp.setBounds(0,0,1366,768);
    JLabel adLabel1=new JLabel();
    adLabel1.setBounds(0,0,1366,768);
    Image img1=new ImageIcon("F:\\wall papers\\Download-High-Res-Crazy-Concrete-Textures.jpg").getImage();  
    ImageIcon ad1=new ImageIcon(img1.getScaledInstance(1366,768,Image.SCALE_SMOOTH));
    adLabel1.setIcon(ad1);
    JLabel adLabel2 = new JLabel();
    adLabel2.setBounds(0, 0, 1366, 768);
    Image img2=new ImageIcon("<path>\\A100004.png").getImage();  
    ImageIcon ad2=new ImageIcon(img2.getScaledInstance(1366,768,Image.SCALE_SMOOTH));
    adLabel2.setIcon(ad2);
    adLabel2.setBackground(new Color(0,0,0,0));
    adLabel2.revalidate();
    lp.add(adLabel1,JLayeredPane.MODAL_LAYER);
    lp.add(adLabel2,JLayeredPane.DRAG_LAYER);
    panel.add(lp);


  }

  public static void main(String args[])
  {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        new Test();
      }
    });
  }
}

If I do not use JPanel it is working, it shows only a blank panel. But I want it to be done in the JPanel.

Example:

enter image description here

and I tried with this png image:

enter image description here

Rahul Sharma
  • 5,614
  • 10
  • 57
  • 91
Shrinivasan
  • 261
  • 4
  • 9
  • 1
    *"If I do not use `JPanel` it is working."* If not using a panel, then what? Wat is it you see instead of one image overlaying the other? I would not use `null` layouts for this, but custom painting. BTW - Good work on posting source the looks like (I did not try it) it would compile and run. One way to get image(s) for such an example (that we can run to see it fail to overlay the images) is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). – Andrew Thompson Dec 01 '17 at 09:11
  • If I use 'JPanel' It shows only a blank panel with no image – Shrinivasan Dec 01 '17 at 09:13
  • Uh-huh.. the `panel` component is never added to a parent container.. – Andrew Thompson Dec 01 '17 at 09:16
  • How can I do that ? – Shrinivasan Dec 01 '17 at 09:27
  • There are a number of ways, one is `this.add(panel);` .. – Andrew Thompson Dec 01 '17 at 09:54
  • I have tried adding this.add(panel) in the constructor it but it shows **Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: adding container's parent to itself** so only i removed it. – Shrinivasan Dec 01 '17 at 10:00
  • 1
    The `panel` is a local variable to `onInit()`, so it could not be added in the constructor. I suggest to [edit] the question to show a [mcve] (after looking at the code more closely, it became clear it was copy/paste compilable due to missing methods. I've voted to close because there is no MCVE. Make sure to hot-link to images. – Andrew Thompson Dec 01 '17 at 10:39
  • @user1803551 Good point, there are two good approaches in the first two answers of the linked question. Since I already voted to close for another reason, I cannot close this, but perhaps other passer-by's can shut it down. – Andrew Thompson Dec 02 '17 at 03:34
  • @AndrewThompson Umm... the passer-by decided to answer the question instead... :) – user1803551 Dec 02 '17 at 03:37

1 Answers1

1

You have a number of possible solutions, you could, for example try:

  • Using a GridBagLayout, although that would become insanely complex really quickly
  • Create you own LayoutManager, but that's probably overkill for the problem
  • Use a OverlayLayout manager, but since I don't have any experience with it, I can't say if it would solve your issue or not.

Or, you could...

Take control of the whole process and fallback to custom painting. This gives you the same level of flexibility as writing your own LayoutManager, but without the complexity and since you're only drawing images, makes a life a whole lot simpler.

If you need to display other components (like text or text fields) you could use a custom painting route to render the images as the background and one or layout mangers to deal with the other components.

Example

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

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

                try {
                    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) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage background;
        private BufferedImage foreground;

        public TestPane() throws IOException {
            background = ImageIO.read(getClass().getResource("Background.png"));
            foreground = ImageIO.read(getClass().getResource("Foreground.png"));
        }

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

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = 0;
            int y = 0;
            int width = getWidth();
            if (background != null) {
                x = (getWidth() - background.getWidth()) / 2;
                y = (getHeight() - background.getHeight()) / 2;
                width = background.getWidth();
                g2d.drawImage(background, x, y, this);
            }
            if (foreground != null) {
                x = x + width - foreground.getWidth();
                g2d.drawImage(foreground, x, y, this);
            }
            g2d.dispose();
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366