3

我使用 Swing/G2D 的次数不多,所以请耐心等待。我有以下类,它是我的 GUI 上的一个组件(意味着是一种画布):

import javax.swing.*;
import java.awt.*;

public class DrawPanel extends JComponent{
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;

    g2.setPaint(Color.black);
    g2.fillRect(0, 0, getWidth(), getHeight());

    BrushStroke bs = new BrushStroke();     
    add(bs);
}
}

我一直在尝试将以下内容添加到上面的 JComponent 中:

import javax.swing.*;
import java.awt.*;

public class BrushStroke extends JComponent{
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setPaint(Color.red);
    g2.fillOval(0, 0, 10, 10);          
}
}

BrushStroke 不会显示在 DrawPanel 上。

我一直在寻找答案,我看到的每个例子似乎都是矛盾的。

如果有人尝试过我的工作,那么将不胜感激。另外,如果我采取了完全错误的方法,请说。

4

2 回答 2

3
  1. 您永远不应该以任何绘画方法将组件添加到面板。每当 Swing 确定需要绘制组件时,就会调用绘制方法。因此,您将多次将组件添加到面板中。

  2. 当您进行自定义绘制时,您负责覆盖 getPreferredSize() 方法以提供组件的大小。这样布局管理器可以正确定位组件。如果您不这样做,则首选大小为 0,因此无需绘制任何内容。

阅读 Swing 教程中关于自定义绘画的部分以获取更多信息和示例。

于 2011-11-28T22:23:26.007 回答
2

关于JComponent.add方法,文档说:

注意:如果组件已添加到已显示的容器中,则必须在该容器上调用 validate 以显示新组件。如果要添加多个组件,您可以通过在添加所有组件后仅调用一次 validate 来提高效率。

向 DrawPanel 添加元素后,您应该刷新它。注意不要在painComponent方法中这样做,您将最终陷入无限递归。

请改为执行以下操作:

DrawPanel drawPanel = new DrawPanel();
drawPanel.add(new BrushStroke());
drawPanel.repaint();

编辑 这是一个完全有效的解决方案(扩展 JPanels 而不是 JComponent)

public static void main(String[] args){
   JFrame frame = new JFrame();
   DrawPanel drawPanel = new DrawPanel();
   drawPanel.add(new BrushStroke());
   frame.getContentPane().add(drawPanel);
   frame.pack();
   frame.setVisible(true);
}
class DrawPanel extends JPanel{
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(Color.black);
        g2.fillRect(0, 0, getWidth(), getHeight());
    }
    @Override
    public  Dimension getPreferredSize(){
        return new Dimension(100, 100);
    }
}
class BrushStroke extends JPanel{
    public void paintComponent(Graphics g){
        this.setOpaque(false);
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.red);
        g2.fillOval(0, 0, 10, 10); 
    }
    @Override
    public  Dimension getPreferredSize(){
        return new Dimension(10, 10);
    }
}

输出给出以下信息:

在此处输入图像描述

于 2011-11-28T20:08:11.677 回答