Java Swing:在 JPanel 的组件下绘制?

Posted

技术标签:

【中文标题】Java Swing:在 JPanel 的组件下绘制?【英文标题】:Java Swing: paint under components of a JPanel? 【发布时间】:2012-06-19 23:54:45 【问题描述】:

我有一个 JPanel,里面有一个按钮。按钮的位置无关紧要。 paint(Graphics g) 代码是:

@覆盖 公共无效油漆(图形g) super.paint(g); /* 绘制代码 */

如果我想用黑色矩形填充面板的整个空间,同时面板中还有按钮,填充的矩形将简单地覆盖所有内容。所以不是有一个按钮,然后按钮周围都是黑色的,整个面板都是黑色的。

有什么办法可以修改面板,或者绘画过程,让组件绘制在自定义绘画之上?

我曾尝试将super.paint(g) 放在绘画的末尾,例如:

@覆盖 公共无效油漆(图形g) /* 绘制代码 */ super.paint(g);

... 认为它会先进行自定义绘画,然后简单地将组件放在上面。但是,如果这样做,自定义绘画将完全消失,只显示按钮。也就是说,只有一个按钮和一个白色(默认)背景,而不是黑色矩形。

有什么想法吗?

谢谢!

编辑: 我想澄清一下黑色矩形是一个例子。我知道我可以简单地设置背景颜色,但我试图最终能够做任何我想做的自定义绘画。

【问题讨论】:

再说一次,你想达到什么目的?一个按钮,因为它被黑色覆盖,所以看不到?如果有,目的是什么? 我正在尝试制作一个具有自定义绘画但也使用基本 Swing 组件的菜单。我意识到我可以做 setBackground(..) 但它不允许我自定义绘画。而且,据我所知,如果菜单是纯色且无法与之交互,它们就不是很有趣。 【参考方案1】:

我认为您想覆盖 paintComponent() 而不是 paint()

paint() 通常不做任何绘画,而是委托给paintComponent()paintBorder()paintChildren()

查看javax.swing.JComponent.paint()了解更多信息

例子:

  @Override
  public void paintComponent(Graphics g) 
    /* your draw code here */
  

你可以调用 super.paintComponent(g);像往常一样绘制组件,但可以省略。

【讨论】:

+1 作为参考,“Swing 程序应该覆盖paintComponent() 而不是覆盖paint()。”—Painting in AWT and Swing: The Paint Methods 是的!这正是我需要的。非常感谢! 你能举个例子吗?我有同样的问题,我无法让它工作。【参考方案2】:

您可以将面板的背景设置为黑色并调整 UI 委托的颜色。您可以setBorderPainted(false) 并根据需要突出显示该按钮。这是一个sscce,可以在需要时更新您的问题。这个AnimationTest 展示了paintComponent() 如何更新面板“后面的”组件。

附录:首先放置super.paintComponent(g) 将确保组件看起来覆盖在(可能发生变化的)背景上。由于组件的背景颜色受其 UI 委托的控制,因此您可以执行以下任何操作:

使用UIManager更改对应的属性,如下图。 使用覆盖paintComponent()的自定义JButton,如here所示。 使用自定义 UI 委托,如 here 所示。

SSCCE:

import component.Laf;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

/** @see https://***.com/a/11075785/230513 */
public class ButtonPanel extends JPanel 

    public ButtonPanel() 
        this.setBackground(Color.black);
        final JButton b = new JButton(new AbstractAction("Button")

            @Override
            public void actionPerformed(ActionEvent e) 
                System.out.println("Clicked");
            
        );
        // b.setBorderPainted(false);
        this.add(b);
    

    private void display() 
        UIManager.put("Button.foreground", Color.white);
        UIManager.put("Button.background", Color.black);
        JFrame f = new JFrame("ButtonPanel");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    

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

            @Override
            public void run() 
                new ButtonPanel().display();
            
        );
    

【讨论】:

但是如果我想做的不仅仅是设置背景颜色,我该如何让它发挥作用呢?我的目标是做自定义绘画,黑色矩形只是一个例子。 我已经链接到上面一个更复杂的例子。 现在看。欣赏它。

以上是关于Java Swing:在 JPanel 的组件下绘制?的主要内容,如果未能解决你的问题,请参考以下文章

java swing编程问题:一个jframe中添加一个jpanel后,为jpanel添加一个滚动条,当jpanel中内容过多时滑动

Java 每次把一个Swing组件放在一个JPanel中时,总是放在左边,有啥办法让其放在面板中间?

从 Java Swing 组件中检索对象

Swing:如何在每个组件、JPanel、JButton 等上绘制动画?

Java Swing - 如何更改 JPanel 的 TitledBorder 上的字体大小?

如何在Java Swing中创建响应式JList