【问题标题】:Paint over the top of a swing Icon?在秋千图标的顶部绘画?
【发布时间】:2021-05-03 02:32:47
【问题描述】:

我正在渲染一堆包含图标的 JLabel。我想通过在它们的顶部绘制某种线条或符号来有条件地注释这些图标。是否可以在摇摆的图标上绘制?我的 JLabel 如下所示的示例:

我用来封装包含我的 JLabels 的 waypoint 组件的类:

/**
 * Waypoint to be drawn on the map
 */
public class Waypoint extends DefaultWaypoint {
    protected JLabel label;
    private final long id;
    private final EntityType type;

    public Waypoint( long id ) {
        this.id = id;
        this.type = null;
        this.label = null;
    }

    public Waypoint( long id, EntityType type, Location coord ) {
        super( locToGeoPos(coord) );
        this.id = id;
        this.type = type;
        this.label = new JLabel();
    }

    public void setIcon( ImageIcon icon ) {
        label = new JLabel( icon, JLabel.CENTER );
        label.setBorder( new LineBorder(Color.BLACK) );

      }

    public void setBackgroundColor( Color bgrColor ) {
        label.setOpaque( true );
        label.setBackground( bgrColor );
    }

    public void setToolTipText( String tooltipText ) {
        label.setToolTipText( "<html>" + tooltipText + "</html>" );
    }

    public JLabel getLabel() {
        return label;
    }

    public void annotateIcon() {
        // TODO
    }

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 是的,可以创建一个扩展 JLabel 的类,然后覆盖 paintComponent 方法。这里是“官方”教程:docs.oracle.com/javase/tutorial/uiswing/painting/index.html
  • JLabel 是一个复杂的组件,它处理文本、图像和各种对齐选项,尝试扩展它以提供自定义“覆盖”可能不是您可用的最佳解决方案。就个人而言,我会考虑创建一个新图像,使用基本图像和您想要覆盖的任何其他内容,并将其分配给标签,它会为您提供更高级别的自定义,并且通常会更容易
  • 是否可以在 swing 中的图标上绘图? - 您可以使用Compound Icon。它将允许您在原始图标之上绘制第二个图标。

标签: java swing paintcomponent


【解决方案1】:

是的,有可能:

        Image img = ImageIO.read(new File("IMAGE PATH HERE"));
        ImageIcon icon = new ImageIcon(img);

        JLabel label = new JLabel(icon, JLabel.CENTER) {

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.RED);
                g.drawOval(0, 0, 10, 10);
            }
        };

在这里,我重写了JLabel 类的paintComponent 方法。 super.paintComponent(); 行将执行组件的默认绘制。我们只是在它上面涂漆。

【讨论】:

  • 请注意,在我们进行自定义绘画之前,您可以/应该调用super.paintComponent(g); 来执行正常绘画,这也将允许正确绘制边框,并将使用正常方式设置之前的任何图像。
  • 请注意,您的代码仍将绘制在任何先前设置的 JLabel 边框之上。 OP 确实在他的代码中设置了一个不起作用的边框,而是需要在绘制图像后使用g.drawRect(...) 手动绘制边框。
  • 请注意,JLabel 是一个复杂的组件,它处理文本、图像和各种对齐属性 - 以 JLabel 开头可能不是“最佳”长期解决方案
  • g.drawImage(img, 0, 0, null); 应该是 g.drawImage(img, 0, 0, this);
  • (1-) 因为我们现在只需要使用图像 - 不,你不需要。 super.paintComponent() 将绘制标签的图标。如果要同时绘制图像和椭圆,则应扩展 JComponent 或 JPanel,以免继承 JLabel 自定义绘制。
【解决方案2】:

是的,你可以这样做。这是一个完整的工作示例。您可以根据需要缩放图标。这将绘制图像。等待 2 秒,然后在图像上绘制一条对角红线。

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class DrawingOverIcon extends JPanel {
    
    
    static JFrame f = new JFrame();
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(500, 500);
    }
    
    public static void main(String[] args) {
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DrawingOverIcon doi = new DrawingOverIcon();
        ImageIcon icon = new ImageIcon("f:/download.png");
        JLabel label = new JLabel(icon);
        doi.setBackground(Color.white);
        f.add(doi);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        
        doi.add(label);
        doi.repaint();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ie) {
        }

        // From here down is what you would do to modify the
        // icon.
        Image image = icon.getImage();
        BufferedImage bi = new BufferedImage(image.getWidth(null),
                image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
        
        Graphics2D g2d =
                (Graphics2D) bi.getGraphics();
        g2d.drawImage(image,0,0,null);
        g2d.setStroke(new BasicStroke(10));
        g2d.setColor(Color.RED);
        g2d.drawLine(0, 0, 500, 500);
        icon.setImage(bi);
        doi.repaint();
    }
    
}

【讨论】:

  • 如果您只需要在应用程序期间绘制一次图像,这是一个非常有效的解决方案。要稍后恢复/更改图像,只需再次从文件中加载它并根据需要进行更改。
猜你喜欢
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-26
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多