Newer
Older
CardRegister / src / hayashi / yuu / register / CardRegister.java
@yuuhayashi yuuhayashi on 26 Jan 2014 20 KB version 2010-03-19
package hayashi.yuu.register;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.LogManager;
import java.util.logging.Logger;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;

import jp.co.areaweb.tools.csv.CsvFile;
import jp.co.areaweb.tools.csv.CsvRecord;
import hayashi.yuu.tools.mail.gui.SettingDialog;
import hayashi.yuu.tools.properties.Encrypt;

/**
 * <b>メインウインドウフレーム</b><br/>
 * GUIでの操作。<br/>
 *
 * メニュー構成:<br/>
 *   [メニュー]<br/>
 *   [メニュー]->[ファイル(F)]<br/>
 *   [メニュー]->[ファイル(F)]->[設定...]<br/>
 *   [メニュー]->[ファイル(F)]->[カード名の保存(S)]<br/>
 *   [メニュー]->[ファイル(F)]->[終了(X)]<br/>
 *   [メニュー]->[モード(M)]<br/>
 *   [メニュー]->[モード(M)]->[冗長モード(V)]<br/>
 *   [メニュー]->[モード(M)]->[メール送信]<br/>
 *   [メニュー]->[モード(M)]->[XMLファイル出力]<br/>
 *   [メニュー]->[ヘルプ(H)]<br/>
 *   [メニュー]->[ヘルプ(H)]->[このプログラムについて...(A)]<br/>
 * <br/>
 * パネル構成:<br/>
 * 	・中央に、メインパネルを配置<br/>
 * 		・メインパネルに、テキスト表示パネルを配置<br/>
 * 		・メインパネルに、蒐集データを表示するテーブルパネルを配置<br/>
 * 	・下部にシリアル通信制御を行う「実行/停止」ボタンを配置<br/>
 *
 * @author hayashi
 *
 */
public class CardRegister extends JFrame implements ActionListener, WindowListener, PropertyChangeListener
{
	public static final String PROGRAM_NAME = "カード・レジスター";

    /**
	 * ログ設定プロパティファイルのファイル内容
	 */
	protected static final String LOGGING_PROPERTIES_DATA
	    = "handlers=java.util.logging.ConsoleHandler\n"
	    + ".level=FINEST\n"
	    + "java.util.logging.ConsoleHandler.level=INFO\n"
	    + "java.util.logging.ConsoleHandler.formatter=deister.jp.tools.YuuLogFormatter";

    /**
	 * static initializer によるログ設定の初期化
	 */
    static {
        final Logger logger = Logger.getLogger("SampleLogging");
        InputStream inStream = null;
        try {
            inStream = new ByteArrayInputStream(LOGGING_PROPERTIES_DATA.getBytes("UTF-8"));
            try {
                LogManager.getLogManager().readConfiguration(inStream);
                logger.config("ログ設定: LogManagerを設定しました。");
            }
            catch (IOException e) {
                logger.warning("ログ設定: LogManager設定の際に例外が発生しました。:" + e.toString());
            }
        }
        catch (UnsupportedEncodingException e) {
            logger.severe("ログ設定: UTF-8エンコーディングがサポートされていません。:" + e.toString());
        }
        finally {
            try {
                if (inStream != null) {
                	inStream.close();
                }
            } catch (IOException e) {
                logger.warning("ログ設定: ログ設定プロパティファイルのストリームクローズ時に例外が発生しました。:"+ e.toString());
            }
        }
    }

    public static CardRegister mainFrame;
    boolean fComponentsAdjusted;
    JPanel buttonPanel;
    JToggleButton openButton;
    JMenuBar mainMenuBar;	// [メニュー]
    JMenu menuFile;			// [メニュー]->[ファイル(F)]
    JMenuItem miSetting;	// [メニュー]->[ファイル(F)]->[設定...]
    public static SettingDialog settingDialog;

