連載
Swingのスレッド処理を理解する:SwingでJavaに強くなる(6)(1/2 ページ)
第5回では、ToDoリストの表示とToDoの追加を実装しました。第6回ではさらなる機能の実装と前回触れていない点について解説を行います。
今回作成するGUIアプリケーションの仕様
今回は第5回で作成したアプリケーションに対して以下の機能を実装します。
- 一覧のToDoを編集する
- 一覧のToDoを削除する
ToDoリストの実装
プロジェクトの作成
今回は「ToDoList2」という名前のプロジェクトを作成します(第1回の“プロジェクトの作成”を参考にしてください)。
SwingAppMainクラスの作成
アプリケーションの起動および土台となるフレームの生成を担当するクラス「SwingAppMain」を作成します。
package swing.sample; import java.awt.BorderLayout; import java.awt.Container; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class SwingAppMain { /** * アプリケーションの起動 */ public static void main(String[] args) { System.out.println("main : " + SwingUtilities.isEventDispatchThread()); SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowTodoList(); } }); } /** * ToDoリストの生成と表示を行います。 */ private static void createAndShowTodoList() { System.out.println("createAndShowTodoList :" + SwingUtilities. isEventDispatchThread()); JFrame mainFrame = new JFrame("ToDoリスト"); mainFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); Container contentPane = mainFrame.getContentPane(); // ToDoリストを生成 JComponent newContentPane = new ToDoListPane(); contentPane.add(newContentPane, BorderLayout.CENTER); // Windowサイズを調整 mainFrame.pack(); // 表示 mainFrame.setVisible(true); } }
TodoListPaneクラスの生成
次にToDoListPaneクラスを作成します。このクラスは、ToDoリストのすべての機能を提供するクラスです。
package swing.sample; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; /** * ToDoリスト */ public class ToDoListPane extends JPanel { private JList toDoList; private DefaultListModel toDoListModel; private JTextField toDoInputField; private JButton addButton; private JButton modifyButton; private JButton removeButton; public ToDoListPane() { super(new BorderLayout()); // 一覧を生成 toDoListModel = new DefaultListModel(); toDoList = new JList(toDoListModel); JScrollPane listScrollPane = new JScrollPane(toDoList); // TODOリストにリスナを設定 toDoList.addListSelectionListener (new ToDoListSelectionHandler()); // ToDo追加用テキストフィールドの生成 toDoInputField = new JTextField(); // 各ボタンの生成 JPanel buttonPanel = new JPanel(); addButton = new JButton("追加"); modifyButton = new JButton("編集"); removeButton = new JButton("削除"); // ボタンにリスナを設定 addButton.addActionListener (new AddActionHandler()); modifyButton.addActionListener (new ModifyActionHandler()); removeButton.addActionListener (new RemoveActionHandler()); buttonPanel.add(addButton); buttonPanel.add(modifyButton); buttonPanel.add(removeButton); add(listScrollPane, BorderLayout.NORTH); add(toDoInputField, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); } /** * TODOリスト選択アクションのハンドラ */ private class ToDoListSelectionHandler implements ListSelectionListener { public void valueChanged(ListSelectionEvent arg0) { // TODOリストのどの行も選択されて いない場合や、 // 複数行が選択されている場合は、 // 何もしません if (toDoList.getSelectedIndices(). length!=1){ return; } toDoInputField.setText((String)toDoList. getSelectedValue()); } } /** * 追加ボタンアクションのハンドラ */ private class AddActionHandler implements ActionListener { public void actionPerformed(ActionEvent e) { // テキストフィールドの内容を リストモデルに追加 toDoListModel.addElement (toDoInputField.getText()); } } /** * 編集ボタンアクションのハンドラ */ private class ModifyActionHandler implements ActionListener { public void actionPerformed(ActionEvent e) { // テキストフィールドの内容で リストモデルを編集 // TODOリストのどの行も 選択されていない場合や、 // 複数行が選択されている場合は、 // 何もしません if (toDoList.getSelectedIndices(). length != 1) { return; } toDoListModel.set(toDoList. getSelectedIndex(), toDoInputField.getText()); } } /** * 削除ボタンアクションのハンドラ */ private class RemoveActionHandler implements ActionListener { public void actionPerformed(ActionEvent e) { // テキストフィールドの内容を リストモデルに追加 // TODOリストのどの行も 選択されていない場合や、 // 複数行が選択されている場合は、 // 何もしません if (toDoList.getSelectedIndices(). length != 1) { return; } setButtonsEnabled(false); Thread removeThread = new RemoveThread(toDoList.getSelectedIndex()); removeThread.start(); } } /** * ボタンの状態を更新します */ private void setButtonsEnabled(boolean enabled) { addButton.setEnabled(enabled); modifyButton.setEnabled(enabled); removeButton.setEnabled(enabled); } /** * 削除処理を行うクラス */ class RemoveThread extends Thread { int index; RemoveThread(int index) { this.index = index; } public void run() { // 時間のかかる処理を実行 doLongTask(); // イベントディスパッチスレッドで ボタンを変更 SwingUtilities.invokeLater(new Runnable() { public void run() { toDoListModel. remove(index); setButtonsEnabled(true); } }); } } /** * 時間のかかる処理 */ private void doLongTask() { try { Thread.sleep(10000); } catch (InterruptedException ex) { } }
アプリケーションの実行
「SwingAppMain」クラスを実行し、ToDoを追加してみます(図2では「20:00退社」の追加を試みようとしている)。
なお、今回は以下のような機能を実装しました。
(1)[編集]ボタンをクリックすると、一覧の選択されている1行の文字列がテキストフィールドに表示されている文字列に変更される
(2)[削除]ボタンをクリックすると、一覧の選択されている1行が削除される
Copyright © ITmedia, Inc. All Rights Reserved.