HOWTO · Java

使用 Java Swing 创建画布

本文演示了如何使用 Java Swing 制作画布并在其上绘制形状。

本页内容

在 Java 中,我们可以通过两种方式制作画布,使用 Java AWT 或 Java Swing。今天,我们将学习如何使用 Java Swing 制作画布并绘制形状。

使用 Java Swing 创建画布

示例代码(PaintPanel.java 类):

// write your package here
package com.voidtesting.canvas;
// import necessary libraries
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JPanel;

public class PaintPanel extends JPanel {
  // count the number of points
  private int pointCounter = 0;
  // array of 10000 Point references
  private Point[] points = new Point[10000];

  // make GUI and register the mouse event handler
  public PaintPanel() {
    // handles frame mouse motion event
    addMouseMotionListener(new MouseMotionAdapter() {
      // store the drag coordinates and repaint
      @Override
      public void mouseDragged(MouseEvent event) {
        if (pointCounter < points.length) {
          // find points
          points[pointCounter] = event.getPoint();
          // increment point's number in the array
          ++pointCounter;
          // repaint JFrame
          repaint();
        } // end if
      } // end mouseDragged method
    } // end anonymous inner class
    ); // end call to the addMouseMotionListener
  } // end PaintPanel constructor

  /*
  draw oval in a 5 by 5 bounding box at the given location
  on the window
  */
  @Override
  public void paintComponent(Graphics g) {
    // clear drawing area
    super.paintComponent(g);
    // draw all points that we have in array
    for (int i = 0; i < pointCounter; i++) g.fillOval(points[i].x, points[i].y, 5, 5);
  } // end paintComponent method
} // end PaintPanel Class

示例代码(Canvas.java 类):

// write your package here
package com.voidtesting.canvas;
// import necessary libraries
import java.awt.BorderLayout;
import java.awt.Label;
import javax.swing.JFrame;

public class Canvas {
  public static void main(String[] args) {
    // create JFrame Object
    JFrame jFrame = new JFrame("Canvas Using Java Swing");
    // create PaintPanel Object
    PaintPanel paintPanel = new PaintPanel();
    // add paintPanel in center
    jFrame.add(paintPanel, BorderLayout.CENTER);
    // place the created label in the south of BorderLayout
    jFrame.add(new Label("Drag the mouse to draw"), BorderLayout.SOUTH);
    // exit on close
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // set frame size
    jFrame.setSize(500, 400);
    // set jFrame location to center of the screen
    jFrame.setLocationRelativeTo(null);
    // display frame
    jFrame.setVisible(true);
  }
}

输出:

使用 java swing 制作画布 - 在画布上绘制

在 PaintPanet.java 类中,它扩展 JPanel 以创建用于绘制的承诺区域。Point 类表示 x 和 y 坐标。

我们创建一个 Point 类的对象来保存每个鼠标拖动事件的所有坐标,而 Graphics 类用于绘制。在这个例子中,我们使用一个 Point 类型的数组,其中包含 10,000 个点/坐标,用于存储每个鼠标拖动事件发生的位置。

我们可以看到 paintComponent 使用这些坐标进行绘制。请注意,名为 pointCounter 的实例变量仍然跟踪通过鼠标拖动事件捕获的点总数。

一旦它达到 10,000 的上限,我们就不能再画了。

然后,我们注册可以监听 PaintPanel 类的鼠标移动事件的 MouseMotionListener。在 addMouseMotionListener() 监听器中,我们创建了一个匿名内部类的对象,该对象扩展名为 MouseMotionAdapter 的适配器类。

为什么我们要覆盖 mouseDragged?因为 MouseMotionAdapter 实现 MouseMotionListener,匿名内部类对象是 MouseMotionListener。匿名内部类继承了默认的 mouseMoved 和 mouseDragged 实现。

所以,它已经实现了接口的所有方法。但是,无论何时调用默认方法,它们都不执行任何操作,这就是为什么我们覆盖 mouseDragged 以捕获鼠标拖动事件的点并将它们保存为 Point 对象。

if 语句确保我们只在有容量的情况下保存数组中的点。调用 getPoint() 方法来检索事件发生的坐标,将它们保存在索引 pointCounter 处的 points 数组中,然后也增加 pointCounter。

在发出 if 语句之前,我们使用 repaint() 方法来处理对绘制周期的更新。接下来,paintComponent 方法接收 Graphics 的参数,只要 PaintPanel 必须显示在计算机屏幕上,该参数就会自动调用。

在 paintComponent 方法中,我们调用 paintComponent 的超类来清除绘图区域。请记住,我们使用 super 关键字来访问超类的方法和实例。

我们在给定位置通过数组中的每个点绘制一个 5 x 5 椭圆形,它可以上升到 pointCounter,而 fillOval() 方法绘制实心椭圆形。

现在,来到主类 Canvas.java。它创建了 JFrame 和 PaintPanel 的对象。

然后,我们使用 add() 方法将 PaintPanel 的对象添加到 JFrame 窗口的中心。我们使用 BorderLayout.CENTER 将其添加到 JFrame 窗口的中心。

接下来,我们使用 BorderLayout.SOUTH 在 JFrame 窗口的南部添加一个 Label。之后,我们使用 setDefaultCloseOperation()、setSize()、setLocationRelativeTo() 和 setVisible() 方法在用户单击十字符号 (X) 时关闭窗口,设置 JFrame 窗口的大小,将 JFrame 窗口移动到计算机屏幕的中央并分别显示。

我们可以以编程方式绘制,而不是在画布上手动绘制。

示例代码(Draw.java 类具有 main 方法):

// write your package here
package com.voidtesting.canvas.draw;
// import necessary libraries
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Draw extends JPanel {
  @Override
  public void paintComponent(Graphics g) {
    // call method of the super class
    super.paintComponent(g);
    // set background color
    this.setBackground(Color.cyan);

    // set color of the shape
    g.setColor(Color.red);
    // draw line
    g.drawLine(5, 30, 380, 30);

    // set color of the shape
    g.setColor(Color.blue);
    // draw rectangular
    g.drawRect(5, 40, 90, 55);

    // set color of the shape
    g.setColor(Color.BLACK);
    // draw string
    g.drawString("Hi, how are you?", 100, 50);

    // set color of the shape
    g.setColor(Color.green);
    // draw filled rectangular
    g.fill3DRect(5, 100, 90, 55, true);
    // draw filled oval
    g.fillOval(150, 100, 90, 55);
  }

  public static void main(String[] args) {
    // create JFrame Object
    JFrame jFrame = new JFrame("Canvas");
    // add the object of Draw Class in center
    jFrame.add(new Draw(), BorderLayout.CENTER);
    // exit on close
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // set frame size
    jFrame.setSize(300, 200);
    // set jFrame location to center of the screen
    jFrame.setLocationRelativeTo(null);
    // display frame
    jFrame.setVisible(true);
  }
}

输出:

使用 java swing 制作画布 - 以编程方式在画布上绘制