今から始めるプログラミング5
前回入力と出力のある画面ができたので、使用しているクラスについて説明します。
といってもjavaDocを参照していただきたいところです。そして日本語がわからなくなる。安心してください。僕もわかりません。
それでも解説すると。
Dimension 幅と高さを表現しています。
FlowLayout コンポーネントを一定の順序で配置します。
ActionEvent ActionListenerをimplementsすると実装しなくてはならないメソッドの引数にいて、イベントの情報を取得できたりします?僕は具体的に何かに使用する時は、Actionのもとに名前を設定して、同じメソッド内で名前でif文での分岐を行ってどのボタンが押されたとか、メニューが選択されたとか違う処理を行っていました。でも後述のクラス分割をすると不要になります。
ActionListener 解説済み
JButton ボタン
JFrame 画面
JTextField テキストフィールド
File ファイルを表現しています。データベースと並んで情報の永続化としてファイルを扱うことが多いと思うので、利用方法を一通り知っておくといいと思います。僕は昔このクラスに関連してFileChooserというクラスでファイルの選択ダイアログを使用することができるのですが、それを知らず、フォルダ選択ダイアログを自作したことがあります。不要とわかった時には微妙な気分でした。
JTable グリッド状のフィールドを作成したい時に使用。結構クセが強い?
以上が、使用したクラスの説明です。
つぎにクラス分割をしてみましょう。
といっても、すでにこのコンポーネント郡はかなり細かくクラスが用意されているので、あまり細かくする必要はなので練習みたいな感じです。
WEBアプリケーションなど応用的なアプリケーション開発においてMVCモデルというモジュールの分割がされているフレームワークが多く、表示と管理、処理を役割分担するのが通例です。もっともMVCではなくMMVCとかMVVCとかちがうそんなんじゃない、みたいなくらいいろいろあるっぽいですが。
僕としては、わかりやすいみやすければいいのでは?ぐらいでいいと思っています。
そんなわけで、ここでは、起動と画面と処理という感じで分けています。
MainClass メインクラス・・・起動について、アプリケーションで環境情報を読み込んだり初期処理を行うことを想定して分けています。ここでは入力画面を表示(コンストラクタを呼び出し)しているだけですが。
InputFrame 入力画面・・・ファイル表示したいパスを入力する画面です。
FileListFrame ファイルリスト画面・・・入力画面で入力されたパスのファイルリストを表示します。
ClosingListener クローズ処理・・・あまり通常こういう分け方しないかもしれないですが、リスナーを実装した別クラスを作りそこに処理を記述しています。閉じるボタンが押された場合の処理クラスです。閉じるボタンで起動します。
FileListListener ファイルリスト処理・・・スペルが逆かな?指定されたパスに所属するファイルのリストアップを行うクラスです。入力画面の表示ボタンで起動します。
以上のクラスのプログラムコードが以下になります。パッケージが飛んでいてすいません。
MainClass
-----------------------------------------
package sample6;
public class MainClass {
/**
* @param args
*/
public static void main(String args){
new InputFrame();
}
}
-----------------------------------------
InputFrame
-----------------------------------------
package sample6;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class InputFrame extends JFrame {
/**
* コンストラクタ
*/
public InputFrame(){
init();
}
/**
* 画面の初期化
*/
private void init(){
//タイトル
this.setTitle("入力画面");
//サイズ
this.setSize(new Dimension(200,100));
//コンテナを取得
Container container = this.getContentPane();
//レイアウトを設定する
container.setLayout(new GridLayout(3,1));
//テキストフィールドを追加
JTextField textField = new JTextField("input path");
container.add(textField);
//表示ボタンを追加
JButton viewButton = new JButton("表示");
//ボタンをリスナーに登録する
viewButton.addActionListener(new FileListListener(textField));
container.add(viewButton);
//閉じるボタンを追加
JButton closeButton = new JButton("閉じる");
container.add(closeButton);
//ボタンをリスナーに登録する
closeButton.addActionListener(new ClosingListener(this, ClosingListener.FLG_EXIT));
//表示をする
this.setVisible(true);
}
}
-----------------------------------------
FileListFrame
-----------------------------------------
package sample6;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
public class FileListFrame extends JFrame {
/**
* コンストラクタ
*
* @param files
*/
public FileListFrame(String files) {
init(files);
}
/**
* 画面の初期化
*
* @param files
*/
private void init(String files) {
// タイトル
this.setTitle("結果表示画面");
// サイズ
this.setSize(new Dimension(200, 300));
// コンテナを取得
Container container = this.getContentPane();
// レイアウトを設定する
container.setLayout(new BorderLayout());
// テーブルを表示(別のメソッドに切り出します。)
JTable table = this.initTable(files);
//コンテナに追加します
container.add(table,BorderLayout.CENTER);
// 閉じるボタンを追加
JButton closeButton = new JButton("閉じる");
//コンテナに追加
container.add(closeButton,BorderLayout.SOUTH);
//リスナーに登録
closeButton.addActionListener(new ClosingListener(this, ClosingListener.FLG_NO_EXIT));
// 表示をする
this.setVisible(true);
}
private JTable initTable(String files) {
// テーブルのオブジェクトを生成します。
// 引数としては行数、と列数を指定します。
JTable table = new JTable(files.length, 1);
// 生成したテーブルに文字列を設定していきます。
for (int i = 0; i < files.length; i++) {
//配列の数だけループします。
//i行目の1列目に文字列を設定しています
table.setValueAt(files[i], i, 0);
}
//設定したテーブルを返します
return table;
}
}
-----------------------------------------
ClosingListener
-----------------------------------------
package sample6;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class ClosingListener implements ActionListener {
private JFrame frame;
private int flg = 0;
/**終了しないフラグ**/
public static final int FLG_NO_EXIT = 0;
/**終了するフラグ**/
public static final int FLG_EXIT = -1;
/**
* コンストラクタで画面の参照を渡す
* @param frame
* @param flg
*/
public ClosingListener(JFrame frame, int flg){
this.frame = frame;
this.flg = flg;
}
public void actionPerformed(ActionEvent arg0) {
//画面を閉じる
frame.setVisible(false);
//画面を破棄する
frame.dispose();
if(flg==FLG_EXIT){
//フラグが終了するフラグだったら
//アプリケーションを終了する
System.exit(0);
}
}
}
-----------------------------------------
FileListListener
-----------------------------------------
package sample6;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JTextField;
public class FileListListener implements ActionListener {
private JTextField textField;
public FileListListener(JTextField textField){
this.textField = textField;
}
public void actionPerformed(ActionEvent arg0) {
//表示ボタンの処理
//入力されたテキストフィールドの値を取得
String path = this.textField.getText();
//パスからファイルオブジェクトを生成する
File file = new File(path);
//ファイルオブジェクトからリストを取得
String[] list = file.list();
//結果表示画面のオブジェクトを生成、リストを渡す
new FileListFrame(list);
}
}
-----------------------------------------
長くなりましたが、なんとなくクラスの分割が見えてくれれば幸いです。
もし余力があれば、管理を担当するコントローラを画面と処理の間におく分割をおこなってみてもいいと思います。画面から処理を処理から画面を参照しなくていいコーディングができると、もう上級者といっていいのでは?と思ってしまいます。
というか参照ってなんでしたっけ?という方はググってみてください。なかなか深い世界です。シャローコピーとかディープ子ピーとか。勉強しておいた方がいい知識もあります。
またここで記載したプログラムは結構穴だらけで、アプリケーションとして売り出すにはなかなかに完成度が低いです。
なので次回少しでも完成したアプリケーションに近くなるようなコーディングを紹介させていただければ、と思っています。