如何在JPanel上的JLabel上“绘画”?

4
我有一组JLabels,每个JLabel都通过setText()方法包含一个字母,不透明度和背景设置为白色,在一个GridLayout的JPanel上,使标签形成表格。 我正在进行简单的动画,突出显示某些行和列,然后是它们的交叉点。我可以使用标签的setBackground()来实现这个目的,但我认为如果能够使用Graphics对象(可能是绘制一个围绕交叉点的圆,然后清除它),就会有更多的“选择”。 我试图扩展JLabel或直接在JPanel上绘制(在一个方法中使用getGraphics()),但它没有起作用,我认为在这种情况下绘图在标签后面。我无法弄清楚“绘画”代码应该放在哪里,在任何情况下都没有出现在屏幕上。
简而言之,像以下方法一样,可以用于在标签上方绘制吗? 它应该是JLabel还是JPanel的方法?
public void drawsomething() {
    Graphics2D g2d = (Graphics2D) getGraphics();
    g2d.fillRect(100, 100, 100, 100);
    }

4
我不确定您尝试实现的确切效果,但听起来最好的方法是在JLabel的paintComponent(...)方法中绘制。为什么不创建一个sscce,展示一下您尝试过的内容呢? - Hovercraft Full Of Eels
2
我错在哪里了?请编辑您的问题并添加一个SSCCE - mKorbel
1
请明确表达您要做什么,而不是讲一个长故事。 - Juvanis
1
抱歉讲了这么多,本来不是故意的。 - maximz101
1
@kleopatra,我并不是在抱怨什么。我只是想说像“不要这样做,不要那样做”这样的泛泛而谈的评论并没有太大的帮助。而像“注意getGraphics方法,参见讨论[链接]”这样的表达方式更能传达你想要表达的信息。 - dm76
显示剩余5条评论
4个回答

4
如果您重写了paintChildren()方法,会发生什么?
protected void paintChildren(Graphics g) {
  super.paintChildren(g);
//paint your lines here
}

如果我将绘图代码放在JPanel的paintChildren()中,绘图将会显示。但是如果我想在方法调用时绘制和删除,如何在paintChildren()之外获取子级图形上下文呢?或者我应该将绘画代码放在paintChildren()中,并依靠条件每次进行绘制/删除吗? - maximz101
我不确定您想要实现什么,但您可以将所有内容绘制在BufferedImage中并使用它。 - StanislavL
我只是想编写能够在JLabel网格上绘制并清除的方法(例如drawSomething(x, y)),作为动画的一部分。 你所说的“使用”BufferedImage,是指在绘制后将其添加到面板中吗? - maximz101
你可以使用JLayeredPane相对容易地实现drawSomething(x,y),请参考我的答案。 - dm76

3

2

我还不太了解绘图方面的知识,但是我为您创建了一个小的样例代码,希望您能从中获取一些信息。为了在 JLabel 上绘画,您可以使用它的 paintComponent(Graphics g) 方法。

示例代码:

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

public class DrawingOnJLabel extends JFrame
{
    private CustomLabel label;
    private int flag = 1;
    private JPanel contentPane;

    public DrawingOnJLabel()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        contentPane = new JPanel();
        contentPane.setBackground(Color.WHITE);
        label = new CustomLabel(200, 200);
        label.setLabelText("A");
        label.setValues(50, 50, 100, 100, 240, 60);

        final JButton button = new JButton("CLEAR");
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        if (flag == 1)              
                        {
                            label.setFlag(flag);
                            flag = 0;
                            button.setText("REPAINT");
                            contentPane.revalidate();
                            contentPane.repaint();
                        }   
                        else if (flag == 0) 
                        {
                            label.setFlag(flag);
                            flag = 1;
                            button.setText("CLEAR");
                            contentPane.revalidate();
                            contentPane.repaint();
                        }
                    }
                });
            }
        });     

        contentPane.add(label);

        add(contentPane, BorderLayout.CENTER);
        add(button, BorderLayout.PAGE_END);
        setSize(300, 300);
        setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new DrawingOnJLabel();
            }
        });
    }
}

class CustomLabel extends JLabel
{
    private int sizeX;
    private int sizeY;
    private int x, y, width, height, startAngle, arcAngle;
    private int flag = 0;
    private String text;

    public CustomLabel(int sX, int sY)
    {
        sizeX = sX;
        sizeY = sY; 
    }

    // Simply call this or any set method to paint on JLabel.
    public void setValues(int x, int y, int width, int height, int startAngle, int arcAngle)
    {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.startAngle = startAngle;
        this.arcAngle = arcAngle;
        repaint();
    }

    public void setFlag(int value)
    {
        flag = value;
        repaint();
    }

    public Dimension getPreferredSize()
    {
        return (new Dimension(sizeX, sizeY));
    }

    public void setLabelText(String text)
    {
        super.setText(text);
        this.text = text;
        flag = 0;
        repaint();
    }

    public void paintComponent(Graphics g)
    {
        if (flag == 0)
        {
            g.setColor(Color.RED);          
            g.drawString(text, 20, 20);
            g.setColor(Color.BLUE);
            g.drawOval(x, y, width, height);
            g.fillOval(x + 20, y + 20, 15, 15);
            g.fillOval(x + 65, y + 20, 15, 15);
            g.fillRect(x + 40, y + 40, 5, 20);
            g.drawArc(x + 20, y + 30, 55, 55, startAngle, arcAngle);            
        }
        else if (flag == 1)
        {
            g.clearRect(x, y, width, height);
        }
    }
}

@Tommy:很高兴这个例子有所帮助。谢谢你的赞赏,祝你和其他人保持微笑 :-) - nIcE cOw

0
使用paintComponent(Graphics g)而不是paint(Graphics g)。这将覆盖GUI的绘制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接