Как нарисовать что-то над всеми компонентами JPanel - PullRequest
1 голос
/ 29 марта 2020

Как нарисовать что-то поверх всех компонентов панели?

В приведенном ниже коде я попытался сделать это, переопределяя метод paintComponent, я вызываю super.paintComponent(g), надеясь, что при этом будут отрисованы все компоненты, добавленные как часть конструктора, но мой X остается ниже изображения.

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Stack extends JPanel {

    private final JLabel some_text = new JLabel("Some very long text that will be covered", JLabel.LEFT);
    private final JLabel some_icon = new JLabel((Icon)null, JLabel.CENTER);
    public static final String COMPASS_URL = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Compass_Rose_English_North.svg/240px-Compass_Rose_English_North.svg.png";

    public Stack() throws IOException {
        super(new GridBagLayout());

        URL compassUrl = new URL(COMPASS_URL);
        BufferedImage compassImage = ImageIO.read(compassUrl);
        ImageIcon compassIcon = new ImageIcon(compassImage);
        some_icon.setIcon(compassIcon);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;

        add(some_icon, c);

        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;
        add(some_text, c);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setColor(Color.RED);
        g2.setStroke(new BasicStroke(15));
        g2.drawLine(0, 0, this.getWidth(), this.getHeight());
        g2.drawLine(this.getWidth(), 0, 0, this.getHeight());
        g2.dispose();
    }

    private static void createAndShowUI() throws IOException {
        JFrame frame = new JFrame("MyFrame");
        frame.getContentPane().add(new Stack());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    createAndShowUI();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Есть ли способ вывести мой X на передний план или подождать, пока super.paintComponent(g) все раскрасит, а затем запустить код, который dr aws X?

Спасибо, Роберто

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Переопределите метод paint(…) вашего JPanel:

protected void paint(Graphics g)
{
    super.paint(g);

    // add custom painting code here
}

Метод paint(…) вызывает метод paintChildren(…), поэтому ваш пользовательский код будет выполнен после того, как все компоненты на панели будут окрашены.

См. . Более подробное описание механизма рисования .

0 голосов
/ 29 марта 2020

Попробуйте это. Я внес следующие изменения:

  • Нарисовал изображение в paintComponent, а не setIcon.
  • расположило изображение по центру.
  • used setPreferredSize для реального размера панели (настройка размера рамки включает границы, которые, вероятно, не соответствуют вашим требованиям).
  • используется RenderingHints в paintComponent для сглаживания краев креста.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Stack2 extends JPanel {

    private final JLabel some_text = new JLabel(
            "Some very long text that will be covered", JLabel.LEFT);
    private final JLabel some_icon =
            new JLabel((Icon) null, JLabel.CENTER);
    public static final String COMPASS_URL =
            "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Compass_Rose_English_North.svg/240px-Compass_Rose_English_North.svg.png";
    BufferedImage compassImage;

    public Stack2() throws IOException {
        super(new GridBagLayout());

        URL compassUrl = new URL(COMPASS_URL);
        compassImage = ImageIO.read(compassUrl);
//        ImageIcon compassIcon = new ImageIcon(compassImage);
//        some_icon.setIcon(compassIcon);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;

        add(some_icon, c);

        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;
        add(some_text, c);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.drawImage(compassImage,
                (400 - compassImage.getWidth()) / 2,
                (400 - compassImage.getHeight()) / 2, null);
        g2.setColor(Color.RED);
        g2.setStroke(new BasicStroke(15));
        g2.drawLine(0, 0, this.getWidth(), this.getHeight());
        g2.drawLine(this.getWidth(), 0, 0, this.getHeight());
        g2.dispose();
    }

    private static void createAndShowUI() throws IOException {
        JFrame frame = new JFrame("MyFrame");
        Stack2 panel = new Stack2();
        frame.getContentPane().add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel.setPreferredSize(new Dimension(400, 400));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    createAndShowUI();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
...