Java 如何用 Swing 制作画布?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/776180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make canvas with Swing?
提问by
I'm trying to make a paint editor with Java in which I have a toolbar with the objects that I would like to paste in the canvas. I'm using Swing components to make the GUI, but when I looked for the way of making the canvas, I only found the class canvas from AWT.
我正在尝试使用 Java 制作一个绘图编辑器,其中我有一个工具栏,其中包含我想粘贴到画布中的对象。我正在使用 Swing 组件来制作 GUI,但是当我寻找制作画布的方法时,我只找到了 AWT 中的类画布。
Is there any way to make something similar to canvas with Swing? (for example, JPanel?) I have read that using the class canvas from AWT with a GUI made with swing won't work correctly, is that true?
有没有办法用 Swing 制作类似于画布的东西?(例如,JPanel?)我读过使用 AWT 的类画布和用 Swing 制作的 GUI 将无法正常工作,是真的吗?
回答by coobird
You'll probably want to make a subclass of JPanel
and implement your own way of painting components you want to draw onto the panel.
您可能希望创建一个子类JPanel
并实现您自己的方式来绘制要绘制到面板上的组件。
The basic approach will probably be along the line of assigning a MouseListener
to the subclass of JPanel
, then implement painting functionality.
基本方法可能是将 a 分配MouseListener
给 的子类JPanel
,然后实现绘画功能。
The basic idea may be something along the line of:
基本思想可能是这样的:
class MyCanvas extends JPanel implements MouseListener
{
Image img; // Contains the image to draw on MyCanvas
public MyCanvas()
{
// Initialize img here.
this.addMouseListener(this);
}
public void paintComponent(Graphics g)
{
// Draws the image to the canvas
g.drawImage(img, 0, 0, null);
}
public void mouseClicked(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
Graphics g = img.getGraphics();
g.fillOval(x, y, 3, 3);
g.dispose();
}
// ... other MouseListener methods ... //
}
The above example is incomplete (and not tested -- it definitely won't compile), but it gives an idea about how to implement a MyCanvas
class in which a user can click on and draw circles.
上面的例子是不完整的(并且没有经过测试——它肯定不会编译),但它提供了一个关于如何实现MyCanvas
一个用户可以点击并绘制圆圈的类的想法。
The img
object is used to hold the image of the canvas. The paintComponent
method is used to paint the img
object to the canvas. In the mouseClicked
method, the Graphics
object associated with img
is retrieved in order to fillOval
onto the image.
该img
对象用于保存画布的图像。该paintComponent
方法用于将img
对象绘制到画布上。在该mouseClicked
方法中,检索Graphics
与之关联的对象img
以fillOval
将其添加到图像上。
Since one the requirements is to paste images onto the canvas, it may be a good idea to hold some Image
s that you want to paste into the canvas. Perhaps something along the line of:
由于其中一个要求是将图像粘贴到画布上,因此保留一些Image
要粘贴到画布中的 s可能是个好主意。也许是这样的:
Image[] myImages; // Used to store images to paint to screen.
Then, in the routine to paint the image onto img
stored in MyCanvas
:
然后,在将图像绘制到img
存储在的例程中MyCanvas
:
g.drawImage(myImage[INDEX_OF_DESIRED_IMAGE], 0, 0, null);
By using the drawImage
method of the Graphics
object, other Image
s can be drawn onto Image
s.
通过使用对象的drawImage
方法,可以将Graphics
其他Image
s绘制到Image
s上。
As for the question on AWT and Swing, yes, it is true that you do not want to mix components from the AWT and Swing, as they differ in the way they render GUI components. AWT is based on heavyweight components, meaning they native windowing for painting the GUI, while Swing is based on lightweight components, meaning the GUI is drawn by Java itself without using native components.
至于关于 AWT 和 Swing 的问题,是的,您确实不想混合来自 AWT 和 Swing 的组件,因为它们呈现 GUI 组件的方式不同。AWT 基于重量级组件,这意味着它们用于绘制 GUI 的本机窗口,而 Swing 基于轻量级组件,这意味着 GUI 是由 Java 本身绘制的,不使用本机组件。
A good guide on the difference of AWT and Swing is provided in Painting in AWT and Swingarticle from Sun.
Sun 的Paint in AWT 和 Swing文章中提供了有关 AWT 和 Swing 区别的良好指南。
回答by jjnguy
In order to make a custom 'Canvas' in swing you usually write a subclass of a JPanel
. Then, you must overwrite the protected paintComponent(Graphics g)
method of JPanel
.
为了在 Swing 中制作自定义的“画布”,您通常会编写JPanel
. 然后,您必须覆盖 的protected paintComponent(Graphics g)
方法JPanel
。
In the paint method, you can call methods on the Graphics
object to actually draw on the JPanel
.
在paint方法中,您可以调用Graphics
对象上的方法来实际在JPanel
.
As always, the Java Tutorials have a great referenceon this to get you started.
与往常一样,Java 教程在这方面有很好的参考,可以帮助您入门。
回答by Tom Hawtin - tackline
Simply subclass JComponent
.
只是子类JComponent
。
JPanel
is an inappropriate class. It is often suggested as it appears to have setOpaque(true)
invoked on it automatically. It's actually the PL&F which does that, and whether or not it actually happens is implementation and vendor dependent.
JPanel
是一个不合适的类。通常建议使用它,因为它似乎已setOpaque(true)
自动调用它。它实际上是 PL&F 这样做的,它是否真的发生取决于实现和供应商。
Canvas
is a heavyweight component. That is to say that it is controlled by the underlying windowing system. The result is that it will typically be drawn over the top of Swing components, without respect to z-order or clipping (putting it in a scroll pane will give odd behaviour).
Canvas
是一个重量级的组件。也就是说它是由底层的窗口系统控制的。结果是它通常会被绘制在 Swing 组件的顶部,而不考虑 z 顺序或裁剪(将它放在滚动窗格中会产生奇怪的行为)。
回答by Tom Hawtin - tackline
You might want to look at the Minueto API. It is a very simple to use graphics api, and you can combine the Java event listening with it to provide your drawing capability.
您可能想查看 Minueto API。它是一个非常简单易用的图形 api,您可以将 Java 事件侦听与其结合以提供您的绘图能力。