在Java组件上的图像绘制

时间:2016-05-07 12:49:24

标签: java image swing jlabel

我正在尝试创建一个绘制图形的简单应用程序......

package Tests.Drawing;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.EtchedBorder;

public class DrawingTest extends JFrame
{
    private Canvas drwArea;
    private JButton btnClear;

    public static void main(String[] args)
    {
        DrawingTest StartForm = new DrawingTest();
        StartForm.setVisible(true);
    }


    public DrawingTest()
    {
        //Window...
        this.setTitle("Drawing objects test00");
        this.setBounds(0,0,510,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(null);
        //Drawing area...
        drwArea = new Canvas();
        drwArea.setBounds(0, 0, 400, 450);      
        drwArea.setBackground(Color.WHITE);
        drwArea.setOpaque(true);
        drwArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
        drwArea.addMouseMotionListener(new MouseMotionAdapter()
        {
            @Override
            public void mouseDragged(MouseEvent e)
            {
                //Write code to paint on the image...
            }
        });

        this.getContentPane().add(drwArea);
        //Clear button...
        btnClear = new JButton("Clear");
        btnClear.setBounds(410,50,70,30);
        btnClear.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                //Write code to clear the image...
            }
        });

        this.getContentPane().add(btnClear);

    }

    private class Canvas extends JLabel
    {
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            //The idea of overriding this method is
            //achieving persistence...
        }
    }

}

我已经看到,要绘制的典型组件是Jlabel(顺便说一句,有没有更好的人?)。使用方法“getGraphics”我可以使用一个对象,它有几种方法在组件上绘制。我的问题是,不是直接在JLabel上绘画,而是想在图像上(在内存中)绘画,一旦绘画完成,将结果发送到JLabel。我怎样才能做到这一点?我有点失落......

提前致谢。

1 个答案:

答案 0 :(得分:2)

  

我想画一幅图像(在记忆中)

我建议你创建一个所需大小的BufferedImage对象,通过调用它上面的createGraphics()获取它的Graphics2D对象,并使用这个Graphics2D对象绘制它。

  

一旦绘画完成,将结果发送到JLabel

然后通过简单地调用

从上面的BufferedImage创建一个ImageIcon
Icon myIcon = new ImageIcon(myBufferedImage);

然后通过myLabel.setIcon(myIcon);

设置JLabel的图标

此外,您可以绘制到在JPanel的paintComponent方法中显示的BufferedImage,如果您想在程序运行时更新图像,这可能是更好的方法。有关这方面的更多信息,请查看一些these examples

其他评论:

  • 不要使用通过在组件上调用getGraphics()获得的Graphics对象进行绘制。这将返回一个短暂的Graphics对象,冒着消失的图形或者更糟的是NullPointerException。相反,直接或通过绘制BufferedImage(是的,您可以通过paintComponent(...)获取其Graphics对象)间接绘制JPanel的getGraphics()方法,然后将BufferedImage绘制到GUI在paintComponent方法中。
  • 虽然null布局和setBounds()似乎是Swing新手,比如创建复杂GUI的最简单和最好的方法,但是你创建的Swing GUI会越多,你会遇到更严重的困难使用它们时当GUI调整大小时,他们不会调整组件的大小,他们是增强或维护的皇室女巫,当他们放置在滚动窗格中时,他们完全失败,当他们在所有平台或屏幕分辨率不同时看起来很糟糕原来的。