    JMenuItem miSave;		// [メニュー]->[ファイル(F)]->[登録データの保存(S)]
    JMenuItem miExit;		// [メニュー]->[ファイル(F)]->[終了(X)]
    static JCheckBoxMenuItem miMail;		// [メニュー]->[モード(M)]->[メール送信]
    static JCheckBoxMenuItem miXMLout;		// [メニュー]->[モード(M)]->[XMLファイル出力]
    JMenu menuMode;			// [メニュー]->[モード(M)]
    JMenu menuHelp;			// [メニュー]->[ヘルプ(H)]
    JMenuItem miAbout;		// [メニュー]->[ヘルプ(H)]->[このプログラムについて...(A)]
    public static JTextArea textArea;
    public static JTable recordTable;
    public static DefaultTableModel tmodel;

    static boolean tagmenteMode = false;
    static boolean autoMode = false;
    public static Logger logger;
    protected boolean openFlag = false;
    protected DeviceProcess deviceProcess = null;

    //============================================
    // 以下は、データコレクターから読み取ったデータ
    //

    /**
     * データコレクターから読み取ったレコードを保持します。
     */
    public static Vector<CollectData> dataStore = new Vector<CollectData>();

    /**
     *  デバイス(PaSoRi)のデータインスタンス
     */
    public static DeviceData device = new DeviceData();

    /**
     * カードの名称を定義したCSVファイル
     */
    public static CsvFile taglistFile = null;

    //
    // 以上
    //============================================

    /**
     * <b>「Card Register」</b><br/>
     * 起動オプション:<br/>
     *  <-mail>	メール送信モード<br/>
     *  <-xml>	XMLファイル出力モード<br/>
     *  <-tag>	タグ名定義のメンテナンスモード
     *  <-auto>	自動起動モード
     */
    public static void main(String args[]) throws Exception {
    	boolean mailMode = false;
    	boolean xmlMode = false;
    	CardRegister.tagmenteMode = false;
    	for (int i = args.length; i > 0; i--) {
			// <-mail> メール送信モード
    		if (args[i-1].equals("-mail")) {
    			mailMode = true;
    		}

			// <-xml>	XMLファイル出力モード
    		if (args[i-1].equals("-xml")) {
    			xmlMode = true;
    		}

			// <-tag> 登録タグ名称のメンテナンスモード
    		if (args[i-1].equals("-tag")) {
    			CardRegister.tagmenteMode = true;
    		}

			// <-auto>	自動起動モード
    		if (args[i-1].equals("-auto")) {
    			CardRegister.autoMode = true;
    		}
    	}

        (new CardRegister(mailMode, xmlMode)).setVisible(true);
    }

