1

I have a class "Map" which extends JPanel. I add it to a class that extends a JFrame.

public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int width = Math.abs(startX - endX);
        int height= Math.abs(startY - endY);
        g.setColor(Color.RED);
        g.fillRect(startX, startY, width, height);
    }

My class "Map" also contains a label with an image in it. If the image is smalled than the window, when I draw a rectangle it is seen. In short, it is under the label.

Justas S
  • 584
  • 4
  • 12
  • 34
  • `I want to be able to draw rectangles on the jlabel(which is a picture).`, I already answered that in your last posting (http://stackoverflow.com/a/20575316/131872). You extend your JLable (not a JPanel) and do the custom painting in the paintComponent() method of the label. – camickr Dec 14 '13 at 01:54

1 Answers1

5

paintComponent is the "bottom" of the paint chain, so anything painted here will appear below everything else.

A better solution might be to add the Map panel to the label (setting the JLabel's layout manager appropriately).

Or, create a "base" panel, set it's layout manager to use a OverlayLayout manager and add the JLabel and Map panel to it.

This will, of course, all depend on what it is you want to achieve...

Updated with "Panel on Label" example

Basically, this takes a JLabel, sets an icon (as the background image), set it's layout as BorderLayout and then adds a JPanel on to it.

Remember, JPanel is opaque by default, so you need to make it transparent ;)

Panel on label

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class OverlayLabel {

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

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

                    JLabel background = new JLabel(new ImageIcon(ImageIO.read(new File("/path/to/image"))));
                    background.setLayout(new BorderLayout());
                    background.add(new TestPane());

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(background);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics g2d = (Graphics2D) g.create();
            int x = (getWidth() - 20) / 2;
            int y = (getHeight() - 20) / 2;
            g2d.setColor(Color.RED);
            g2d.fillRect(x, y, 20, 20);
            g2d.dispose();
        }

    }

}

Updated with example of OverlayLayout

OverlayLayout basically uses the components x/y alignment to make determinations about how best it should place the individual components

OverlayLayout

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class OverlayLabel {

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

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

                    JLabel background = new JLabel(new ImageIcon(ImageIO.read(new File("/path/to/image"))));
                    background.setAlignmentX(0.5f);
                    background.setAlignmentY(0.5f);

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new OverlayLayout(frame.getContentPane()));
                    frame.add(new TestPane());
                    frame.add(background);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics g2d = (Graphics2D) g.create();
            int x = (getWidth() - 20) / 2;
            int y = (getHeight() - 20) / 2;
            g2d.setColor(Color.RED);
            g2d.fillRect(x, y, 20, 20);
            g2d.dispose();
        }

    }

}

And finally, if none of that is working for you, you could use JLayeredPane as the base, which will allow you to determine the z-order of each component...

See How to use layered panes for more details...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • You can add a panel to a JLabel? :/ I want to be able to draw rectangles on the jlabel(which is a picture). – Justas S Dec 14 '13 at 00:20
  • `JLabel` extends from `JComponent` which extends from `Container`, so yes, it is just a container like `JPanel`. Just remember though, `JLabel` has no default layout manager and you won't be able to control (to any great level of percision) this position of the icon – MadProgrammer Dec 14 '13 at 00:28
  • Okay, so I added a "Map" object to a label and set its layout to "OverlayLayout", nothing changed... What does OverlayLayout do? – Justas S Dec 14 '13 at 00:32
  • It basically acts a little like `BorderLayout`, but puts everything in the `CENTER` position (unlike `BorderLayout` which only allows a single component to sit within a given position) – MadProgrammer Dec 14 '13 at 00:38
  • And if you're going to add the panel to the label, I might use `BorderLayout` instead ;) – MadProgrammer Dec 14 '13 at 00:41