Java Swing之JPanel和JComponent
如果需要创建一个能够进行绘制的组件,一般需要定义一个扩展JComponent的类,并覆盖其中的paintComponent方法。如下所示:
class MyComponent extends JComponent { public void paintComponent(Graphics g) { 自己编写的绘制代码 } }
其中paintComponent方法有一个Graphics类型的参数,该参数保存着用于绘制图像和文本的设置。在Java中,所有的绘制都必须使用Graphics对象,其中包含了绘制图案、图像和文本的方法。一定不要自己调用paintComponent方法。在应用程序需要重新绘图的时候,这个方法将被自动地调用,不要人为地干预这个自动的处理过程。以下是一个绘制组件的完整示例:
import javax.swing.*; import java.awt.*; /** * @author Iong */ public class HelloWorld { public static void main(String[] args) { EventQueue.invokeLater(() -> { JFrame frame = new HelloWorldFrame(); frame.setTitle("NotHelloWorld"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } } class HelloWorldFrame extends JFrame { public HelloWorldFrame() { add(new HelloWorldComponent()); pack(); } } class HelloWorldComponent extends JComponent { public static final int MESSAGE_X = 50; public static final int MESSAGE_Y = 80; private static final int DEFAULT_WIDTH = 250; private static final int DEFAULT_HEIGHT = 200; public void paintComponent(Graphics g) { g.drawString("Hello World!", MESSAGE_X, MESSAGE_Y); } public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } }
上面讲到了绘制组件时一般需要定义一个扩展JComponent的类,但是,有时我们也会通过扩展JPanel绘制组件,而不是JComponent。JPanel是一个可以包含其他组件的容器,两者的不同之处在于JPanel默认的Opaque(中文意思:不透明的)属性为true,而JComponent默认的Opaque属性为false。当Opaque属性为true时,就意味着该面板不是透明的,需要在面板的边界内绘制所有的像素,即不能包含有透明的内容视图。因此在扩展JPanel类绘制组件时,可以在每个面板子类的paintComponent方法中调用super.paintComponent来用背景色绘制面板,即:
class MyPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); 自己编写的绘制代码 } }