6-4-1: コンポーネントのクラスの継承関係

コンポーネントを目的別に分類して調べるために、 それらの継承関係と 共通のスーパークラスとなる抽象クラスの存在について調べてみましょう。


・ JDKのコンポーネントの継承関係は、 歴史的な理由から多少込み入って見える部分が存在します。 いきなり Swingコンポーネントについて調べる前に、 まず JDK1.1以前に用いられていた java.awtパッケージのコンポーネントについて 見てみましょう。
旧来のコンポーネントの継承関係は、下記のように比較的単純な構造になっています。 クラスの数も多くないので、そのすべてを示しておきましょう。


Component -+- Container -+- Panel --+- Applet
           |             |
           |             +- Window -+- Frame
           |             |          +- Dialog -+- FileDialog
           |             +- ScrollPane
           |
           +- Label
           +- Button
           +- Checkbox
           +- Choice
           +- List
           +- Scrollbar
           +- Canvas
           +- TextComponent -+- TextField
                             +- TextArea

MenuComponent -+- MenuItem -+- Menu -+- PopupMenu
               |            +- CheckboxMenuItem
               | 
               +- MenuBar
 

すべてのコンポーネントは Component もしくは MenuComponentを 共通のスーパークラスとします。 これらは抽象クラスでそれ自身はオブジェクトを生成できません。 Componentのサブクラスはさらに2つのグループに分かれます。 1つ目は Container のサブクラスです。 Containerはレイアウトの機能を提供するクラスで、やはり抽象クラスです。 Containerのサブクラスは内部に他の Component を配置することができます。 2つ目のグループは直接ユーザーインターフェイスを担当するクラス群で、 これらの大半は Componentの直接のサブクラスです。 ただし、文字入力を担当する TextField と TextArea は共通のスーパークラス TextComponentを持ちます。 TextComponent はこれら2つのクラスに共通する性質を定義し、やはり抽象クラスです。
(参照:これらのコンポーネントを 確認できるアプレットそのソース。)

・ さて、今度はSwingコンポーネントの継承関係を見てみましょう。 かなり複雑にものになっていますが、基本的な考え方は JDK1.1までと同じです。 クラスの数や種類が増えているだけのことです。 (この他にも javax.swing パッケージに含まれるクラスが多数存在します。 そのいくつかは下記のコンポーネントを実現するための部品となり、 それ自身コンポーネントであるものも存在します。 それらは下記の図では省略しました。)


Container -+- Panel -+- Applet -+- JApplet
           |
           +- Window -+- JWindow
           |          +- Frame -+- JFrame
           |          +- Dialog -+- JDialog
           |
           +- JComponent -+- AbstractButton -+- JButton
                          |                  +- JToggleButton -+- JCheckbox
                          |                  |                 +- JRadioButton
                          |                  |   
                          |                  +- JMenuItem -+- JMenu
                          |                                +- JCheckboxMenuItem
                          |                                +- JRadioButtonMenuItem
                          |
                          +- JComboBox
                          +- JColorChooser
                          +- JDesktopIcon
                          +- JFileChooser
                          +- JLayeredPane ---+- JDesktopPane
                          +- JTextComponent -+- JEditorPane
                          |                  +- JTextField -+- JPasswdField
                          |                  +- JTextArea
                          |                  +- JTextPane
                          |
                          +- JInternalFrame
                          +- JLabel
                          +- JList
                          +- JMenuBar
                          +- JOptionPane
                          +- JPanel
                          +- JPopupMenu
                          +- JProgressBar
                          +- JRootPane
                          +- JScrollBar
                          +- JScrollPane
                          +- JSeparator
                          +- JSlider
                          +- JSplitPane
                          +- JTabbedPane
                          +- JTable
                          +- JToolBar
                          +- JToolTip
                          +- JTree
                          +- JViewport
 

・ 注意すべき点をいくつか指摘しておきましょう。
まず、上の図では省略しましたが、すべての Swingコンポーネントは Component のサブクラスです。 コンポーネントのサイズ、色など基本的な形状と それらをコントロールするメソッドは Componentのレベルで定義されます。 この点は従来通りです。
また、すべての Swingコンポーネントは Container のサブクラスになっています。 つまりレイアウトの機能をあらかじめ含んでいるわけです。 このため継承関係を見ただけでは、 コンポーネントがコンテナなのか GUIを直接取り扱うものなのか区別がわかりにくく なっています。 JFrame や JPanel の他、 クラス名の最後に "Pane" が付くものはコンテナのクラスと考えてください。
ほとんどの Swingコンポーネントは JComponent という抽象クラスを 共通のスーパークラスとしています。 メニューを構成するコンポーネントも JComponentのサブクラスです。 例外はアプレットの JApplet と 独立したウィンドウを生成する JFrameなど のクラスです。 これらが JComponentのサブクラスでないのは、 いわゆる Light Weightのオブジェクトとして取り扱えないという実装上の 問題からのようです。(将来的には継承関係が変更される可能性があります。)
JComponentのレベルで追加される機能は、 JDK1.1以降に拡張されてきた新しいものです。 JDK1.2からは、 ToolTip によるインターフェイスの提供、Accessibilityへの対応、 Look & Feel の選択機能などが導入されています。