Search code examples
javaswingjframejpaneljwindow

How to make a window transparent, draggable and add some layered components?


I don't know how to add a JLabel on top of a JPanel. I want to display some information in a label on the mobile image. The image is in the JPanel. I already managed to make the JFrame undecorated.

Output http://i44.tinypic.com/2mhacsj.png

enter image description here

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Remote extends JFrame {
    JPanel p2;

    private Window Remote;

    public Remote() {
        createAndShowGUI();
    }

    public void createAndShowGUI() {
        // Set title and default close operation
        setTitle("Transparent Panel");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setUndecorated(true);
        p2 = new JPanel();
        JLabel label = new JLabel(new ImageIcon("C://Mobile.png"));
        p2.add(label);
        p2.setPreferredSize(new Dimension(1000, 800));
        add(p2);
        setLayout(new FlowLayout());
        setSize(315, 610);
        setVisible(true);
        setLocation(800, 100);
    }

    public static void main(String args[]) {
        // Run in the EDT
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Remote remote = new Remote();
            }
        });
    }

}

I have 3 Questions:

  1. How do I remove the borders [background] surrounding the mobile?

  2. How do I add some label in the JPanel?

  3. How to make the window movable?


Solution

  • This should meet your requirements:

    public void createAndShowGUI() {
        setTitle("Transparent Panel");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    
        setUndecorated(true);
        AWTUtilities.setWindowOpaque(this, false);
    
        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setBounds(0, 0, 315, 610);
    
        JLabel mobileImageLabel = new JLabel(new ImageIcon("C://Mobile.png"));
        mobileImageLabel.setBounds(0, 0, 315, 610);
        layeredPane.add(mobileImageLabel, Integer.valueOf(0));
    
        JLabel textLabel = new JLabel(" Booting... ");
        textLabel.setVerticalAlignment(SwingConstants.TOP);
        textLabel.setForeground(Color.GREEN);
        textLabel.setBounds(26, 59, 263, 495);
        layeredPane.add(textLabel, Integer.valueOf(1));
    
        setContentPane(layeredPane);
    
        setSize(315, 610);
        setLocation(800, 100);
        setVisible(true);
    }
    

    For a draggable window, call this method from your Remote() constructor:

    public void addListeners() {
        final Point offset = new Point();
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(final MouseEvent e) {
                offset.setLocation(e.getPoint());
            }
        });
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(final MouseEvent e) {
                setLocation(e.getXOnScreen()-offset.x, e.getYOnScreen()-offset.y);
            }
        });
    }
    

    Further notes:

    • instead of JFrame.add() use: getContentPane().add() or setContentPane()
    • AWTUtilities.setWindowOpaque() removes the gray background of an undecorated frame
    • a JLayeredPane can be used to stack components on top of each other
    • the layout in the JLayeredPane has to be done manually

    It should now look something like this::

    result: a transparent jframe with an image and label on top