9

Hi I Would like add to my JFrame border some image. Is this Possible to attach picture to borders for JFrame and create it as 1 object ?

Something like this:

enter image description here

BackSlash
  • 21,927
  • 22
  • 96
  • 136
MTo
  • 406
  • 5
  • 12
  • Please clarify your question for us. – Hovercraft Full Of Eels Mar 08 '14 at 22:53
  • I meant that whole this frame and phone hanger would be treated as 1 object. It is like crating better looking Frame. For example in the games, asume that Heal Mark is a circle and the frame of it is a circle. I would like add to this frame something like this http://fc05.deviantart.net/fs51/f/2009/340/7/b/HP_Bars_by_Project_Garnia.png And I would like to do the same with this.Is it more clearly right now ? – MTo Aug 13 '14 at 17:20
  • Have you seen http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html ? – apangin Aug 13 '14 at 19:54
  • Yep but it isn't it. His is more about shape of frame with some graphics on it – MTo Aug 13 '14 at 23:41
  • 3
    The single way is to set your `JFrame` undecorated and draw the frame border and top right buttons by out own. PS: The real `JFrame` size would be bigger than is seems. Outside background should be `opaque`. Then, use `JLayeredPane` to draw your outside content. – SeniorJD Aug 14 '14 at 10:27
  • @HovercraftFullOfEels - Hi, any chance my answer can claim the bounty? – Nick Grealy Aug 19 '14 at 14:04
  • @NickG: You'll have to wait and see. The bounty doesn't end til tomorrow. – Hovercraft Full Of Eels Aug 19 '14 at 15:44
  • @HovercraftFullOfEels, thanks! I wasn't sure how it worked. – Nick Grealy Aug 19 '14 at 22:57
  • @NickG: There ya go, your bonus has been granted. Your answer so far has garnered 155 rep points for you, congrats and enjoy in peace. – Hovercraft Full Of Eels Aug 20 '14 at 19:09

1 Answers1

9

I'm not sure if it's possible to add the image directly to the border of a JFrame (suggestions welcome). I decided to solve this issue by using a transparent content pane, and using an inner frame to "appear" like the outer frame.

The code is pretty simple, however, let me know if you'd like an explanation of how the code works.

Here's the minimum code you'll need to get up and running.

You'll need to provide your own transparent-phone.png image, in the root of the classpath (i.e. next to your PhoneWindow.java file, in the root package).

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

public class PhoneWindow {

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

    public PhoneWindow() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    final JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    // create the  inner frame
                    final JInternalFrame frame2 = new JInternalFrame("My Telephone");
                    frame2.setClosable(true);
                    frame2.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
                    // add elements to the outer frame
                    frame.setUndecorated(true);
                    frame.setBackground(new Color(0, 0, 0, 0));
                    JPanel pane = new TranslucentPane();
                    frame.setContentPane(pane);
                    frame.setLayout(new BorderLayout());
                    // add inner frame and phone picture
                    frame.add(frame2, BorderLayout.CENTER);
                    frame.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/transparent-phone.png")))), BorderLayout.EAST);
                    frame.setLocationRelativeTo(null);
                    frame.setMinimumSize(new Dimension(400, 300));
                    frame.pack();
                    // show
                    frame2.setVisible(true);
                    frame.setVisible(true);
                } catch (Throwable ex) {
                    ex.printStackTrace();
                }

            }
        });
    }

    public class TranslucentPane extends JPanel {

        public TranslucentPane() {
            setOpaque(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0f));
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }

    }

}

Here's the full Java class (including close and draggable behaviour)

https://gist.github.com/nickgrealy/16901a6428cb79d4f179

And here's a screenshot of the final product

N.B. the transparent sections inside/outside the phone.

The final result with transparency.

References:

Community
  • 1
  • 1
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119