Swingに関する世界観です。Javaの世界観(A.GUI)も参照のこと。
Swingは、Pure Javaで書かれたJavaのGUIツールキット。
Javaは"Write once, run anywhere"というスローガンを売りにしている。これは、Javaで書かれたコードはどのOS・どのプラットフォームにおいても、一度書けばどこでも動く、というJavaの理念。
Swingは、そのようなJava仮想マシンで同じように動く「Pure Java」なGUIツールキットとして知られる。
OS依存のコードを使っていないため、OSのルック・フィールとは異なる見た目になる。これは、.NET FrameworkのWindows.Formsとは異なる特徴で、たとえWindowsでもLinuxでも、Windows/Linuxネイティブなアプリケーションとは異なる見た目を持つ。
また、OS依存のコードを使っていないため、コードの見た目や開発の手法も異なる。リスナーと呼ばれる「メッセージループライクな継承システム」によって、イベントにメソッドを登録する形で開発する。GTK+やVBよりも、Windows APIやXlibに近い開発方法である。
マルチテキストなどのコンポーネントも、一切OSの仕組みを使わず、Pure Javaで独自に実装されている。
こうした点は、デスクトップアプリケーションをどのOSでも動かせる、という点で優れている。たとえば、Swingで書かれたアプリケーションは、Windowsで動けばLinuxでも同じように動く。
また、もっと小型のモバイルなシステムでJava MEを使う場合でも、Swingが動くような環境がもしあるのであれば、WindowsでSwingで開発したアプリケーションをモバイル機器でも動かせる。
JavaのGUIであるSwingは、クロスプラットフォームであらゆるOSで同じように動くことで有名です。同様の技術に、EclipseによるOSネイティブなウィジェットを使用するSWTがあります。
Swingでは、ActionListenerというインターフェースを実装することで、イベント処理を行う。
addActionListener()でボタンなどのオブジェクトとアクションリスナーを関連づけし、ボタンに対してクリックなどのアクションを行った際に生み出されるActionEventのインスタンスに対して、アプリケーションがどのように振る舞うかをactionPerformed()というメソッドで設定する。
後日注記:Swingのリスナは、Windows APIやX11でいうイベントループに相当し、実際よく似ている。
Swingの主なコンポーネントに、
コンポーネント | 説明 |
---|---|
JFrame | ウィンドウフレーム |
JDialog | ダイアログ |
JButton | ボタン |
JLabel | ラベル文字 |
JTextField | テキスト入力フィールド(一行) |
JTextArea | テキスト入力エリア(複数行) |
JPanel | パネル |
JMenuBar | メニューバー |
JToolBar | ツールバー |
JPopupMenu | ポップアップメニュー |
などがある。詳しくはSwing - とほほのJava入門などを参照のこと。
Swingでは、ルック・フィールをそれぞれのプラットフォームと調和するように切り替えることができる。
たとえば、
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
とすればMetal(Swingの独自ルック・フィール)となる。
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
とすればMotif風の見た目になる。
システムのルック・フィール名はUIManager.getSystemLookAndFeelClassName()で取得できる。よって、
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
とすれば、MacならMac風、WindowsならWindows風のルック・フィールになる。
Javaの継承は、GUIツールキットと相性がいいことで知られています。
たとえば、Swingを使う際に、テキストボックス(JTextArea)とテキストフィールド(JTextField)には、同じ「テキストを編集する」という機能が必要です。
そのため、これらの親クラスであるJTextComponentで、文字列の入力と編集に関する設定であるsetEditable()メソッドが定義されています。
ほかにも、ボタン(JButton)やメニュー項目(JMenuItem)に必要なクリックを実行するdoClick()メソッドは、親クラスのAbstractButtonクラスで定義されています。
このように、オブジェクト指向の継承は、GUIツールキットと相性がよく、コントロールに対して必要なメソッドを適切な親クラスで定義するようになっています。
(放送大学「コンピュータとソフトウェア ('18)」を参考に執筆しました。)
はっきり言って、Swingの開発は非常に簡単です。
たとえば、以下のページにサンプルとなるコードがあります。
このページのように、
public class HogeApp implements ActionListener { // 使うコンポーネントを定義する private JFrame hogeFrame; private Container hogeContentPane; private JButton hogeButton; // コンストラクタでコンポーネントを作成する public HogeApp() { hogeFrame = new JFrame("Hoge"); hogeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); hogeFrame.setSize(150, 100); hogeContentPane = hogeFrame.getContentPane(); hogeButton = new JButton("Hoge"); hogeButton.addActionListener(this); hogeContentPane.add(hogeButton, BorderLayout.CENTER); hogeFrame.setVisible(true); } // アクションイベントごとに処理を行う public void actionPerformed(ActionEvent event) { if (event.getSource() == hogeButton) { // ここにボタンクリック時の処理を記述する hogeButton.setText("Fuga"); } } // プログラムを起動する public static void main(String[] args) { new HogeApp(); } }
のように記述します。
まず、ActionListenerを実装したHogeAppなどのアプリケーションのメンバ関数として、使うコンポーネントを定義します(extends JFrameでフレームを継承することもできる)。
そして、コンストラクタでそれらのコンポーネントを作成します。フレームからgetContentPane()で取得したContentPaneに対してボタンを追加します。自分自身がActionListenerを実装しているため、ボタンのaddActionListener()にはthisを指定します。
そして、actionPerformed()メソッドでアクションイベントごとの処理を記述します。
最後に、main関数でHogeApp()を起動するのです。
2023.05.15-16
移植性に関連する内容があります。
GUIの開発全般についてはGUI開発を参照のこと。
イベント駆動を参照のこと。
SwingはPure Javaで書かれたJavaのツールキットであり、Javaの理想通り、どんな環境でも同じ見た目になる。
その代わり、独自のフラットな魔術的な雰囲気のする見た目(ルック・フィール)になる。
Windowsネイティブのルック・フィールがいいなら、IBMがEclipse向けに開発したSWT(JavaでネイティブGUIが開発できる)を使うか、VB.NETかC#(Microsoft版Javaという位置づけの.NET Framework向け言語)でWindows.Formsを使った方が良い。