Rectangle is not drawn on top

前提是你 提交于 2020-01-15 23:55:19

问题


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.


回答1:


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 ;)

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

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...



来源:https://stackoverflow.com/questions/20578028/rectangle-is-not-drawn-on-top

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!