[英]How to draw in JPanel? (Swing/graphics Java)
I'm working on a project in which I am trying to make a paint program.我正在做一个项目,我正在尝试制作一个绘画程序。 So far I've used Netbeans to create a GUI and set up the program.
到目前为止,我已经使用 Netbeans 创建了 GUI 并设置了程序。
As of right now I am able to call all the coordinated necessary to draw inside it but I am very confused with how to actually paint inside it.截至目前,我可以调用所有必要的协调来在其中绘制,但我对如何在其中实际绘制感到非常困惑。
Towards the end of my code I have a failed attempt at drawing inside the panel.在我的代码快结束时,我尝试在面板内绘图失败。
Can anyone explain/show how to use graphics in a example like this?任何人都可以在这样的示例中解释/展示如何使用图形吗?
All examples I have found make a class and extend it with JPanel
but I don't know if I can do this since it was generated in netbeans.我发现的所有示例都制作了 class 并使用
JPanel
扩展它,但我不知道我是否可以这样做,因为它是在 netbeans 中生成的。
I need to draw inside a
JPanel
, inside my JFrame
.我需要在
JPanel
内部,在我的JFrame
内部绘图。 I don't know where to put the graphics class.
我不知道把显卡 class 放在哪里。
package javapaint;
import java.awt.*;
import javax.swing.*;
public class JavaPaintUI extends javax.swing.JFrame {
public JavaPaintUI() {
initComponents();
}
private void initComponents() {
jPanel2 = new javax.swing.JPanel();
jPanel2.setBackground(new java.awt.Color(255, 255, 255));
jPanel2.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
jPanel2.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
jPanel2MousePressed(evt);
}
public void mouseReleased(java.awt.event.MouseEvent evt) {
jPanel2MouseReleased(evt);
}
});
jPanel2.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
jPanel2MouseDragged(evt);
}
});
pack();
}// </editor-fold>
int currentX, currentY, oldX, oldY;
private void jPanel2MouseDragged(java.awt.event.MouseEvent evt) {
if (tool == 1) {
currentX = evt.getX();
currentY = evt.getY();
oldX = currentX;
oldY = currentY;
System.out.println(currentX + " " + currentY);
System.out.println("PEN!!!!");
}
}
private void jPanel2MousePressed(java.awt.event.MouseEvent evt) {
oldX = evt.getX();
oldY = evt.getY();
System.out.println(oldX + " " + oldY);
}
//mouse released//
private void jPanel2MouseReleased(java.awt.event.MouseEvent evt) {
if (tool == 2) {
currentX = evt.getX();
currentY = evt.getY();
System.out.println("line!!!! from" + oldX + "to" + currentX);
}
}
//set ui visible//
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new JavaPaintUI().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel2;
// End of variables declaration
class jPanel2 extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("BLAH", 20, 20);
g.drawRect(200, 200, 200, 200);
}
}
}
The whole thing is a JFrame
and the white section in the center is jPanel2
which is what I want to draw on.整个东西是
JFrame
,中间的白色部分是jPanel2
,这是我想画的。
Note the extra comments.注意额外的注释。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
class JavaPaintUI extends JFrame {
private int tool = 1;
int currentX, currentY, oldX, oldY;
public JavaPaintUI() {
initComponents();
}
private void initComponents() {
// we want a custom Panel2, not a generic JPanel!
jPanel2 = new Panel2();
jPanel2.setBackground(new java.awt.Color(255, 255, 255));
jPanel2.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
jPanel2.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
jPanel2MousePressed(evt);
}
public void mouseReleased(MouseEvent evt) {
jPanel2MouseReleased(evt);
}
});
jPanel2.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent evt) {
jPanel2MouseDragged(evt);
}
});
// add the component to the frame to see it!
this.setContentPane(jPanel2);
// be nice to testers..
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}// </editor-fold>
private void jPanel2MouseDragged(MouseEvent evt) {
if (tool == 1) {
currentX = evt.getX();
currentY = evt.getY();
oldX = currentX;
oldY = currentY;
System.out.println(currentX + " " + currentY);
System.out.println("PEN!!!!");
}
}
private void jPanel2MousePressed(MouseEvent evt) {
oldX = evt.getX();
oldY = evt.getY();
System.out.println(oldX + " " + oldY);
}
//mouse released//
private void jPanel2MouseReleased(MouseEvent evt) {
if (tool == 2) {
currentX = evt.getX();
currentY = evt.getY();
System.out.println("line!!!! from" + oldX + "to" + currentX);
}
}
//set ui visible//
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new JavaPaintUI().setVisible(true);
}
});
}
// Variables declaration - do not modify
private JPanel jPanel2;
// End of variables declaration
// This class name is very confusing, since it is also used as the
// name of an attribute!
//class jPanel2 extends JPanel {
class Panel2 extends JPanel {
Panel2() {
// set a preferred size for the custom panel.
setPreferredSize(new Dimension(420,420));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("BLAH", 20, 20);
g.drawRect(200, 200, 200, 200);
}
}
}
HFOE put a good link as the first comment on this thread. HFOE 将一个很好的链接作为对该线程的第一条评论。 Camickr also has a description of active painting vs. drawing to a
BufferedImage
in the Custom Painting Approaches article. Camickr 在自定义绘画方法一文中还描述了主动绘画与绘制到
BufferedImage
。
See also this approach using painting in a BufferedImage
.另请参阅在
BufferedImage
中使用绘画的这种方法。
When working with graphical user interfaces, you need to remember that drawing on a pane is done in the Java AWT/Swing event queue .使用图形用户界面时,您需要记住在窗格上绘图是在Java AWT/Swing 事件队列中完成的。 You can't just use the
Graphics
object outside the paint()
/ paintComponent()
/etc.您不能只在
paint()
/ paintComponent()
/etc 之外使用Graphics
object。 methods.方法。
However, you can use a technique called " Frame buffering ".但是,您可以使用一种称为“帧缓冲”的技术。 Basically, you need to have a BufferedImage and draw directly on it (see it's
createGraphics()
method; that graphics context you can keep and reuse for multiple operations on a same BufferedImage
instance, no need to recreate it all the time, only when creating a new instance).基本上,您需要有一个BufferedImage并直接在其上绘制(请参阅它的
createGraphics()
方法;您可以保留并重用该图形上下文以在同一个BufferedImage
实例上进行多个操作,无需一直重新创建它,仅在创建时一个新实例)。 Then, in your JPanel
's paintComponent()
, you simply need to draw the BufferedImage
instance unto the JPanel
.然后,在您的
JPanel
的paintComponent()
中,您只需将BufferedImage
实例绘制到JPanel
即可。 Using this technique, you can perform zoom, translation and rotation operations quite easily through affine transformations .使用这种技术,您可以通过仿射变换非常轻松地执行缩放、平移和旋转操作。
Here is a simple example.这是一个简单的例子。 I suppose it will be easy to understand:
我想这很容易理解:
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Graph extends JFrame {
JFrame f = new JFrame();
JPanel jp;
public Graph() {
f.setTitle("Simple Drawing");
f.setSize(300, 300);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
jp = new GPanel();
f.add(jp);
f.setVisible(true);
}
public static void main(String[] args) {
Graph g1 = new Graph();
g1.setVisible(true);
}
class GPanel extends JPanel {
public GPanel() {
f.setPreferredSize(new Dimension(300, 300));
}
@Override
public void paintComponent(Graphics g) {
//rectangle originates at 10,10 and ends at 240,240
g.drawRect(10, 10, 240, 240);
//filled Rectangle with rounded corners.
g.fillRoundRect(50, 50, 100, 100, 80, 80);
}
}
} }
And the output looks like this: output 看起来像这样:
Variation of the code by Bijaya Bidari that is accepted by Java 8 without warnings in regard with overridable method calls in constructor: Bijaya Bidari 的代码变体被 Java 8 接受,没有关于构造函数中可覆盖方法调用的警告:
public class Graph extends JFrame {
JPanel jp;
public Graph() {
super("Simple Drawing");
super.setSize(300, 300);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
jp = new GPanel();
super.add(jp);
}
public static void main(String[] args) {
Graph g1 = new Graph();
g1.setVisible(true);
}
class GPanel extends JPanel {
public GPanel() {
super.setPreferredSize(new Dimension(300, 300));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//rectangle originated at 10,10 and end at 240,240
g.drawRect(10, 10, 240, 240);
//filled Rectangle with rounded corners.
g.fillRoundRect(50, 50, 100, 100, 80, 80);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.