    /**
     * コンストラクタ<br/>
     *
     * @throws Exception
     */
    public CardRegister(boolean mailMode, boolean xmlMode) throws Exception {
    	Encrypt.PASSWORD_KEY = "himitukagi";		// 秘密鍵
        CardRegister.logger = Logger.getLogger(PROGRAM_NAME);		// Loggerオブジェクトの生成

        // ログ出力
        CardRegister.logger.info(PROGRAM_NAME + " - プログラム起動");

        // 初期設定
        fComponentsAdjusted = false;
        addWindowListener((WindowListener) this);
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        Container container = getContentPane();
        container.setLayout(new BorderLayout());
        setTitle(PROGRAM_NAME);

        mainFrame = this;

        // フレームアイコンの設定
        URL url = this.getClass().getResource("/hayashi/yuu/register/exe16x16.png");
        this.setIconImage(Toolkit.getDefaultToolkit().createImage(url));

        this.openFlag = false;

        // [メニュー]->[ファイル(F)]
        menuFile = new JMenu("ファイル(F)");
        menuFile.setMnemonic('F');
        menuFile.setFont(new Font("Dialog", 0, 12));

        // [メニュー]->[ファイル(F)]->[設定...]
        miSetting = new JMenuItem("設定...");
        miSetting.addActionListener(this);
        miSetting.setFont(new Font("Dialog", 0, 12));
        menuFile.add(miSetting);
        settingDialog = new SettingDialog(this, true, "config/sendmail.properties", logger);

        // [メニュー]->[ファイル(F)]->[登録データの保存(S)]
        miSave = new JMenuItem("登録データの保存(S)");
        miSave.addActionListener(this);
        miSave.setMnemonic('S');
        miSave.setFont(new Font("Dialog", 0, 12));
        menuFile.add(miSave);

        // [メニュー]->[ファイル(F)]->[------------]
        menuFile.addSeparator();

        // [メニュー]->[ファイル(F)]->[終了(X)]
        miExit = new JMenuItem("終了(X)");
        miExit.addActionListener(this);
        miExit.setMnemonic('X');
        miExit.setFont(new Font("Dialog", 0, 12));
        menuFile.add(miExit);

        // [メニュー]->[モード(M)]->[メール送信]
        miMail = new JCheckBoxMenuItem("メール送信", mailMode);
        miMail.addPropertyChangeListener((PropertyChangeListener)this);
        miMail.addActionListener(this);
        miMail.setFont(new Font("Dialog", Font.PLAIN, 12));

        // [メニュー]->[モード(M)]->[]
        miXMLout = new JCheckBoxMenuItem("XMLファイル出力", xmlMode);
        miXMLout.addPropertyChangeListener((PropertyChangeListener)this);
        miXMLout.addActionListener(this);
        miXMLout.setFont(new Font("Dialog", Font.PLAIN, 12));

        // [メニュー]->[モード(M)]
        menuMode = new JMenu("モード(M)");
        menuMode.setMnemonic('M');
        menuMode.setFont(new Font("Dialog", Font.PLAIN, 12));
        menuMode.add(miMail);
        menuMode.add(miXMLout);

        // [メニュー]->[ヘルプ(H)]->[GurdiX OEM monitor について...(A)]
        miAbout = new JMenuItem("'" + PROGRAM_NAME + "'について...(A)");
        miAbout.addActionListener(this);
        miAbout.setMnemonic('A');
        miAbout.setFont(new Font("Dialog", Font.PLAIN, 12));

        // [メニュー]->[ヘルプ(H)]
        menuHelp = new JMenu("ヘルプ(H)");
        menuHelp.setMnemonic('H');
        menuHelp.setFont(new Font("Dialog", Font.PLAIN, 12));
        menuHelp.add(miAbout);

        // [メニュー]
        mainMenuBar = new JMenuBar();
        mainMenuBar.add(menuFile);
        mainMenuBar.add(menuMode);
        mainMenuBar.add(menuHelp);
        getRootPane().setJMenuBar(mainMenuBar);

		//--------------------------------------------------------
		// 上部パネル
        // 		モニターコンソール用のテキストエリア
		//-----------------------------------------------

        // テキスト表示パネルを配置
        CardRegister.textArea = new JTextArea(5, 30) {
			@Override
			public void append(String str) {
				super.append(str);
				textArea.setCaretPosition(textArea.getDocument().getLength());
			}
        };
        CardRegister.textArea.setEditable(false);
        CardRegister.textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
		JScrollPane scrollPane = new JScrollPane(CardRegister.textArea);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.setPreferredSize(new Dimension(500, 100));
		add(BorderLayout.NORTH, scrollPane);


		//--------------------------------------------------------
		// 中央パネル
		//-----------------------------------------------

		// 蒐集データを表示するテーブルパネルを配置
		tmodel = new DefaultTableModel(CollectData.columnNames, 0) {
			@Override
			public boolean isCellEditable(int row, int column) {
				if ((column == 2) || (column == 3)) {
					return true;
				}
				return false;
			}
		};
		recordTable = new JTable(tmodel);
		recordTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		DefaultTableColumnModel columnModel  = (DefaultTableColumnModel)recordTable.getColumnModel();
		columnModel.getColumn(0).setPreferredWidth(120);
		columnModel.getColumn(1).setPreferredWidth(120);
		columnModel.getColumn(2).setPreferredWidth(240);
		columnModel.getColumn(3).setPreferredWidth(640 - 120 - 120 - 240);

		JScrollPane tablePanel = new JScrollPane(recordTable);
		tablePanel.setPreferredSize(new Dimension(644, 240));
		add(BorderLayout.CENTER, tablePanel);

		//--------------------------------------------------------
		// 下部パネル
		//-----------------------------------------------

        // 下部に「実行/停止」ボタンを配置
        openButton = new JToggleButton("実行");
        openButton.addActionListener(this);
        openButton.setToolTipText("カード読取を開始します");
        JPanel southPanel = new JPanel(new FlowLayout());
        try {
        	southPanel.add(openButton);
        	southPanel.setSize(DeviceItem.LINE_WIDTH, DeviceItem.LINE_HEIGHT);
        }
        catch(Exception e) {
            e.printStackTrace();
            CardRegister.logger.warning(e.toString());
        }
        getContentPane().add(BorderLayout.SOUTH, southPanel);

		pack();
		setLocationRelativeTo(null);
		setVisible(true);

		//-----------------------

		taglistFile = new CsvFile((new File("config/taglist.csv")).getAbsolutePath());
		taglistFile.setCharsetName("utf8");
		taglistFile.load();
		if (CardRegister.tagmenteMode) {
			for (Iterator<CsvRecord> i = CardRegister.taglistFile.iterator(); i.hasNext(); ) {
				CsvRecord record = i.next();
				String idStr = (String)record.get(0);	// ID
				String addrStr = (String)record.get(1); // address
				String nameStr = (String)record.get(2); // name
				CollectData data = new CollectData(Calendar.getInstance().getTime(), idStr, addrStr, nameStr);
				CardRegister.tmodel.addRow(data.getRecordStrs());
			}
		}

		//--------------------------
		// 自動起動
		//--
		if (CardRegister.autoMode) {
			doButtonAction();
		}
    }

