创建演示应用程序(步骤 2)

接下来,我们将自定义绘图表面添加到框架。为此,我们将创建一个javax.swing.JPanel的子类(一个通用的轻量级容器),该子类将提供用于渲染自定义绘画的代码。

在 GUI 中创建新项目

javax.swing.JPanel 子类

单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行 SwingPaintDemo2.另外,要自己编译和运行示例,请查阅example index

package painting;

import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

public class SwingPaintDemo2 {
   
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI(); 
            }
        });
    }

    private static void createAndShowGUI() {
        System.out.println("Created GUI on EDT? "+
        SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Swing Paint Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new MyPanel());
        f.pack();
        f.setVisible(true);
    }
}

class MyPanel extends JPanel {

    public MyPanel() {
        setBorder(BorderFactory.createLineBorder(Color.black));
    }

    public Dimension getPreferredSize() {
        return new Dimension(250,200);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);       

        // Draw Text
        g.drawString("This is my custom Panel!",10,20);
    }  
}

您会注意到的第一个更改是,我们现在正在导入许多其他类,例如JPanelColorGraphics。由于某些较旧的 AWT 类仍在现代 Swing 应用程序中使用,因此在一些 import 语句中看到java.awt包是正常的。我们还定义了一个自定义JPanel子类,称为MyPanel,它包含大部分新代码。

MyPanel类定义具有一个构造函数,该构造函数在其边缘设置了黑色边框。这是一个细微的细节,一开始可能很难看清(如果是,只需 注解 掉setBorder的调用,然后重新编译.)MyPanel也会覆盖getPreferredSize,这将返回所需的面板宽度和高度(在这种情况下为 250)是宽度,200 是高度。)因此,SwingPaintDemo类不再需要指定帧的大小(以像素为单位)。它只是将面板添加到框架,然后调用pack

paintComponent方法是您进行所有自定义绘制的地方。该方法由javax.swing.JComponent定义,然后被您的子类覆盖以提供其自定义行为。它的唯一参数java.awt.Graphics对象公开了许多绘制 2D 形状和获取有关应用程序图形环境的信息的方法。在大多数情况下,此方法实际接收的对象将是java.awt.Graphics2D(Graphics子类)的实例,该实例为复杂的 2D 图形渲染提供支持。

大多数标准 Swing 组件的外观都由单独的“ UI Delegate”对象实现。 super.paintComponent(g)的调用将图形上下文传递给组件的 UI 委托,该委托绘制了面板的背景。有关此过程的详细信息,请参见上述 SDN 文章中标题为“绘画和 UI 委托”的部分。

Exercises:

  • 现在您已经在屏幕上绘制了一些自定义文本,请像以前一样try最小化和还原应用程序。

  • 用另一个窗口遮挡一部分文本,然后将该窗口移开以重新显示自定义文本。在这两种情况下,绘画子系统都将确定该组件已损坏,并确保调用了paintComponent方法。