Graphics2D 和 JComponent

发布于 2024-12-18 13:49:52 字数 956 浏览 3 评论 0原文

我没怎么用过Swing/G2D,所以请耐心等待。 我有以下类,它是我的 GUI 上的一个组件(意味着是一种可以绘制的 Canvas):

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 上。

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

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

I have not used Swing/G2D much, so please be patient.
I have the following class which is a component on my GUI (meant to be a kind of Canvas to draw on):

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

I have been trying to add the following to the above 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);          
}
}

The BrushStroke does not show on the DrawPanel.

I have been searching forever for an answer, and each example I look at seems to be contradictory.

If anybody has attempted what I am, then help would be greatly appreciated. Also, if I am taking the completely wrong approach, please do say.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷月断魂刀 2024-12-25 13:49:52
  1. 您永远不应该以任何绘画方法将组件添加到面板。每当 Swing 确定需要绘制组件时,就会调用绘制方法。因此,您将多次将组件添加到面板。

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

有关详细信息,请阅读 Swing 教程中关于 自定义绘制 的部分和例子。

  1. You should never add a component to a panel in any painting method. The painting methods are invoked whenever Swing determines a component needs to be painted. Therefore you would be adding the component to the panel multiple times.

  2. When you do custom painting you are responsible for overriding the getPreferredSize() method to give the size of the component. This way the layout managers can position the components properly. If you don't do this then the preferred size is 0, so there is nothing to paint.

Read the section from the Swing tutorial on Custom Painting for more information and examples.

无言温柔 2024-12-25 13:49:52

JComponent.add 方法上,文档 说:

注意:如果一个组件被添加到一个已经被
显示,必须在该容器上调用 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);
    }
}

输出给出以下内容:

在此处输入图像描述

On the JComponent.add method, the documentation says:

Note: If a component has been added to a container that has been
displayed, validate must be called on that container to display the
new component. If multiple components are being added, you can improve
efficiency by calling validate only once, after all the components
have been added.

You should refresh your DrawPanel after adding an element to it. Watch out not to do it in the painComponent method, you will end up in an infinite recursion.

Do the following instead:

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

EDIT
Here is a fully working solution (extending JPanels instead of 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);
    }
}

The output gives the following:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文