	public void addNotify() {
        Dimension d = getSize();
        super.addNotify();
        if (fComponentsAdjusted) {
            return;
        }
        setSize(getInsets().left + getInsets().right + d.width, getInsets().top + getInsets().bottom + d.height);
        Component components[] = getComponents();
        for (int i = 0; i < components.length; i++) {
            Point p = components[i].getLocation();
            p.translate(getInsets().left, getInsets().top);
            components[i].setLocation(p);
        }

        fComponentsAdjusted = true;
    }

	DeviceProcess process = null;
	TouchScreen screen = null;

	/**
	 * [実行/停止]ボタンがクリックされた時のアクション
	 */
	private void doButtonAction() {
        openButton.setText("Requesting....");
        openButton.setEnabled(false);
        if (openFlag) {
            screen.screenMode = -1;
			screen.setVisible(false);
			screen.dispose();
			screen = null;
            close();
    	    openFlag = false;
    	    openButton.setText("実行");
        }
        else {
            open();
            try {
				screen = new TouchScreen("カード登録");
				screen.init();
				//screen.setVisible(true);
			}
            catch (Exception e) {
				e.printStackTrace();
				return;
			}
    	    openFlag = true;
    	    openButton.setText("停止");
        }
        openButton.setEnabled(true);
	}

	/**
	 * 「実行」ボタンをクリックしたときの処理。
	 * GuardiXデータコレクタとのシリアル通信ポートをオープンして、
	 * シリアル通信ポートからのデータ受信処理スレッドを起動する。
	 */
    public void open() {
    	CardRegister.logger.info(PROGRAM_NAME + ".open()");

        /*
         * シリアルポートからのデータ読取処理を開始する。
         */
        try {
        	this.process = new DeviceProcess();
        	this.process.start();
        }
        catch(Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, e.toString(), "Exception", 0);
        }

