本教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
请参阅Java语言变化以了解Java SE 9及后续版本中更新的语言功能的摘要。
请参阅JDK发行说明以获取有关所有JDK版本的新功能、增强功能和已删除或弃用选项的信息。
接下来,我们将在框架中添加一个自定义绘图表面。为此,我们将创建一个javax.swing.JPanel的子类(一个通用的轻量级容器),该子类将提供绘制自定义绘画的代码。
javax.swing.JPanel子类
点击“启动”按钮使用Java™ Web Start(下载JDK 7或更高版本)运行SwingPaintDemo2。或者,要自己编译和运行示例,请参考示例索引。
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("在EDT上创建GUI? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing绘图演示");
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);
// 绘制文本
g.drawString("这是我的自定义面板!",10,20);
}
}
你会注意到的第一个变化是我们现在导入了许多额外的类,比如JPanel、Color和Graphics。由于一些旧的AWT类仍然在现代的Swing应用程序中使用,所以在一些导入语句中看到java.awt包是正常的。我们还定义了一个名为MyPanel的自定义JPanel子类,它包含了大部分新代码。
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 Delegate"部分。
练习:
paintComponent方法。