3. デスクトップ関係
2006.12.22 株式会社四次元データ 鈴木 圭
- 3.1. システム・トレイ機能
- 3.2. スプラッシュ・スクリーンの表示
- 3.3. 関連付けられたアプリケーションによる起動
- 3.4. JTabbedPane の改良 - タブに任意のコンポーネント
- 3.5. JTable のソーティング/フィルタリング
- 3.6. テキスト・コンポーネントの印刷機能
- 3.7. デプロイメント
- 3.8. その他の変更
Mustang ではデスクトップ関係の機能が大幅に改善されました。中でもシステム・トレイやスプラッシュ・スクリーンの表示、ネイティブで関連付けられたアプリケーションの起動など、デスクトップ環境との統合に力が入れられています。Swing 関係では JTable のソーティング/フィルタリング機能や SwingWorker の標準搭載などが行われました。他にも既知のバグ修正や動作速度の向上、描画品質の改善など、安定性や品質を向上させる改善が行われました。
3.1. システム・トレイ機能
Mustang ではデスクトップ・アプリケーションを作成する場合に有用な機能がいくつか追加されました。その一つとして、システム・トレイ機能があります。これは Windows や XWindow などを利用している方にとってはおなじみの、システム・トレイ(プラットフォームによって「タスクトレイ」「通知領域」などと呼ばれます)に小さなアイコンを表示するという機能です。システム・トレイ機能のために新しく追加されたクラスは以下の二つです:
- java.awt.SystemTray
- トレイ・アイコンを格納するシステム・トレイを表すクラス。 - java.awt.TrayIcon
- システム・トレイに格納するトレイ・アイコンを表すクラス。
基本的な使用方法
使い方は TrayIcon インスタンスを作成し、SystemTray#add(TrayIcon) でシステム・トレイに追加します。以下にサンプル・コードを示します:
import java.awt.AWTException; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.TrayIcon; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; public class TrayIconMain { public static void main(String[] arguments) throws AWTException { // システム・トレイがサポートされていなければ終了. if(!SystemTray.isSupported()) { System.out.println("SystemTray is not supported."); return; } // SystemTray インスタンスは static メソッドで取得する. SystemTray systemTray = SystemTray.getSystemTray(); // トレイ・アイコンのイメージ. 白枠に黒く塗りつぶす. Dimension trayIconSize = systemTray.getTrayIconSize(); BufferedImage trayIconImage = new BufferedImage(trayIconSize.width, trayIconSize.height, BufferedImage.TYPE_3BYTE_BGR); Graphics graphics = trayIconImage.getGraphics(); graphics.setColor(Color.BLACK); graphics.fillRect(0, 0, trayIconSize.width-1, trayIconSize.height-1); graphics.setColor(Color.WHITE); graphics.drawRect(0, 0, trayIconSize.width-1, trayIconSize.height-1); graphics.dispose(); // トレイ・アイコンに持たせるポップアップメニューの作成. MenuItem menuItem = new MenuItem("Exit"); menuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); PopupMenu trayIconMenu = new PopupMenu(); trayIconMenu.add(menuItem); // トレイ・アイコンを作成し, システム・トレイに追加する. TrayIcon trayIcon = new TrayIcon(trayIconImage); trayIcon.setToolTip("Hello, TrayIcon."); trayIcon.setPopupMenu(trayIconMenu); systemTray.add(trayIcon); // 失敗した場合は AWTException } }
実行例:
サンプル・コードでは最初に SystemTray#isSupported メソッドで実行環境がシステム・トレイをサポートしていることを確認し、それから SystemTray#getSystemTray メソッドで SystemTray クラスのインスタンスを取得しています。もしシステム・トレイがサポートされない環境で SystemTray#getSystemTray メソッドを使用すると UnsupportedOperationException が発生します。次にトレイ・アイコンに持たせるイメージとポップアップ・メニューを作成しています。そして最後にイメージ、ツールチップ、ポップアップ・メニューを持つ TrayIcon インスタンスを作成し、システム・トレイに追加しています。システム・トレイへの追加(SystemTray#add(TrayIcon))に失敗すると java.awt.AWTException が投げられます。
サンプル・コードの TrayIcon クラスをインスタンス化する部分では、java.awt.Image を引数に取るコンストラクタを使用し、後からツールチップとポップアップ・メニューの設定をしていますが、ツールチップやポップアップ・メニューはコンストラクタで指定することもできます。TrayIcon クラスのコンストラクタは以下の形式があります:
- TrayIcon(Image image)
- TrayIcon(Image image, String tooltip)
- TrayIcon(Image image, String tooltip, PopupMenu popup)
ポップアップ・メッセージ
TrayIcon#displayMessage メソッドを使用するとシステム・トレイに格納したトレイ・アイコンの近くにポップアップ・メッセージを表示することができます。以下に使用例を示します:
TrayIcon trayIcon; ... trayIcon.displayMessage("caption", "message", TrayIcon.MessageType.INFO);
実行例:
TrayIcon#displayMessage メソッドの引数の最初の二つはキャプションとメッセージです。三番目の引数はメッセージの種類を表す列挙型 TrayIcon.MessageType を指定します。TrayIcon.MessageType の値は以下の通りです:
TrayIcon.MessageType.ERROR | エラー・メッセージ |
---|---|
TrayIcon.MessageType.INFO | 情報メッセージ |
TrayIcon.MessageType.NONE | 単純なメッセージ |
TrayIcon.MessageType.WARNING | 警告メッセージ |
マウス・イベント
トレイ・アイコン上で発生したイベントに対するリスナを設定することができます。設定できるリスナは java.awt.event パッケージの ActionListener、MouseListener、MouseMotionListener です。マウス・イベントに関しては MouseEvent#getComponent メソッドの戻り値は null、MouseEvent#getSource メソッドの戻り値は TrayIcon となります。
ActionListener を追加した場合、ActionListener#actionPerformed メソッドが呼び出されるタイミングは、マウスやキーボードでトレイ・アイコンが選択された場合など、プラットフォームに依存します。
トレイ・アイコンのイメージ・サイズ
トレイ・アイコンのサイズは SystemTray#getTrayIconSize メソッドで取得することができます。また、TrayIcon#getImageAutoSize メソッドでイメージ・サイズの自動調整を行うかどうかを指定することが出来ます。
3.2. スプラッシュ・スクリーンの表示
Mustang ではアプリケーション起動時にスプラッシュ・スクリーンを表示することができるようになりました。スプラッシュ・スクリーンとはアプリケーションの起動時に表示される、起動中であることを示すためのウィンドウのことです。一般にはアプリケーションのロゴなどの画像とともに、起動中であることを認識してもらうためのプログレス・バーなどが表示されることが多いです。
スプラッシュ・スクリーンの例:
基本的な使い方
スプラッシュ・スクリーンに画像を表示するには、java コマンドの -splash オプション、または JAR ファイルに含める MANIFEST.MF の SplashScreen-Image オプションで表示したい画像のパスを指定します。使用できる画像の形式は GIF、PNG、JPEG の三種類です。透過 GIF/PNG にも対応しているようです。
java コマンドの -splash オプションで指定する場合の例:
java -splash:image.png com.example.Main
MANIFEST.MF ファイルの SplashScreen-Image オプションで指定する場合の例:
Manifest-Version: 1.0 Main-Class: com.example.Main SplashScreen-Image: image.png ...
スプラッシュ・スクリーンでアニメーション
スプラッシュ・スクリーン機能で画像を表示するだけならば上述のとおり簡単に行うことができますが、プログレス・バーを表示するなどアニメーションを行う場合は、それを行うコードを記述しなければなりません。
スプラッシュ・スクリーンを操作するには java.awt.SplashScreen クラスを使用します。SplashScreen クラスには表示する画像を設定する setImageURL メソッドや描画のための Graphics2D を作成する createGraphics メソッドが含まれています。SplashScreen のインスタンスを取得するには static メソッドである SplashScreen#getSplashScreen を使用します。このメソッドはスプラッシュ・スクリーンが存在しないか、既に SplashScreen#close メソッドで閉じられている場合には null を返します。
以下にスプラッシュ・スクリーンにプログレス・バーを描画するサンプル・コードを示します:
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.SplashScreen; public class SplashScreenMain { public static void main(String[] arguments) { animateProgress(); } private static void animateProgress() { SplashScreen splashScreen = SplashScreen.getSplashScreen(); if(splashScreen == null) { return; } Dimension size = splashScreen.getSize(); Graphics2D graphics = splashScreen.createGraphics(); graphics.setColor(Color.RED); int width = 8; int interval = 4; int height = 16; for(int x = 0; x < size.width; x += width+interval) { graphics.fillRect(x, size.height-height*2, width, height); splashScreen.update(); try { Thread.sleep(100); } catch(InterruptedException e) { } } graphics.dispose(); } }
実行例:
3.3. 関連付けられたアプリケーションによる起動
Mustang ではネイティブ・デスクトップで登録されているアプリケーションの関連付けによるファイルの起動などを行うことができます。例えば、Windows において .txt という拡張子のファイルを「開く」と、メモ帳などの関連付けられたアプリケーションによって開かれます。Mustang ではこのような機能を扱うためのクラス java.awt.Desktop が追加されました。Desktop クラスでは以下の機能がサポートされます:
- 指定された URI をデフォルトのブラウザで表示する。
- 指定されたメール・アドレスをデフォルトのメール・クライアントで起動する。
- 指定されたファイルのオープン、編集、印刷を登録されたアプリケーションで起動する。
以下に sample.txt というファイルを関連付けられたアプリケーションで開くサンプル・コードを示します:
import java.awt.Desktop; import java.io.File; import java.io.IOException; public class DesktopMain { public static void main(String[] arguments) { // デスクトップがサポートされているか. if(!Desktop.isDesktopSupported()) { System.out.println("Desktop is not supported."); return; } Desktop desktop = Desktop.getDesktop(); // 「開く」操作がサポートされているか. if(!desktop.isSupported(Desktop.Action.OPEN)) { System.out.println("Desktop.Action.OPEN is not supported."); return; } // 関連付けられたアプリケーションでファイルを開く. try { desktop.open(new File("sample.txt")); } catch(IOException exception) { exception.printStackTrace(); } } }
このサンプル・コードでは、最初に Desktop#isDesktopSupported メソッドによって実行環境がデスクトップ機能をサポートしていること、次に Desktop#isSupported(Desktop.Action) メソッドで「開く」操作がサポートされていることを確認しています。その後、Desktop#open(File) メソッドで sample.txt ファイルを関連付けられたアプリケーションで開きます。このとき、関連付けられたアプリケーションが存在しないなどの理由でファイルを開くことができなかった場合は java.io.IOException が投げられます。
サンプル・コードでは関連付けられたアプリケーションでファイルを開くメソッド Desktop#open(File) を使用しましたが、Desktop クラスには他にもブラウザで表示するメソッドや印刷するメソッドなど、以下に挙げるものがあります:
- void browse(URI uri)
- 指定された URI をデフォルトのブラウザで表示する。 - void edit(File file)
- 指定されたファイルを関連付けられたアプリケーションで編集する。 - void mail()
- デフォルトのメール・クライアントを起動する。 - void mail(URI mailtoURI)
- 指定された mailto URL をデフォルトのメール・クライアントで開く。 - void open(File file)
- 指定されたファイルを関連付けられたアプリケーションでファイルを開く。 - void print(File file)
- 指定されたファイルをネイティブ・デスクトップの機能を利用して印刷する。
また、これらの各操作は列挙型 Desktop.Action によって表されます:
Desktop.Action.BROWSE | ブラウズ |
---|---|
Desktop.Action.EDIT | 編集 |
Desktop.Action.MAIL | メール |
Desktop.Action.OPEN | 開く |
Desktop.Action.PRINT | 印刷 |
Desktop.Action の値を Desktop#isSupported(Desktop.Action) メソッドの引数に与えることで、対応する操作がサポートされていることを確認することができます。
3.4. JTabbedPane の改良 - タブに任意のコンポーネント
javax.swing.JTabbedPane のタブ部分に任意のコンポーネントを設定する事ができるようになりました。この機能のために JTabbedPane には以下のメソッドが追加されました:
- void setTabComponentAt(int index, Component component)
- 指定インデックスのタブにコンポーネントを設定する。 - Component getTabComponentAt(int index)
- 指定インデックスのタブに設定されているコンポーネントを返す。 - int indexOfTabComponent(Component tabComponent)
- 指定コンポーネントが設定されているタブのインデックスを返す。どのタブにも指定コンポーネントが設定されていない場合は -1 を返す。
これによって、例えば以下のような閉じるボタンを持ったタブを作成することができます(タブの部分に JLabel と JButton を含む JPanel を設定しています):
ソース・コード:
import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.border.EmptyBorder; public class JTabbedPaneMain { public static void main(String[] arguments) { JTabbedPane tabbedPane = new JTabbedPane(); addTab(tabbedPane, "砂糖"); addTab(tabbedPane, "塩"); addTab(tabbedPane, "酢"); addTab(tabbedPane, "醤油"); addTab(tabbedPane, "味噌"); JFrame frame = new JFrame("JTabbedPane Sample"); frame.pack(); frame.add(tabbedPane); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 300); frame.setLocationRelativeTo(null); frame.setVisible(true); } private static void addTab(JTabbedPane tabbedPane, String name) { JLabel label = new JLabel(name); label.setBorder(new EmptyBorder(0, 0, 0, 0)); JButton button = new JButton("×"); button.setFocusable(false); button.setContentAreaFilled(false); button.setBorder(new EmptyBorder(0, 0, 0, 0)); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { Container container = (Container)event.getSource(); while(!(container instanceof JTabbedPane)) { container = container.getParent(); } JTabbedPane tabbedPane = (JTabbedPane)container; int index = tabbedPane.getSelectedIndex(); if(index != -1) { tabbedPane.remove(index); } } }); JPanel panel = new JPanel(); panel.setOpaque(false); panel.add(label); panel.add(button); tabbedPane.addTab(null, new JScrollPane(new JTextArea())); tabbedPane.setTabComponentAt(tabbedPane.getTabCount()-1, panel); } }
3.5. JTable のソーティング/フィルタリング
javax.swing.JTable の行のソーティングやフィルタリングを手軽に行うことができるようになりました。そのためのクラスとして javax.swing.table.TableRowSorter 及び javax.swing.RowFilter が追加されました。TableRowSorter クラスは JTable の行のソーティングを行うことに特化したクラスであり、より汎用的な「行のソーティング」を行うクラス javax.swing.RowSorter を間接的に継承しています。
行のソーティング
TableRowSorter クラスを使用すると、以下のような行のソーティング機能を持つ JTable を手軽に作成することが出来ます:
ソース・コードは以下の通りです:
import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.RowSorter; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; public class JTableMain { public static void main(String[] arguments) { String[] columns = { "人名", "金額", }; Object[][] rows = { { "夏目漱石", 1000 }, { "野口英世", 1000 }, { "守礼門", 2000 }, { "新渡戸稲造", 5000 }, { "樋口一葉", 5000 }, { "福沢諭吉", 10000 }, }; // ソーティング時に文字列以外の比較を行いたい列がある場合は // getColumnClass メソッドをオーバーライドして適切な Class オブジェクトを返す. TableModel tableModel = new DefaultTableModel(rows, columns) { @Override public Class getColumnClass(int column) { switch(column) { case 0 : return String.class; case 1 : return Integer.class; default : throw new RuntimeException(); } } }; // TableRowSorter クラスによって行のソーティング機能を付加する. JTable table = new JTable(tableModel); RowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(tableModel); table.setRowSorter(rowSorter); JFrame frame = new JFrame("JTable Sorting Sample"); frame.pack(); frame.add(new JScrollPane(table)); frame.setSize(400, 300); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
上記コードでは、テーブルの第一カラムに文字列、第二カラムに数値データを使用しています。そのため、JTable#setRowSorter(RowSorter) メソッドで単純にソーティング機能を付加しただけでは、ソーティングが行われるときに文字列として比較が行われてしまうため、数値データが意図したとおりにソーティングされません。そこで、JTable のモデルに使用する javax.swing.table.DefaultTableModel の getColumnClass メソッドをオーバーライドし、適切な Class オブジェクトを返すようにしています。
行のフィルタリング
TableRowSorter#setRowFilter(RowFilter) メソッド(正確には DefaultRowSorter のメソッド)を使用すると、行のフィルタリング(表示/非表示の選別)を行うことができます。setRowFilter メソッドの引数の RowFilter は、フィルタリング条件を表す抽象クラスで、RowFilter#include メソッドが true を返す行が JTable に表示されます。
RowFilter には一般的なフィルタリング条件を表す RowFilter を作成するための static メソッドが含まれています:
- RowFilter<M,I> dateFilter(RowFilter.ComparisonType type, Date date, int... indices)
- 指定した日付と比較する RowFilter を作成します。 - RowFilter<M,I> numberFilter(RowFilter.ComparisonType type, Number number, int... indices)
- 指定した数値と比較する RowFilter を作成します。 - RowFilter<M,I> regexFilter(String regex, int... indices)
- 指定した正規表現にマッチする値を表示する RowFilter を作成します。 - RowFilter<M,I> andFilter(Iterable<? extends RowFilter<? super M,? super I>> filters)
- 複数の RowFilter の AND 条件を表す RowFilter を作成します。 - RowFilter<M,I> orFilter(Iterable<? extends RowFilter<? super M,? super I>> filters)
- 指定した RowFilter の OR 条件を表す RowFilter を作成します。 - RowFilter<M,I> notFilter(RowFilter<M,I> filter)
- 指定した RowFilter の NOT 条件を表す RowFilter を作成します。
dateFilter、numberFilter の引数にある RowFilter.ComparisonType は比較の種類を表す列挙型で、以下に示す値が定義されています:
RowFilter.ComparisonType.AFTER | 指定した値よりも後であること判定する。 |
---|---|
RowFilter.ComparisonType.BEFORE | 指定した値よりも前であることを判定する。 |
RowFilter.ComparisonType.EQUAL | 指定した値と一致することを判定する。 |
RowFilter.ComparisonType.NOT_EQUAL | 指定した値と一致しないことを判定する。 |
また、dateFilter、numberFilter、regexFilter に共通する引数 indices は比較対象とするカラムのインデックス(0 〜)を指定します。indices に複数の値が指定された場合は OR 条件となります。例えば
RowFilter.numberFilter(RowFilter.ComparisonType.EQUAL, 10, 0, 1, 2);
というステートメントは、第 0 カラム、第 1 カラム、第 2 カラムの値の一つ以上が 10 の場合に true となる RowFilter を作成します。indices を指定しなかった場合は全てのカラムが比較対象となります。
また、andFilter、orFilter、notFilter を使用することで、指定した RowFilter の AND/OR/NOT 条件を表す RowFilter を作成することができます。
以下に、regexFilter、numberFilter、orFilter メソッドを組み合わせて使用する例を示します:
JTable table = new JTable(tableModel); TableRowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(tableModel); table.setRowSorter(rowSorter); // 人名が野口英世または金額が 5000 円フィルタを作成し, rowSorter に設定する. List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(); filters.add(RowFilter.regexFilter("野口英世", 0)); filters.add(RowFilter.numberFilter(RowFilter.ComparisonType.EQUAL, 5000, 1)); rowSorter.setRowFilter(RowFilter.orFilter(filters));
実行例:
3.6. テキスト・コンポーネントの印刷機能
javax.swing.text.JTextComponent クラスに、内容を印刷するための print メソッドが追加されました。print メソッドにはいくつかのオーバーロードがあり、単純な印刷だけではなく、ヘッダ/フッタのフォーマットの指定など詳細な指定を行うこともできます。print メソッドは印刷に失敗した場合に java.awt.print.PrinterException を投げます。
以下に引数を持たない print メソッドを使用した例を示します:
JTextComponent textComponent; ... try { textComponent.print(); } catch(PrinterException exception) { exception.printStackTrace(); }
3.7. デプロイメント
Java Plug-in や Java Web Start の機能改善が行われました。Java Plug-in と Java Web Start のダウンロード・エンジンが統合されるとともに、ダウンロードやキャッシングの機能強化、GUI などのユーザ体感の改善などが行われています。
また、各プラットフォームにおける改善も行われました。Windows 環境では、インストールされている JRE や Java Plug-in、Java Web Start のバージョンの識別機能のサポートや "プログラムの追加と削除" 機能との統合に関する改善、GNOME ではショートカットやサブメニュー項目の作成に関する改善が行われました。
その他の変更点としては
- デスクトップ・ショートカットに .ico ファイルや .png ファイルが使用可能
- Mozilla Firefox ブラウザのサポート
- HTTP 圧縮や HTTP キャッシュ・コントロール
- 複数ファイル・タイプのキャッシング
- オフライン・モードでの使用のサポート
- JNPL バージョニング・プロトコル及び JARDiff のサポート(Java Plug-in)
- JAR のインデクシング(Java Web Start)
- キャッシュ・サイズのコントロールやキャッシュのクリーンアップ・ポリシーの導入(Java Web Start)
- 柔軟なアップデート・ポリシーの導入(Java Web Start)
などが行われました。
3.8. その他の変更
- SwingWorker の標準搭載
- シングルスレッドとして設計されている Swing でマルチスレッド処理をサポートする SwingWorker が標準搭載されるようになりました。 - ダイアログ・ボックスの Modality
- 以前のダイアログ・ボックスにはモーダル/モードレスの分類しかありませんでしたが、Mustang ではアプリケーション・モーダル、ツールキット・モーダル、ドキュメント・モーダルという分類が行われ、モーダル・ダイアログ・ボックスの状態を細かく指定することができるようになりました。 - 真のダブル・バッファリング
ダブル・バッファリングの改善により、他のウィンドウに隠されているウィンドウが前面に表示されるときの速度が改善されました。 - ドラッグ&ドロップ機能の強化/改善
- バグ・フィックスやドラッグ&ドロップのユーザ体感の改善に加え、カスタマイズ性も向上しました。ドロップ・モードを表す列挙型 javax.swing.DropMode や、ドロップ先を表す javax.swing.TransferHandler.DropLocation クラス、ドラッグ&ドロップの情報を表す javax.swing.TransferHandler.TransferInfo クラスなどが追加されました。また、これらのクラスの Getter/Setter が javax.swing.JList や javax.swing.JTable などいくつかのコンポーネントに追加されました。 - JFileChooser で現在表示されているカーソルを知る
- javax.swing.JFileChooser に現在表示されているカーソルを知ることができるようになりました。このために javax.swing.plaf.basic.BasicDirectoryModel に java.beans.PropertyChangeListener を設定するための addPropertyChangeListener メソッドなどが追加されました。 - ウィンドウの最小サイズの設定
- java.awt.Window クラスにウィンドウの最小サイズを設定するためのメソッド setMinimumSize が追加されました。 - スクリーン座標でのマウス・イベントの発生位置
- 発生したマウス・イベントの座標をスクリーン座標で簡単に取得することが可能となりました。MouseEvent、MouseWheelEvent、MenuDragMouseEvent クラス(全て java.awt.event パッケージ)それぞれに getLocationOnScreen、getXOnScreen、getYOnScreen メソッドが追加されました。 - 描画関係の品質や速度の改善
- ネイティブ OS の API の使用やハードウェア・アクセラレーションによる描画速度の向上が行われました。また、アンチエイリアシングの強化などテキスト描画の品質が改善されました。 - シングルスレッド・レンダリング
- OpenGL での描画においてシングルスレッド・レンダリング(Single-Threaded Rendering:STR)が用いられるようになり、描画速度が向上しました。 - レイアウトの強化
- コンポーネントのベースラインの取得(java.awt.Component#getBaseline など)や、コンポーネント間のスペースの設定(javax.swing.LayoutStyle)が行えるようになりました。 - 非英語ロケールでの入力の改善
- 非英語ロケールでの入力に関する多くのバグが解消されました。 - GIF Writer の追加
- ImageIO での GIF のサポートは、今までは読み込みしかサポートされていませんでしたが、新しく書き込みも行うことができるようになりました。 - etc...
まとめ
今回はデスクトップ関係の機能強化について解説を行ってきました。Java といえばサーバー・サイド開発というイメージが強いかもしれませんが、今回の機能強化でネイティブ・デスクトップとの統合が図られ、通常のデスクトップ・アプリケーションの開発に必要だった色々な機能がサポートされるようになりました。
次回は Mustang の XML サポートについて解説します。