1

I think that everything is written correctly in the code I just need to know how to sort out different layers.

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;

class FullSceenToggleAction extends AbstractAction {

    private JFrame frame;
    private GraphicsDevice fullscreenDevice;

    public FullSceenToggleAction(JFrame frame) {
        this(frame, GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
    }

    public FullSceenToggleAction(JFrame frame, GraphicsDevice fullscreenDevice) {
        this.frame = frame;
        this.fullscreenDevice = fullscreenDevice;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        frame.dispose();
        if (frame.isUndecorated()) {
            fullscreenDevice.setFullScreenWindow(null);
            frame.setUndecorated(false);
        } else {
            frame.setUndecorated(true);
            fullscreenDevice.setFullScreenWindow(frame);
        }
        frame.setVisible(true);
        frame.repaint();
    }

}

public class Main {

    public static final void addKeyBinding(JComponent c, String key, final Action action) {
        c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(key), key);
        c.getActionMap().put(key, action);
        c.setFocusable(true);
    }

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Fullscreen Toggle Test");
        Container contentPane = frame.getContentPane();
        contentPane.add(new JLabel("Hey"), BorderLayout.CENTER);
        frame.add(new JLabel(new ImageIcon("C:/Users/SamBr/Pictures/DesktopBackgrounds/image.png")));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(960, 600);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setTitle("Virtual World");
        addKeyBinding(frame.getRootPane(), "F11", new FullSceenToggleAction(frame));
    }

}

When I run the code I see the image but no text "Hey" in front of it or anywhere on the screen I do not understand why it is not shown or how I can make it visible in front of the image.

Sam
  • 65
  • 7
  • in design part, right click the component and there should be an option to get component front or back – Y.Kaan Yılmaz Mar 12 '16 at 19:47
  • I already told you the problem, but you never commented back to me, as if you ignored it. If you don't understand a comment, please don't just ignore it, please ask for clarification. – Hovercraft Full Of Eels Mar 12 '16 at 19:50
  • @Sam If you are using layout, you can't really place your components at the exact location you want (and most layout do not allow partial overlapping of components). The positions of the components will be determined by the layout. If you are interesting to let 2 images overlap and move them to anywhere you want, you can consider custom painting. You may take a look here: [Image which overlaps](http://stackoverflow.com/questions/35711891/how-to-create-a-background-and-foreground-image-which-overlaps/35711894#35711894). – user3437460 Mar 12 '16 at 20:24

2 Answers2

3

I told you the reason before -- you are adding two components to the contentPane, and the 2nd component is displacing the first.

Note that these two lines of code add a component to the same container, the JFrame's contentPane:

    contentPane.add(new JLabel("Hey"), BorderLayout.CENTER);
    frame.add(new JLabel(
           new ImageIcon("C:/Users/SamBr/Pictures/DesktopBackgrounds/image.png")));

Since as per the JFrame API:

As a convenience, the add, remove, and setLayout methods of this class are overridden, so that they delegate calls to the corresponding methods of the ContentPane.

Also, the contentPane uses a BorderLayout by default, and if you add a component without use of 2nd parameter constants, the components are added by default into the BorderLayout.CENTER location.

If you want both to display, then either

  1. Use a different layout from the container's default BorderLayout
  2. Keep the BorderLayout, but add your two JLabel's to two different BorderLayout locations, such as BorderLayout.CENTER, BorderLayout.PAGE_START,...
  3. Use a JLayeredPane to hold layers
  4. Draw the image in a image-drawing JPanel's paintComponent method, and add the "Hey" JLabel to this JPanel
  5. .... other solutions.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
1

Who knows exactly what you are trying to do.

But here are some example of displaying text on a label at different locations depending on your requirement:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class LabelImageText extends JPanel
{
    public LabelImageText()
    {
        JLabel label1 = new JLabel( new ColorIcon(Color.ORANGE, 100, 100) );
        label1.setText( "Easy Way" );
        label1.setHorizontalTextPosition(JLabel.CENTER);
        label1.setVerticalTextPosition(JLabel.CENTER);
        add( label1 );

        //

        JLabel label2 = new JLabel( new ColorIcon(Color.YELLOW, 200, 150) );
        label2.setLayout( new BoxLayout(label2, BoxLayout.Y_AXIS) );
        add( label2 );

        JLabel text = new JLabel( "More Control" );
        text.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        label2.add( Box.createVerticalGlue() );
        label2.add( text );
        label2.add( Box.createVerticalStrut(10) );

        //

        JLabel label3 = new JLabel( new ColorIcon(Color.GREEN, 200, 150) );
        label3.setLayout( new GridBagLayout() );
        add( label3 );

        JLabel text3 = new JLabel();
        text3.setText("<html><center>Text<br>over<br>Image<center></html>");
        text3.setLocation(20, 20);
        text3.setSize(text3.getPreferredSize());
        label3.add( text3 );

        //

        JLabel label4 = new JLabel( new ColorIcon(Color.CYAN, 200, 150) );
        add( label4 );

        JTextPane textPane = new JTextPane();
        textPane.setText("Add some text that will wrap at your preferred width");
        textPane.setEditable( false );
        textPane.setOpaque(false);
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        StyledDocument doc = textPane.getStyledDocument();
        doc.setParagraphAttributes(0, doc.getLength(), center, false);
        textPane.setBounds(20, 20, 75, 100);
        label4.add( textPane );
    }

    public static class ColorIcon implements Icon
    {
        private Color color;
        private int width;
        private int height;

        public ColorIcon(Color color, int width, int height)
        {
            this.color = color;
            this.width = width;
            this.height = height;
        }

        public int getIconWidth()
        {
            return width;
        }

        public int getIconHeight()
        {
            return height;
        }

        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor(color);
            g.fillRect(x, y, width, height);
        }
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("LabelImageText");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new LabelImageText() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

The easy solution just uses a single label with both icon and text. The others use other components and take advantage of layout managers.

camickr
  • 321,443
  • 19
  • 166
  • 288