在JPanel中的不透明组件上绘制自定义内容 [英] Draw custom stuff on top of opaque components in a JPanel

查看:103
本文介绍了在JPanel中的不透明组件上绘制自定义内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JPanel,其中填充了几个不透明的自定义组件.现在,我想通过覆盖paintComponent()方法在这些组件之上绘制一些内容.我的问题是,已涂漆的东西被放置在嵌入式组件的后面,并且由于它们是不透明的,因此被它们覆盖.

I have an JPanel populated with several opaque custom components. Now I would like to draw something on top of these components by overriding the paintComponent() method. My problem is that the painted stuff is placed behind the embedded components and, as they are opaque, is covered by them.

有什么方法可以让绘画出现在组件的顶部?

Is there any way to let the painting appear on top of the components?

这是我要做的事的简短示例:

Here's a short example of what I'm trying to do:

public class DrawOnTop {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame("Draw on top");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new MyPanel());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

class MyPanel extends JPanel {

    public MyPanel() {
        setLayout(new BorderLayout(3, 3));
        add(new JButton("Button 1"), BorderLayout.NORTH);
        add(new JButton("Button 2"), BorderLayout.CENTER);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.drawLine(0, 0, getVisibleRect().width, getVisibleRect().height);
    }
}

推荐答案

您正在按照正确的思路进行思考. 唯一的问题是,您应该像下面的代码中那样重写paintChildren()方法.这是因为paintComponent()方法首先被调用,然后对组件本身(MyPanel)进行背景等绘画,然后被称为paintBorders(),最后被称为paintChildren(),该方法将绘画组件内部的所有内容称呼它.

You were thinking along the right lines. Only problem was that you should have Overridden the paintChildren() method like in the code below. This is because the paintComponent() method is called as first and does the background etc painting of the component itself (the MyPanel), then is called paintBorders() and lastly the paintChildren() which paints all that is inside of the component calling it.

public class DrawOnTop {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("Draw on top");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new MyPanel());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

class MyPanel extends JPanel {

    public MyPanel() {
        setLayout(new BorderLayout(3, 3));
        JButton b1 = new JButton("Button 1");
        MouseListener ml = new MouseAdapter() {

            @Override
            public void mouseExited(MouseEvent e) {
                super.mouseExited(e);
                MyPanel.this.repaint();
            }
        };
        b1.addMouseListener(ml);
        JButton b2 = new JButton("Button 2");
        b2.addMouseListener(ml);
        add(b1, BorderLayout.NORTH);
        add(b2, BorderLayout.CENTER);
    }

    @Override
    protected void paintChildren(Graphics g) {
        super.paintChildren(g);
        g.setColor(Color.red);
        g.drawLine(0, 0, getVisibleRect().width, getVisibleRect().height);
    }
}

重要的注意,在代码示例中,我还添加了MouseListener以便在鼠标退出按钮时重新绘制面板,否则一旦鼠标进入按钮,按钮将始终停留在该行上方在其中之一上.

Important to notice, in the code sample, that I added also a MouseListener to repaint the panel when a mouse exits a button, otherwise the buttons would always stay over the line once mouse enters over one of them.

但是,如果您希望始终在组件的顶部进行自定义绘画,那么我建议您使用玻璃窗格. 玻璃窗格的使用示例在此处提供:

But if you want to have a custom painting that is always on top of your components then I would suggest to use a glass pane. Examples of a glass pane use are provided here:

  1. 简单的一个.
  2. 更复杂的一个.
  1. Simple one.
  2. A more complex one.

这篇关于在JPanel中的不透明组件上绘制自定义内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