在 Java 组件上绘制的图像
Image drawing on a Java component
我正在尝试创建一个绘制图形的简单应用程序...
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。我怎样才能做到这一点?我有点迷路...
提前致谢。
I would like to paint on an image (in memory)
我建议您然后创建一个所需大小的 BufferedImage 对象,通过对其调用 createGraphics()
获取其 Graphics2D 对象,并使用此 Graphics2D 对象在其上绘制。
and once the painting has finished, send the result to the JLabel
然后通过简单地调用
从上面的 BufferedImage 创建一个 ImageIcon
Icon myIcon = new ImageIcon(myBufferedImage);
然后通过 myLabel.setIcon(myIcon);
设置 JLabel 的图标
您还可以绘制到在 JPanel 的 paintComponent 方法中显示的 BufferedImage,如果您想在程序运行时更新图像,这可能是更好的方法 运行ning。有关更多信息,请查看 these examples.
中的一些内容
其他评论:
- 不要使用通过在组件上调用
getGraphics()
获得的 Graphics 对象进行绘制。这将 return 一个短暂的 Graphics 对象,冒着消失图形或更糟的风险,一个 NullPointerException。相反,直接或通过在 BufferedImage 上绘制(是的,您可以通过 getGraphics()
获取其 Graphics 对象)间接绘制 JPanel 的 paintComponent(...)
方法,然后在 paintComponent 方法中将 BufferedImage 绘制到 GUI .
- 虽然空布局和
setBounds()
对于 Swing 新手来说似乎是创建复杂 GUI 的最简单和最好的方法,但您创建的 Swing GUI 越多,您在使用时 运行 遇到的困难就越严重他们。它们不会在 GUI 调整大小时调整组件的大小,它们是皇家 来增强或维护的,当放置在滚动窗格中时它们会完全失效,当在所有平台或不同的屏幕分辨率上查看时它们看起来很糟糕从原来的。
我正在尝试创建一个绘制图形的简单应用程序...
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。我怎样才能做到这一点?我有点迷路...
提前致谢。
I would like to paint on an image (in memory)
我建议您然后创建一个所需大小的 BufferedImage 对象,通过对其调用 createGraphics()
获取其 Graphics2D 对象,并使用此 Graphics2D 对象在其上绘制。
and once the painting has finished, send the result to the JLabel
然后通过简单地调用
从上面的 BufferedImage 创建一个 ImageIconIcon myIcon = new ImageIcon(myBufferedImage);
然后通过 myLabel.setIcon(myIcon);
您还可以绘制到在 JPanel 的 paintComponent 方法中显示的 BufferedImage,如果您想在程序运行时更新图像,这可能是更好的方法 运行ning。有关更多信息,请查看 these examples.
中的一些内容其他评论:
- 不要使用通过在组件上调用
getGraphics()
获得的 Graphics 对象进行绘制。这将 return 一个短暂的 Graphics 对象,冒着消失图形或更糟的风险,一个 NullPointerException。相反,直接或通过在 BufferedImage 上绘制(是的,您可以通过getGraphics()
获取其 Graphics 对象)间接绘制 JPanel 的paintComponent(...)
方法,然后在 paintComponent 方法中将 BufferedImage 绘制到 GUI . - 虽然空布局和
setBounds()
对于 Swing 新手来说似乎是创建复杂 GUI 的最简单和最好的方法,但您创建的 Swing GUI 越多,您在使用时 运行 遇到的困难就越严重他们。它们不会在 GUI 调整大小时调整组件的大小,它们是皇家 来增强或维护的,当放置在滚动窗格中时它们会完全失效,当在所有平台或不同的屏幕分辨率上查看时它们看起来很糟糕从原来的。