        setVisible(true);
    }

    /**
     * GuardiXへの通信ポートとの送受信スレッドを停止して、
     * 通信ポートをクローズする。
     */
	public void close() {
    	CardRegister.logger.info(PROGRAM_NAME + ".close()");
        try {

        	if (this.process != null) {
        		if (this.process.isAlive()) {
        			this.process.disable();
        			try {
        				this.process.join();
        			}
        			catch (InterruptedException e) {
        				System.out.println("'TelegramProcess' スレッド終了");
        			}
        		}
            	this.process = null;
        	}
        }
        catch(Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, e.toString(), "Exception", 0);
        }
	    System.gc();
    }

    /**
     * [メール送信モード]の選択状態を調べる。
     * @return	ONならば、true
     */
    public static boolean isMail() {
    	return miMail.isSelected();
    }

    /**
     * XMLファイル保存モードの選択状態を調べる。
     * @return	ONならば、true
     */
    public static boolean isXMLout() {
    	return miXMLout.isSelected();
    }

	/**
	 * [メニュー]アクション: <br/>
     * 	各メニューのアクションを呼び出す。
	 * @param event
	 */
	public void actionPerformed(ActionEvent event) {
        Object object = event.getSource();
        if(object == miExit) {
            miExit_Action(event);
        }
        else if (object == miSetting) {
            miSetting_Action(event);
        }
        else if (object == miSave) {
            miSave_Action(event);
        }
        else if (object == miAbout) {
            miAbout_Action(event);
        }
        else if (object == openButton) {
        	doButtonAction();
        }
    }

    /**
     * アクション:
     * [メニュー]->[ヘルプ]->[このプログラムについて]<br/>
     * 	このプログラムについて説明するダイアログウインドウを表示する。
     * @param event
     */
    void miAbout_Action(java.awt.event.ActionEvent event){
        (new AboutDialog(this, true)).setVisible(true);
    }

    /**
     * アクション:
     * [メニュー]->[ファイル]->[終了]<br/>
     * 	終了確認ダイアログウインドウを表示する。
     * @param event
     */
    void miExit_Action(ActionEvent event) {
        (new QuitDialog(this, true)).setVisible(true);
    }

    /**
     * アクション:
     * [メニュー]->[ファイル]->[設定...]<br/>
     * 	「メール送信設定」ダイアログウインドウを表示する。
     *
     * @param event
     */
    void miSetting_Action(ActionEvent event) {
    	settingDialog.setVisible(true);
    }

    /**
     * アクション:
     * [メニュー]->[ファイル]->[タグ名の保存(S)]<br/>
     * 	保存確認ダイアログウインドウを表示する。
     *
     * @param event
     */
    void miSave_Action(ActionEvent event) {
        (new SaveDialog(this, true)).setVisible(true);
    }

    /**
     * [メニュー]->[モード(M)]変更 : アクション<br/>
     * 	「クイックモード」の値を反映させる。
     * @param evt
     */
    public void propertyChange(PropertyChangeEvent evt) {
    	CardRegister.logger.fine(PROGRAM_NAME + ".propertyChange()");
    }

    /**
     * アクション:フレームウインドウがアクティブになった時の・オペレーション<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowActivated(WindowEvent arg0) {
	}

    /**
     * アクション:フレームウインドウが閉じられた時の・オペレーション<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowClosed(WindowEvent arg0) {
	}

    /**
     * アクション:フレームウインドウが閉じられる時の・オペレーション<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowClosing(WindowEvent arg0) {
		(new QuitDialog(this, true)).setVisible(true);
	}

    /**
     * アクション:フレームウインドウが非アクティブになった時の・オペレーション<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowDeactivated(WindowEvent arg0) {
	}

    /**
     * アクション:フレームウインドウが最小化から戻った時の・オペレーション<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowDeiconified(WindowEvent arg0) {
	}

    /**
     * アクション:フレームウインドウが最小化されたときの・オペレーション<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowIconified(WindowEvent arg0) {
	}

    /**
     * アクション:ウインドウが開いた。<br/>
     * 	何もしない。
     * @param arg0	イベント
     */
	public void windowOpened(WindowEvent arg0) {
	}
}