diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..5b2d3cc --- /dev/null +++ b/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/.externalToolBuilders/New_Builder.launch b/.externalToolBuilders/New_Builder.launch new file mode 100644 index 0000000..3547ec9 --- /dev/null +++ b/.externalToolBuilders/New_Builder.launch @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch b/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch new file mode 100644 index 0000000..7fe64af --- /dev/null +++ b/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4428c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.class +*.jar +*.zip +*.dll +test/* \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..f46adb5 --- /dev/null +++ b/.project @@ -0,0 +1,32 @@ + + + CardRegister + + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/New_Builder.launch + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..416f4fb --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..ced856e --- /dev/null +++ b/README.txt @@ -0,0 +1,57 @@ +�y�J�[�h�E���W�X�^�[�z + Card Register + version 0.85 - 2010/03/18 + +[���s�ɕK�v�ȃt�@�C��] + ./CardRegister.jar �v���O�����{�� + ./lib/activation-1.1.jar ���[�����M���C�u���� + ./lib/mail-1.4.jar ���[�����M���C�u���� + ./lib/jna.jar Java Native Access ���C�u���� + ./lib/felicalib.dll PaSoRi API���C�u���� + +[�������] + �EWindows XP (felicalib���ˑ����Ă���) + �EJRE 1.5.x �ȍ~ + +�y�K�{���C�u�����z + �E'felicalib.dll' + < http://felicalib.tmurakam.org/ > + felicalib �́AUSB�ڑ��� FeliCa(�t�F���J) ���[�_ PaSoRi(�p�\��) ���g���āAFeliCa �ɃA�N�Z�X + ���邽�߂̃��C�u�����ł��BSuica, Edy, nanaco �Ȃǂ̓d�q�}�l�[�ւ̃A�N�Z�X�ȂǂɎg�p�ł��܂��B + �t���[�\�t�g (BSD ���C�Z���X) + + �E'PaSoRi'�̐ڑ���'FeliCa�|�[�g�\�t�g�E�F�A'�̃C���X�g�[�� + < http://www.sony.co.jp/Products/felica/pcrw/ > + + �E'JNA.jar'�t�@�C�� + Java Native Access + < https://jna.dev.java.net/ > + +�y�C���X�g�[���ƋN�����@�z + (1) PaSoRi��ڑ����āA'FeliCa�|�[�g�\�t�g�E�F�A'���C���X�g�[������B + (2) �K���ȃf�B���N�g���ɁACardRegister.zip��W�J����B + (3) �W�J���ꂽ'CardRegister.bat'���_�u���N���b�N����ƋN�����܂��B + +�y�N���I�v�V�����z + > java hayashi.yuu.register.CardRegister <�I�v�V����> + <-mail> �N�����Ƀ��[�����M���[�h��ON�ɂ���B + <-xml> �N������XML�t�@�C���o�̓��[�h��ON�ɂ���B + <-tag> �J�[�h�o�^���̃����e�i���X���[�h�ŋN������B + <-auto> �u���s�{�^���v���N���b�N���ꂽ��ԂŋN������B + +�y���������z + �E�����z�P�[�^�C��FeliCa�͓ǂ߂܂���B + �E'FeliCa�|�[�g�\�t�g�E�F�A'���C���X�g�[������Ă��Ă��A�uPaSoRi�v���ڑ�����Ă��Ȃ���΃G���[�ɂȂ�܂��B + +�y�ύX�����z +�Eversion 0.85 - 2010/03/18 + �E�J�[�h���������ƃT�E���h�� + �E�����N�����[�h +�Eversion 0.84 - 2010/03/17 + �E�������[�����M + �E�Ȃ܂�����������������s��ɑΉ� +�Eversion 0.83 - 2010/03/17 + �E�J�[�h���������ƃr�[�v�� + �E�u�����������A�o�Z���܂����B�v +�Eversion 0.80 - 2010/03/12 + �E�V�K�J�� - PaSoRiReader�𗬗p \ No newline at end of file diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..d19bf10 --- /dev/null +++ b/build.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/classes/dest/CardRegister.bat b/classes/dest/CardRegister.bat new file mode 100644 index 0000000..b245c8e --- /dev/null +++ b/classes/dest/CardRegister.bat @@ -0,0 +1,3 @@ +rem java -cp ".;CardRegister.jar;lib\jna.jar;lib\hayashi_0220.jar;lib\activation-1.1.jar;lib\mail-1.4.jar" -Djava.library.path=lib hayashi.yuu.register.CardRegister + +java -cp ".;CardRegister.jar;lib\jna.jar;lib\hayashi_0220.jar;lib\activation-1.1.jar;lib\mail-1.4.jar" hayashi.yuu.register.CardRegister diff --git a/classes/dest/config/sendmail.properties b/classes/dest/config/sendmail.properties new file mode 100644 index 0000000..7f7497f --- /dev/null +++ b/classes/dest/config/sendmail.properties @@ -0,0 +1,15 @@ +#SendMail GUI +#Wed Mar 17 11:26:10 JST 2010 +MAIL_POP_before_SMTP=false +mail.smtp.from=hayashi.yuu@gmail.com +alhost= +mail.smtp.host=smtp.gmail.com +MAIL_TO=hayashi.yuu@gmail.com +MAIL_BCC= +mail.smtp.starttls.enable=true +mail.smtp.port=587 +mail.smtp.auth=true +MAIL_POP= +MAIL_CC= +mail.smtp.user=hayashi.yuu@gmail.com +MAIL_PASSWORD= diff --git a/classes/dest/config/taglist.csv b/classes/dest/config/taglist.csv new file mode 100644 index 0000000..b9ddaa1 --- /dev/null +++ b/classes/dest/config/taglist.csv @@ -0,0 +1 @@ +"01010310DA09D027","hayashi.yuu@gmail.com","�͂₵�䂤" diff --git a/classes/dest/lib/belltree.aiff b/classes/dest/lib/belltree.aiff new file mode 100644 index 0000000..8131d41 --- /dev/null +++ b/classes/dest/lib/belltree.aiff Binary files differ diff --git a/classes/dest/lib/exe32x32.png b/classes/dest/lib/exe32x32.png new file mode 100644 index 0000000..9c743fc --- /dev/null +++ b/classes/dest/lib/exe32x32.png Binary files differ diff --git a/classes/hayashi/yuu/register/exe16x16.png b/classes/hayashi/yuu/register/exe16x16.png new file mode 100644 index 0000000..f485c84 --- /dev/null +++ b/classes/hayashi/yuu/register/exe16x16.png Binary files differ diff --git a/config/sendmail.properties b/config/sendmail.properties new file mode 100644 index 0000000..c7ef14a --- /dev/null +++ b/config/sendmail.properties @@ -0,0 +1,15 @@ +#SendMail GUI +#Tue Mar 16 22:44:11 JST 2010 +MAIL_POP_before_SMTP=false +mail.smtp.from=hayashi.yuu@gmail.com +alhost= +mail.smtp.host=smtp.gmail.com +MAIL_TO= +MAIL_BCC= +mail.smtp.starttls.enable=true +mail.smtp.port=587 +mail.smtp.auth=true +MAIL_POP= +MAIL_CC= +mail.smtp.user=hayashi.yuu@gmail.com +MAIL_PASSWORD= diff --git a/config/taglist.csv b/config/taglist.csv new file mode 100644 index 0000000..e64bdff --- /dev/null +++ b/config/taglist.csv @@ -0,0 +1 @@ +"01010310DA09D027","hayashi.yuu@gmail.com","はやし" diff --git a/lib/belltree.aiff b/lib/belltree.aiff new file mode 100644 index 0000000..8131d41 --- /dev/null +++ b/lib/belltree.aiff Binary files differ diff --git a/lib/card.gif b/lib/card.gif new file mode 100644 index 0000000..53533e4 --- /dev/null +++ b/lib/card.gif Binary files differ diff --git a/lib/exe32x32.png b/lib/exe32x32.png new file mode 100644 index 0000000..9c743fc --- /dev/null +++ b/lib/exe32x32.png Binary files differ diff --git a/lib/mainbanner2.jpg b/lib/mainbanner2.jpg new file mode 100644 index 0000000..84d52c9 --- /dev/null +++ b/lib/mainbanner2.jpg Binary files differ diff --git a/make.bat b/make.bat new file mode 100644 index 0000000..20f3e67 --- /dev/null +++ b/make.bat @@ -0,0 +1,6 @@ +rem 'set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_07' +rem set ANT_HOME=c:\java\apache-ant-1.7.1 +rem set path=%path%;c:\java\apache-ant-1.7.1\bin + +ant all +pause diff --git a/src/hayashi/yuu/pasori/felica/Felica.java b/src/hayashi/yuu/pasori/felica/Felica.java new file mode 100644 index 0000000..5c80ba8 --- /dev/null +++ b/src/hayashi/yuu/pasori/felica/Felica.java @@ -0,0 +1,164 @@ +package hayashi.yuu.pasori.felica; + +import com.sun.jna.Pointer; + +/** + * このプログラムのソースは、 + * [亜細亜大学であがたが行う授業に関するサイトです。]から流用したものです。 + * http://itasan.mydns.jp/wiki.cgi/ASIA?page=Java%A4%CE%B1%FE%CD%D1%A1%A7Felica%A5%AB%A1%BC%A5%C9%A5%EA%A1%BC%A5%C0#p0 + * + * プログラムの実行には、 + * [Java Native Access (jna.jar)] + * < https://jna.dev.java.net/ > + * と、 + * [felicalib (felicalib.dll)] + * < http://felicalib.tmurakam.org/ > + * が、別途必要になります。 + * + * @author hayashi + * + */ +public class Felica +{ + final public static short WILDCARD = 0xFF; // ワイルドカード + final public static short SUICA = 0x03; + + /** + * 'PaSoRi'にかざされているFeliCaカードのIDm部分を10回読み出す。 + * 100ms間隔で300回読む。 + * @param args 引数はない + */ + public static void main(String[] args) throws Exception { + Felica task = new Felica(); + for (int i = 0; i < 300; i++) { + try { + String result = (String) task.getID(Felica.WILDCARD); + if (result != null) { + System.out.println(result); + } + } + catch (FelicaException fe) { + System.out.println(fe.toString()); + } + + try { + Thread.sleep(100); // 0.1秒間隔で読む。 + } + catch (InterruptedException e) {} + } + task.close(); + } + + Pointer pasoriHandle; + Pointer felicaHandle; + + /** + * コンストラクタ。ここでFelicaカードリーダへのハンドルを取得している + * @throws FelicaException + */ + public Felica() throws Exception { + pasoriHandle = FelicaLib.INSTANCE.pasori_open(null); + if (pasoriHandle == null) { + throw new Exception("felicalib.dllを開けません"); + } + if (FelicaLib.INSTANCE.pasori_init(pasoriHandle) != 0) { + throw new Exception("PaSoRiに接続できません"); + } + } + + /** + * PaSoRi ハンドルをクローズする + * Felicaカードリーダに関する処理を終了する際に呼ぶメソッド + * 【 void pasori_close(pasori *p) 】 + */ + public void close() { + if (felicaHandle != Pointer.NULL) { + FelicaLib.INSTANCE.felica_free(felicaHandle); + } + if (pasoriHandle != Pointer.NULL) { + FelicaLib.INSTANCE.pasori_close(pasoriHandle); + } + } + + /** + * FeliCa をポーリングする + * 【 felica* felica_polling(pasori *p, uint16 systemcode, uint8 RFU, uint8 timeslot) 】 + * + * @param systemCode + * @throws FelicaException + */ + public void polling(short systemCode) throws FelicaException { + FelicaLib.INSTANCE.felica_free(felicaHandle); + felicaHandle = FelicaLib.INSTANCE.felica_polling(pasoriHandle, systemCode, (byte)0, (byte)0); + if (felicaHandle == Pointer.NULL) { + throw new FelicaException("カード読み取り失敗"); + } + } + + /** + * IDm 取得 + * 【 void felica_getidm(felica *f, uint8 *buf) 】 + * + * @return + * @throws FelicaException + */ + public byte[] getIDm() throws FelicaException { + if (felicaHandle == Pointer.NULL) { + throw new FelicaException("no polling executed."); + } + byte[] buf = new byte[8]; + FelicaLib.INSTANCE.felica_getidm(felicaHandle, buf); + return buf; + } + + /** + * PMm 取得 + * 【 void felica_getpmm(felica *f, uint8 *buf) 】 + * + * @return + * @throws FelicaException + */ + public byte[] getPMm() throws FelicaException { + if (felicaHandle == Pointer.NULL) { + throw new FelicaException("no polling executed."); + } + byte[] buf = new byte[8]; + FelicaLib.INSTANCE.felica_getpmm(felicaHandle, buf); + return buf; + } + + /** + * FelicaカードのID番号を取得するメソッド + * @param systemCode システムコード(例えばSuicaは0x03、ワイルドカードは0xFF) + * @return カードのID番号? + * @throws FelicaException カード情報を読み取れなかった。 + */ + public String getID(short systemCode) throws FelicaException { + FelicaLib.INSTANCE.felica_free(felicaHandle); + felicaHandle = FelicaLib.INSTANCE.felica_polling(pasoriHandle, systemCode, (byte)0, (byte)0); + if (felicaHandle == Pointer.NULL) { + throw new FelicaException("カード読み取り失敗"); + } + byte[] buf = new byte[8]; + FelicaLib.INSTANCE.felica_getidm(felicaHandle, buf); + return String.format("%02X%02X%02X%02X%02X%02X%02X%02X", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); + } + + /** + * FelicaカードのPMmを取得するメソッド + * + * @param systemCode システムコード(例えばSuicaは0x03、ワイルドカードは0xFF) + * @return カードのID番号? + * @throws FelicaException + */ + public String getPM(short systemCode) throws FelicaException { + FelicaLib.INSTANCE.felica_free(felicaHandle); + felicaHandle = FelicaLib.INSTANCE.felica_polling(pasoriHandle, systemCode, (byte)0, (byte)0); + if (felicaHandle == Pointer.NULL) { + throw new FelicaException("カード読み取り失敗"); + } + byte[] buf = new byte[8]; + FelicaLib.INSTANCE.felica_getpmm(felicaHandle, buf); + return String.format("%02X%02X%02X%02X%02X%02X%02X%02X", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); + } +} diff --git a/src/hayashi/yuu/pasori/felica/FelicaException.java b/src/hayashi/yuu/pasori/felica/FelicaException.java new file mode 100644 index 0000000..a884db9 --- /dev/null +++ b/src/hayashi/yuu/pasori/felica/FelicaException.java @@ -0,0 +1,12 @@ +package hayashi.yuu.pasori.felica; + +/** + * 'felicalib.dll'操作上のエラー定義 + * + * @author hayashi + */ +public class FelicaException extends Exception { + public FelicaException(String string) { + super(string); + } +} diff --git a/src/hayashi/yuu/pasori/felica/FelicaLib.java b/src/hayashi/yuu/pasori/felica/FelicaLib.java new file mode 100644 index 0000000..099cb13 --- /dev/null +++ b/src/hayashi/yuu/pasori/felica/FelicaLib.java @@ -0,0 +1,35 @@ +package hayashi.yuu.pasori.felica; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.Pointer; + +/** + * 'felicalib.dll'へアクセスするためのインターフェイス定義 + * + * このプログラムのソースは、 + * [亜細亜大学であがたが行う授業に関するサイトです。]から流用したものです。 + * http://itasan.mydns.jp/wiki.cgi/ASIA?page=Java%A4%CE%B1%FE%CD%D1%A1%A7Felica%A5%AB%A1%BC%A5%C9%A5%EA%A1%BC%A5%C0#p0 + * + * プログラムの実行には、 + * [Java Native Access (jna.jar)] + * < https://jna.dev.java.net/ > + * と、 + * [felicalib (felicalib.dll)] + * < http://felicalib.tmurakam.org/ > + * が、別途必要になります。 + * + * @author hayashi + */ +public interface FelicaLib extends Library { + FelicaLib INSTANCE = (FelicaLib) Native.loadLibrary("lib/felicalib", FelicaLib.class); + + Pointer pasori_open(String dummy); + int pasori_init(Pointer pasoriHandle); + void pasori_close(Pointer pasoriHandle); + Pointer felica_polling(Pointer pasoriHandle, short systemCode, byte rfu, byte time_slot); + void felica_free(Pointer felicaHandle); + void felica_getidm(Pointer felicaHandle, byte[] data); + void felica_getpmm(Pointer felicaHandle, byte[] data); + int felica_read_without_encryption02(Pointer felicaHandle, int serviceCode, int mode, byte addr, byte[] data); +} diff --git a/src/hayashi/yuu/register/AboutDialog.java b/src/hayashi/yuu/register/AboutDialog.java new file mode 100644 index 0000000..d29b57a --- /dev/null +++ b/src/hayashi/yuu/register/AboutDialog.java @@ -0,0 +1,154 @@ +package hayashi.yuu.register; +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +public class AboutDialog extends JDialog implements WindowListener +{ + static final String TITLE = CardRegister.PROGRAM_NAME; + static final String COPY_RIGHT = "All rights reserved.Copyright(c) 2010,, Yuu Hayashi."; + + JLabel label1; + JButton okButton; + JLabel label2; + JTextArea textArea; + JFrame parent; + + public AboutDialog(JFrame parent, boolean modal) { + super(parent, modal); + addWindowListener(this); + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + this.parent = parent; + setTitle("About..."); + getContentPane().setLayout(new BorderLayout()); + setSize(512,320); + + //-------------------------------------------------------- + // 上部パネル + //----------------------------------------------- + label1 = new JLabel(TITLE, JLabel.CENTER); + add(BorderLayout.NORTH, label1); + + //-------------------------------------------------------- + // 中央パネル + //----------------------------------------------- + + /* + * [README.txt]ファイルの内容を表示するTEXTAREA + */ + textArea = new JTextArea(7, 60); + textArea.setEditable(false); + textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + JScrollPane scrollPane = new JScrollPane(textArea); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(BorderLayout.CENTER, scrollPane); + + URL url = getClass().getResource("/README.txt"); + InputStream is; + try { + is = url.openStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + while (br.ready()) { + textArea.append(br.readLine() + "\n"); + } + textArea.setCaretPosition(0); + br.close(); + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + //-------------------------------------------------------- + // 下部パネル + //----------------------------------------------- + JPanel bottonPanel = new JPanel(); + bottonPanel.setLayout(new BorderLayout()); + add(BorderLayout.SOUTH, bottonPanel); + + /* + * [OK]ボタン : このダイアログウインドウを閉じる + */ + okButton = new JButton("OK"); + okButton.setBounds(145,65,66,27); + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new WindowEvent(AboutDialog.this, WindowEvent.WINDOW_CLOSING)); + setVisible(false); + } + }); + JPanel okPanel = new JPanel(new FlowLayout()); + try { + okPanel.add(okButton); + } + catch(Exception e) { + e.printStackTrace(); + CardRegister.logger.warning(e.toString()); + } + bottonPanel.add(BorderLayout.CENTER, okPanel); + + /* + * コピーライト表示 + */ + label2 = new JLabel(COPY_RIGHT, JLabel.CENTER); + label2.setBounds(10,40,340,20); + bottonPanel.add(BorderLayout.SOUTH, label2); + + setVisible(true); + } + + /** + * Shows or hides the component depending on the boolean flag b. + * @param b if true, show the component; otherwise, hide the component. + * @see java.awt.Component#isVisible + */ + public void setVisible(boolean b) { + if (b) { + Rectangle bounds = getParent().getBounds(); + Rectangle abounds = getBounds(); + setLocation(bounds.x + (bounds.width - abounds.width)/ 2, + bounds.y + (bounds.height - abounds.height)/2); + } + super.setVisible(b); + } + + public void windowClosed(WindowEvent e) { + setVisible(false); + } + + public void windowActivated(WindowEvent arg0) { + } + + public void windowClosing(WindowEvent arg0) { + setVisible(false); + } + + public void windowDeactivated(WindowEvent arg0) { + } + + public void windowDeiconified(WindowEvent arg0) { + } + + public void windowIconified(WindowEvent arg0) { + } + + public void windowOpened(WindowEvent arg0) { + } +} diff --git a/src/hayashi/yuu/register/BlankModePanel.java b/src/hayashi/yuu/register/BlankModePanel.java new file mode 100644 index 0000000..94ee794 --- /dev/null +++ b/src/hayashi/yuu/register/BlankModePanel.java @@ -0,0 +1,27 @@ +package hayashi.yuu.register; + +import javax.swing.JLabel; +import java.awt.Font; +import java.awt.GridLayout; + +public class BlankModePanel extends MainPanel +{ + /** + * コンストラクタ + * @param touchScreen 親フレーム + */ + public BlankModePanel(TouchScreen touchScreen) { + super(); + this.parent = touchScreen; + setParentFrame(touchScreen); + + this.setSize(800, 300); + this.setLayout(new GridLayout(2, 1)); + this.add(new JLabel()); + JLabel text = new JLabel("IDカードをかざしてください。", JLabel.CENTER); + text.setFont(new Font("MS PGothic", Font.BOLD, 18)); + this.add(text); + } + + TouchScreen parent; +} diff --git a/src/hayashi/yuu/register/CardRegister.java b/src/hayashi/yuu/register/CardRegister.java new file mode 100644 index 0000000..b08d811 --- /dev/null +++ b/src/hayashi/yuu/register/CardRegister.java @@ -0,0 +1,633 @@ +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; + +/** + * メインウインドウフレーム
+ * GUIでの操作。
+ * + * メニュー構成:
+ * [メニュー]
+ * [メニュー]->[ファイル(F)]
+ * [メニュー]->[ファイル(F)]->[設定...]
+ * [メニュー]->[ファイル(F)]->[カード名の保存(S)]
+ * [メニュー]->[ファイル(F)]->[終了(X)]
+ * [メニュー]->[モード(M)]
+ * [メニュー]->[モード(M)]->[冗長モード(V)]
+ * [メニュー]->[モード(M)]->[メール送信]
+ * [メニュー]->[モード(M)]->[XMLファイル出力]
+ * [メニュー]->[ヘルプ(H)]
+ * [メニュー]->[ヘルプ(H)]->[このプログラムについて...(A)]
+ *
+ * パネル構成:
+ * ・中央に、メインパネルを配置
+ * ・メインパネルに、テキスト表示パネルを配置
+ * ・メインパネルに、蒐集データを表示するテーブルパネルを配置
+ * ・下部にシリアル通信制御を行う「実行/停止」ボタンを配置
+ * + * @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 dataStore = new Vector(); + + /** + * デバイス(PaSoRi)のデータインスタンス + */ + public static DeviceData device = new DeviceData(); + + /** + * カードの名称を定義したCSVファイル + */ + public static CsvFile taglistFile = null; + + // + // 以上 + //============================================ + + /** + * 「Card Register」
+ * 起動オプション:
+ *  <-mail> メール送信モード
+ *  <-xml> XMLファイル出力モード
+ *  <-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); + } + + /** + * コンストラクタ
+ * + * @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 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(); + } + + /** + * [メニュー]アクション:
+ * 各メニューのアクションを呼び出す。 + * @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(); + } + } + + /** + * アクション: + * [メニュー]->[ヘルプ]->[このプログラムについて]
+ * このプログラムについて説明するダイアログウインドウを表示する。 + * @param event + */ + void miAbout_Action(java.awt.event.ActionEvent event){ + (new AboutDialog(this, true)).setVisible(true); + } + + /** + * アクション: + * [メニュー]->[ファイル]->[終了]
+ * 終了確認ダイアログウインドウを表示する。 + * @param event + */ + void miExit_Action(ActionEvent event) { + (new QuitDialog(this, true)).setVisible(true); + } + + /** + * アクション: + * [メニュー]->[ファイル]->[設定...]
+ * 「メール送信設定」ダイアログウインドウを表示する。 + * + * @param event + */ + void miSetting_Action(ActionEvent event) { + settingDialog.setVisible(true); + } + + /** + * アクション: + * [メニュー]->[ファイル]->[タグ名の保存(S)]
+ * 保存確認ダイアログウインドウを表示する。 + * + * @param event + */ + void miSave_Action(ActionEvent event) { + (new SaveDialog(this, true)).setVisible(true); + } + + /** + * [メニュー]->[モード(M)]変更 : アクション
+ * 「クイックモード」の値を反映させる。 + * @param evt + */ + public void propertyChange(PropertyChangeEvent evt) { + CardRegister.logger.fine(PROGRAM_NAME + ".propertyChange()"); + } + + /** + * アクション:フレームウインドウがアクティブになった時の・オペレーション
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowActivated(WindowEvent arg0) { + } + + /** + * アクション:フレームウインドウが閉じられた時の・オペレーション
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowClosed(WindowEvent arg0) { + } + + /** + * アクション:フレームウインドウが閉じられる時の・オペレーション
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowClosing(WindowEvent arg0) { + (new QuitDialog(this, true)).setVisible(true); + } + + /** + * アクション:フレームウインドウが非アクティブになった時の・オペレーション
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowDeactivated(WindowEvent arg0) { + } + + /** + * アクション:フレームウインドウが最小化から戻った時の・オペレーション
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowDeiconified(WindowEvent arg0) { + } + + /** + * アクション:フレームウインドウが最小化されたときの・オペレーション
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowIconified(WindowEvent arg0) { + } + + /** + * アクション:ウインドウが開いた。
+ * 何もしない。 + * @param arg0 イベント + */ + public void windowOpened(WindowEvent arg0) { + } +} diff --git a/src/hayashi/yuu/register/CollectData.java b/src/hayashi/yuu/register/CollectData.java new file mode 100644 index 0000000..98e1e19 --- /dev/null +++ b/src/hayashi/yuu/register/CollectData.java @@ -0,0 +1,137 @@ +package hayashi.yuu.register; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Iterator; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import jp.co.areaweb.tools.csv.CsvRecord; + +public class CollectData +{ + public Calendar date = Calendar.getInstance(); + public String address = null; + public String name = null; + public String data = ""; + public static Calendar baseDate = null; + public static String[] columnNames = {"日時", "カードID", "送信先アドレス","なまえ"}; + + static final String DATETIME_PATTERN = "yyyy/MM/dd'-'HH:mm:ss"; + static SimpleDateFormat dateTimePattern = new SimpleDateFormat(DATETIME_PATTERN); + + /** + * コンストラクタ: データコレクタで取得したデータ + * @param datetime + * @param data + * @param address + * @param name + */ + public CollectData(Date datetime, String data, String address, String name) { + date.setTime(datetime); + if (date.get(Calendar.YEAR) < 2000) { + if (baseDate != null) { + date.set(baseDate.get(Calendar.YEAR), baseDate.get(Calendar.MONTH), baseDate.get(Calendar.DAY_OF_MONTH)); + } + } + else { + CollectData.baseDate = Calendar.getInstance(); + CollectData.baseDate.set(date.get(Calendar.YEAR), date.get(Calendar.MONTH), date.get(Calendar.DAY_OF_MONTH)); + } + this.data = data; + if (address == null) { + this.address = getAddress(data); + } + else { + this.address = address; + } + if (name == null) { + this.name = getName(data); + } + else { + this.name = name; + } + } + + public CollectData(Date datetime, String data) { + this(datetime, data, null, null); + } + + /** + * 収集データをXML形式にして表現する。 + * @return XMLレコード + */ + public Element getXmlElement(Document document) { + Element point = document.createElement("point"); + point.setAttribute("id", this.data); + point.setAttribute("datetime", dateTimePattern.format(this.date.getTime())); + + Element addrEle = document.createElement("address"); + addrEle.appendChild(document.createTextNode(this.address)); + point.appendChild(addrEle); + + Element nameEle = document.createElement("name"); + nameEle.appendChild(document.createTextNode(this.name)); + point.appendChild(nameEle); + + return point; + } + + + /** + * [javax.swing.table.DefaultTableModel]用のレコード形式を取得する。 + * @return + */ + public String[] getRecordStrs() { + String[] strs = new String[4]; + strs[0] = dateTimePattern.format(this.date.getTime()); + strs[1] = this.data; + strs[2] = this.address; + strs[3] = this.name; + return strs; + } + + /** + * カードIDを取得する + * @return カードID(IDm) - 16文字の16進表記 '01010310DA09D027' + */ + public long getId() { + return Long.parseLong(this.data, 16); + } + + public String getAddress(String dataStr) { + if (CardRegister.taglistFile == null) { + return ""; + } + for (Iterator i = CardRegister.taglistFile.iterator(); i.hasNext(); ) { + CsvRecord record = i.next(); + String idStr = (String)record.get(0); // ID + if (idStr.equals(dataStr)) { + return (String)record.get(1); // ID + } + } + return ""; + } + + public String getName(String dataStr) { + if (CardRegister.taglistFile == null) { + return ""; + } + for (Iterator i = CardRegister.taglistFile.iterator(); i.hasNext(); ) { + CsvRecord record = i.next(); + String idStr = (String)record.get(0); // ID + if (idStr.equals(dataStr)) { + try { + String ret = (String)record.get(2); // ID + return ret; // ID + } + catch (IndexOutOfBoundsException ioobe) { + return ""; + } + } + } + return ""; + } +} diff --git a/src/hayashi/yuu/register/DeviceData.java b/src/hayashi/yuu/register/DeviceData.java new file mode 100644 index 0000000..d92f8db --- /dev/null +++ b/src/hayashi/yuu/register/DeviceData.java @@ -0,0 +1,235 @@ +package hayashi.yuu.register; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class DeviceData +{ + /** + * コンストラクタ: データコレクタのデータ + */ + public DeviceData() { + deviceName = null; + typeID = null; + verAVR = null; + dateAVR = null; + verMSP = null; + } + + /** + * データコレクターのデバイス識別コード + * (製品のシリアル番号です) + */ + String deviceID = null; + + /** + * データコレクターのデバイス識別コードを取得する + * @return デバイス識別コード(製品のシリアル番号) + */ + public String getDeviceID() { + return this.deviceID; + } + + /** + * データコレクターのデバイス識別コードを設定する。 + * @param deviceID デバイス識別コード(製品のシリアル番号) + */ + public void setDeviceID(String deviceID) { + this.deviceID = deviceID; + } + + /** + * データコレクターを識別するためにユーザーが定義した名称。 + * 未定義のときは、NULLとする。 + */ + String deviceName = null; // デバイスの定義名称 + + /** + * このデバイスの名称を取得する。 + * 名称が未定義の時は、NULLが戻る。 + * @return デバイス名称 + */ + public String getDeviceName() { + return this.deviceName; + } + + /** + * このデバイスの名称を定義する。 + * @param deviceName + */ + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + String typeID = null; + + public String getTypeID() { + return typeID; + } + + public void setTypeID(String typeID) { + this.typeID = typeID; + } + + /** + * このデバイスの「タイプ名」 + */ + String typeName = "GuardiX OEM"; + + /** + * このデバイスの「タイプ名」を取得する。 + * @return タイプ名 + */ + public String getTypeName() { + return this.typeName; + } + + /** + * ステータス + */ + public int status; + + public int getStatus() { + return this.status; + } + + public void setStatus(int status) { + this.status = status; + } + + public void setStatus(String statusStr) { + this.status = Integer.parseInt(statusStr, 16); + } + + public String getStatusName() { + if (status == 0x02) { + return ("正常"); + } + StringBuffer sbuf = new StringBuffer(); + if ((status & 0x02) == 0) { + sbuf.append("残データあり "); + } + else { + sbuf.append("残データなし "); + } + sbuf.append("["); + if ((status & 0x01) != 0) { + sbuf.append("RAMエラー発生! , "); + } + if ((status & 0x04) != 0) { + sbuf.append("要バッテリー交換! , "); + } + if ((status & 0x08) != 0) { + sbuf.append("メモリーオーバー!"); + } + sbuf.append("]"); + return sbuf.toString(); + } + + /** + * AVR version + */ + String verAVR = null; + + public String getVerAVR() { + return this.verAVR; + } + + public void setVerAVR(String verAVR) { + this.verAVR = verAVR; + } + + /** + * AVR date + */ + Date dateAVR = null; + + public Date getDateAVR() { + return this.dateAVR; + } + + public void setDateAVR(Date dateAVR) { + this.dateAVR = dateAVR; + } + + public void setDateAVR(String dateAVRstr) throws ParseException { + this.dateAVR = (new SimpleDateFormat("yyyyMMdd")).parse(dateAVRstr); + } + + /** + * MSP version + */ + String verMSP = null; + + public String getVerMSP() { + return verMSP; + } + + public void setVerMSP(String verMSP) { + this.verMSP = verMSP; + } + + /** + * Version Type + */ + String verType = null; + + + public String getVerType() { + return verType; + } + + public void setVerType(String verType) { + this.verType = verType; + } + + + /** + * 収集データをXML形式にして表現する。 + * @return XMLレコード + */ + public Element getXmlElement(Document document) { + Element device = document.createElement("device"); + String idStr = getDeviceID(); + if (idStr != null) { + device.setAttribute("sn", idStr); + } + + if (getTypeID() != null) { + Element type = document.createElement("type"); + type.setAttribute("id", getTypeID()); + type.appendChild(document.createTextNode(getTypeName())); + device.appendChild(type); + } + + if (getVerAVR() != null) { + Element avr = document.createElement("AVR"); + avr.setAttribute("ver", getVerAVR()); + if (getDateAVR() != null) { + avr.setAttribute("date", (new SimpleDateFormat("yyyy/MM/dd")).format(getDateAVR())); + } + device.appendChild(avr); + } + + if (getVerMSP() != null) { + Element msp = document.createElement("AVR"); + msp.setAttribute("ver", getVerMSP()); + if (getVerType() != null) { + msp.setAttribute("type", getVerType()); + } + device.appendChild(msp); + } + + String name = getDeviceName(); + if (name != null) { + Element nameEle = document.createElement("name"); + nameEle.appendChild(document.createTextNode(name)); + device.appendChild(nameEle); + } + return device; + } +} diff --git a/src/hayashi/yuu/register/DeviceItem.java b/src/hayashi/yuu/register/DeviceItem.java new file mode 100644 index 0000000..04a939d --- /dev/null +++ b/src/hayashi/yuu/register/DeviceItem.java @@ -0,0 +1,75 @@ +package hayashi.yuu.register; + +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/** + * public class PropertyItem extends JPanel implements ActionListener + * @author hayashi + * + */ +public abstract class DeviceItem extends JPanel implements ActionListener +{ + JLabel label; + JComponent field; + String value; // 設定データを保持する領域 + public static final int ITEM_WIDTH_1 = 120; + public static final int ITEM_WIDTH_2 = 80; + public static final int LINE_WIDTH = ITEM_WIDTH_1 + ITEM_WIDTH_2; + public static final int LINE_HEIGHT = 18; + + /** + * コンストラクタ + * @param prop2 + * @param name + * @param editable + */ + public DeviceItem(String name) { + super(null); + this.value = new String(""); + } + + void createItem(String name, String value) { + this.value = value; + setupLabel(name, value); + setupField(value); + + label.setBounds(0, 0, ITEM_WIDTH_1 - 6, LINE_HEIGHT); + field.setBounds(ITEM_WIDTH_1, 0, ITEM_WIDTH_2, LINE_HEIGHT); + setPreferredSize(new Dimension(ITEM_WIDTH_1, LINE_HEIGHT)); + } + + JLabel setupLabel(String name, String value) { + label = new JLabel(name, JLabel.RIGHT); + add(label); + return label; + } + + /** + * コーディング例: + * + * void setupField(String name, String value) { + * this.value = value; + * ((JTextField)field).setText(value); + * field.setFont(new Font("MS UI Gothic", Font.PLAIN, 12)); + * add(field); + * } + */ + abstract void setupField(String value); + + /** + * [反映]ボタンがクリックされたときの処理 + * + * public void actionPerformed(ActionEvent e) { + * GuardixMonitor.logger.fine("[反映] "+ label.getText() +" = "+ text.getText()); + * prop.setProperty(label.getText(), text.getText()); + * } + * @param e + */ + public abstract void actionPerformed(ActionEvent e); +} diff --git a/src/hayashi/yuu/register/DeviceProcess.java b/src/hayashi/yuu/register/DeviceProcess.java new file mode 100644 index 0000000..45f4975 --- /dev/null +++ b/src/hayashi/yuu/register/DeviceProcess.java @@ -0,0 +1,250 @@ +package hayashi.yuu.register; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Vector; +import java.util.concurrent.FutureTask; + +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; +import javax.swing.JOptionPane; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import hayashi.yuu.pasori.felica.Felica; +import hayashi.yuu.pasori.felica.FelicaException; +import hayashi.yuu.tools.PlaySound; +import hayashi.yuu.tools.SpeedMail; + +public class DeviceProcess extends Thread +{ + public static boolean doing = true; + + public DeviceProcess() throws IOException, UnsupportedAudioFileException, LineUnavailableException { + super(); + init(); + } + + /** + * 参照: + *  ArrayList SerialPortReader.rcvBuffer + */ + public void run() { + String zenkai = null; + Felica task = null; + try { + task = new Felica(); + while (DeviceProcess.doing) { + try { + String result = task.getID(Felica.WILDCARD); + if ((zenkai == null) || !zenkai.equals(result)) { + /* + * 新しい電文を受信できた。 + */ + System.out.println(result); + + command(result); + zenkai = new String(result); + } + } + catch (FelicaException e) { + // 読み取れなかったらそのまま + zenkai = null; + } + + if (!DeviceProcess.doing) { + break; + } + + try { + Thread.sleep(500); + } + catch (InterruptedException e) {} + } + } + catch (Exception e) { + e.printStackTrace(); + CardRegister.logger.warning("'FeliCa'デバイスに接続出来ませんでした。"); + JOptionPane.showMessageDialog(CardRegister.mainFrame, "'FeliCa'デバイスに接続出来ませんでした", "エラー", 0); + } + finally { + if (task != null) { + task.close(); + task = null; + } + } + } + + public void disable() { + DeviceProcess.doing = false; + } + + static final byte CTRL_STX = (byte)0x00fe; + static final byte CTRL_ETX = (byte)0x0003; + static final byte CTRL_NAK = (byte)0x0015; + static final byte CTRL_ACK = (byte)0x0006; + + // 新たな電文を受け取る準備が出来ているかどうか + boolean telegram = false; + + PlaySound sound = null; + + /** + * 各種内部フラグをリセットして初期状態に戻す。 + * @throws LineUnavailableException + * @throws UnsupportedAudioFileException + * @throws IOException + */ + public void init() throws IOException, UnsupportedAudioFileException, LineUnavailableException { + /* + * デバイス内部状態の初期化 + */ + DeviceProcess.doing = true; + CardRegister.device = new DeviceData(); + sound = new PlaySound(); + } + + /** + * 'EXT'を受信した後の、次のコマンドを送信するシーケンス処理 + * @throws LineUnavailableException + * @throws UnsupportedAudioFileException + * + */ + @SuppressWarnings("unchecked") + void command(String rcvStr) throws IOException, UnsupportedAudioFileException, LineUnavailableException { + sound.start(); + + /* + * 蒐集したデータを表示する + */ + CardRegister.textArea.append(rcvStr + "\n"); + CollectData rec = new CollectData(new Date(), rcvStr, null, null); + CardRegister.dataStore.add(rec); + CardRegister.tmodel.addRow(rec.getRecordStrs()); + + /* + * 蒐集したデータをメールで送信する + */ + if (CardRegister.isMail()) { + try { + StringBuffer contentSbuf = new StringBuffer("○○小学校登下校通知システムからのお知らせ。\n"); + contentSbuf.append("\n"); + + String[] recitem = rec.getRecordStrs(); + contentSbuf.append(" 日 時:\t"+ recitem[0] +"\n"); + contentSbuf.append(" カード:\t"+ recitem[1] +"\n"); + contentSbuf.append(" 送信先:\t"+ recitem[2] +"\n"); + contentSbuf.append(" なまえ:\t"+ recitem[3] +"\n"); + + FutureTask task; + SpeedMail mail; + mail = new SpeedMail(CardRegister.settingDialog.getPropertiesFilename()); + + mail.setSubject(recitem[3] +"ちゃん、登校しました。"); + mail.setContent(contentSbuf.toString()); + if (!recitem[2].equals("")) { + mail.setTo(recitem[2]); + } + + task = new FutureTask(mail); + new Thread(task).start(); + + //---------------------------------------------------------------------- + // 送信完了を待つと、カードを連続でかざされた時の処理が間に合わなくなる + //---------------- + /* + try { + task.get(); + CardRegister.textArea.append("メールを送信しました。\n"); + CardRegister.logger.info("メールを送信しました。"); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + catch (ExecutionException e) { + e.printStackTrace(); + } + */ + } + catch (Exception e) { + e.printStackTrace(); + CardRegister.logger.warning("メール送信に失敗しました。"); + JOptionPane.showMessageDialog(CardRegister.mainFrame, "メール送信を送信できませんでした。", "エラー", 0); + } + } + + /* + * 蒐集したデータをXMLファイルにして保存する + */ + if (CardRegister.isXMLout()) { + try { + DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docbuilder = dbfactory.newDocumentBuilder(); + Document document = docbuilder.newDocument(); // Documentの生成 + + Element root = document.createElement("collect"); // root(collect)ノード作成 + document.appendChild(root); // ノードをDocumentに追加 + + Calendar now = Calendar.getInstance(); + root.setAttribute("datetime", (new SimpleDateFormat("yyyy/MM/dd'-'HH:mm:ss")).format(now.getTime())); + + /* + * device要素を生成 + */ + Element device = CardRegister.device.getXmlElement(document); + root.appendChild(device); + + /* + * 読み取ったチェックポイント情報の要素を生成 + */ + Element point = rec.getXmlElement(document); + root.appendChild(point); + + /* + * DOMオブジェクトを文字列として出力 + */ + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer; + transformer = tfactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + + File outfile = new File("data_"+ (new SimpleDateFormat("yyyyMMddHHmmss")).format(now.getTime()) + ".xml"); + transformer.transform(new DOMSource(document), new StreamResult(outfile)); + + CardRegister.logger.info("XMLファイルにして保存しました。"); + } + catch (ParserConfigurationException e) { + e.printStackTrace(); + CardRegister.logger.warning("XMLファイルに保存失敗! (ParserConfigurationException)"); + } + catch (TransformerConfigurationException e) { + e.printStackTrace(); + CardRegister.logger.warning("XMLファイルに保存失敗! (TransformerConfigurationException)"); + } + catch (TransformerException e) { + e.printStackTrace(); + CardRegister.logger.warning("XMLファイルに保存失敗! (TransformerException)"); + } + } + + /* + * 蒐集したデータを削除する。 + */ + CardRegister.dataStore = new Vector(); + init(); + } +} diff --git a/src/hayashi/yuu/register/DeviceSelectItem.java b/src/hayashi/yuu/register/DeviceSelectItem.java new file mode 100644 index 0000000..d1d6342 --- /dev/null +++ b/src/hayashi/yuu/register/DeviceSelectItem.java @@ -0,0 +1,54 @@ +package hayashi.yuu.register; + +import java.awt.event.ActionEvent; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.util.Hashtable; + +import javax.swing.JComboBox; + +public class DeviceSelectItem extends DeviceItem implements FocusListener { + Hashtable prop; // 設定データを保持する領域 + String name; + + public DeviceSelectItem(Hashtable prop, String name, String[] items) { + super(name); + this.prop = prop; + this.name = name; + field = new JComboBox(); + ((JComboBox)field).addFocusListener(this); + for (int i=0; i < items.length; i++) { + ((JComboBox)field).addItem(items[i]); + } + createItem(name, items[0]); + } + + @Override + void setupField(String value) { + this.value = value; + prop.put(this.name, value); + ((JComboBox)field).setSelectedItem(value); + add(field); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.value = (String) ((JComboBox)this.field).getSelectedItem(); + CardRegister.logger.fine("[反映] "+ label.getText() +" = "+ this.value); + prop.put(label.getText(), this.value); + } + + /** + * このフィールドにカーソルが移ったときの処理 + */ + public void focusGained(FocusEvent arg0) { + // 何もしない + } + + /** + * このフィールドから他のフィールドへカーソルが移った時の処理。 + */ + public void focusLost(FocusEvent e) { + actionPerformed(null); + } +} diff --git a/src/hayashi/yuu/register/FooterPanel.java b/src/hayashi/yuu/register/FooterPanel.java new file mode 100644 index 0000000..b6ebca1 --- /dev/null +++ b/src/hayashi/yuu/register/FooterPanel.java @@ -0,0 +1,34 @@ +package hayashi.yuu.register; + +import javax.swing.*; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.GridBagLayout; + +public class FooterPanel extends JPanel +{ + GridBagLayout gbLayout = new GridBagLayout(); + + /** + * コンストラクタ + * @param keytagID + * @throws Exception + */ + public FooterPanel(String siteName) throws Exception { + super(); + this.setBackground(Color.DARK_GRAY); + + //------------------------------------------- + // Inner Reader panel + //---- + this.setLayout(new FlowLayout(FlowLayout.CENTER)); + this.setSize(800, 100); + + //------------------------------------------- + // ユーザーサイト名称 + //---- + JLabel siteNameLabel = new JLabel("ユーザーサイト : '"+ siteName +"' "); + siteNameLabel.setForeground(Color.LIGHT_GRAY); + add(siteNameLabel); + } +} diff --git a/src/hayashi/yuu/register/MainPanel.java b/src/hayashi/yuu/register/MainPanel.java new file mode 100644 index 0000000..dfa483d --- /dev/null +++ b/src/hayashi/yuu/register/MainPanel.java @@ -0,0 +1,54 @@ +package hayashi.yuu.register; + +import javax.swing.JPanel; + + +public class MainPanel extends JPanel implements MainPanelData +{ + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // + // スレッド に関するメソッド + // + + public static int timecount = 0; + + public static int getTimecount() { + return timecount; + } + + public static void setTimecount(int timecount) { + MainPanel.timecount = timecount; + } + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // + // MainPanel に関する共通メソッド + // + TouchScreen parentFrame; // 親フレーム + CollectData loginUser; // 認証されたユーザー(USER_MODEのときのみ有効) + + public long getLoginUserId() { + if (this.loginUser == null) { + return 0L; + } + return this.loginUser.getId(); + } + + public CollectData getLoginUser() { + return this.loginUser; + } + + public TouchScreen getParentFrame() { + return this.parentFrame; + } + + public void setLoginUser(CollectData loginUser) { + this.loginUser = loginUser; + } + + public void setParentFrame(TouchScreen touchScreen) { + this.parentFrame = touchScreen; + } +} diff --git a/src/hayashi/yuu/register/MainPanelData.java b/src/hayashi/yuu/register/MainPanelData.java new file mode 100644 index 0000000..eb8220b --- /dev/null +++ b/src/hayashi/yuu/register/MainPanelData.java @@ -0,0 +1,35 @@ +package hayashi.yuu.register; + + +public interface MainPanelData { + /** + * 親フレームの設定 + * @param parentFrame + */ + public void setParentFrame(TouchScreen parentFrame); + + /** + * 親フレームの取得 + * @return + */ + public TouchScreen getParentFrame(); + + /** + * ログインユーザーの設定 + * @param loginUser + */ + public void setLoginUser(CollectData loginUser); + + /** + * ログインユーザーの取得 + * @return + */ + public CollectData getLoginUser(); + + /** + * ログインユーザーの取得 + * @return + */ + public long getLoginUserId(); + +} diff --git a/src/hayashi/yuu/register/QuitDialog.java b/src/hayashi/yuu/register/QuitDialog.java new file mode 100644 index 0000000..1283773 --- /dev/null +++ b/src/hayashi/yuu/register/QuitDialog.java @@ -0,0 +1,91 @@ +package hayashi.yuu.register; + +import java.awt.Font; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; + +public class QuitDialog extends JDialog implements WindowListener +{ + JButton yesButton; + JButton noButton; + JLabel label1; + + public QuitDialog(JFrame parent, boolean modal) { + super(parent, modal); + addWindowListener((WindowListener) this); + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + setLayout(null); + setSize(getInsets().left + getInsets().right + 337, getInsets().top + getInsets().bottom + 135); + + yesButton = new JButton(" 終了 "); + yesButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new WindowEvent((Window)getParent(), 201)); + System.exit(0); + } + }); + yesButton.setBounds(getInsets().left + 72, getInsets().top + 80, 79, 22); + yesButton.setFont(new Font("Dialog", 1, 12)); + add(yesButton); + + noButton = new JButton("キャンセル"); + noButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new WindowEvent(QuitDialog.this, WindowEvent.WINDOW_CLOSING)); + setVisible(false); + } + }); + noButton.setBounds(getInsets().left + 185, getInsets().top + 80, 99, 22); + noButton.setFont(new Font("Dialog", 1, 12)); + add(noButton); + + label1 = new JLabel("プログラムを終了します。", JLabel.CENTER); + label1.setBounds(78, 33, 180, 23); + add(label1); + setTitle("プログラムの終了"); + setResizable(false); + setVisible(true); + } + + public void setVisible(boolean b) { + if(b) { + Rectangle bounds = getParent().getBounds(); + Rectangle abounds = getBounds(); + setLocation(bounds.x + (bounds.width - abounds.width) / 2, bounds.y + (bounds.height - abounds.height) / 2); + } + super.setVisible(b); + } + + + public void windowActivated(WindowEvent e) { + } + + public void windowClosed(WindowEvent e) { + setVisible(false); + } + + public void windowClosing(WindowEvent e) { + setVisible(false); + } + + public void windowDeactivated(WindowEvent e) { + } + + public void windowDeiconified(WindowEvent e) { + } + + public void windowIconified(WindowEvent e) { + } + + public void windowOpened(WindowEvent e) { + } +} diff --git a/src/hayashi/yuu/register/SaveDialog.java b/src/hayashi/yuu/register/SaveDialog.java new file mode 100644 index 0000000..1bfee8f --- /dev/null +++ b/src/hayashi/yuu/register/SaveDialog.java @@ -0,0 +1,138 @@ +package hayashi.yuu.register; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.awt.BorderLayout; +import java.io.File; +import java.io.IOException; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.table.TableModel; + +import jp.co.areaweb.tools.csv.CsvFile; +import jp.co.areaweb.tools.csv.CsvRecord; + +public class SaveDialog extends JDialog implements WindowListener +{ + JLabel label1; + JButton okButton; + JLabel label2; + JFrame parent; + + public SaveDialog(JFrame parent, boolean modal) { + super(parent, modal); + addWindowListener(this); + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + this.parent = parent; + setTitle("登録データの保存"); + getContentPane().setLayout(new BorderLayout()); + setSize(360,180); + + label1 = new JLabel("登録データの設定変更を保存します。", JLabel.CENTER); + label1.setBounds(10,10,340,20); + add(label1, BorderLayout.NORTH); + + File outfile = CardRegister.taglistFile.getFile(); + label2 = new JLabel(outfile.getAbsolutePath(), JLabel.CENTER); + label2.setBounds(10,40,340,20); + add(label2, BorderLayout.CENTER); + + /* + * [OK]ボタン : このダイアログウインドウを閉じる + */ + okButton = new JButton("OK"); + okButton.setBounds(145,65,66,27); + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + // メインパネルに表示されているデータ内容をタグ定義ファイルに書き出す。 + TableModel model = CardRegister.recordTable.getModel(); + int rowCnt = model.getRowCount(); + for (int i=0; i < rowCnt; i++) { + String idStr = (String)CardRegister.recordTable.getValueAt(i, 1); + String addr = (String)CardRegister.recordTable.getValueAt(i, 2); + String name = (String)CardRegister.recordTable.getValueAt(i, 3); + CsvFile csvf = CardRegister.taglistFile.find(0, idStr); + if (csvf.isEmpty()) { + // 新規タグ + CsvRecord line = new CsvRecord(); + line.add(idStr); + line.add(addr); + line.add(name); + CardRegister.taglistFile.add(line); + } + else { + // 既存タグ + CsvRecord line = csvf.getFirst(); + if (!addr.equals(line.get(1))) { + line.set(1, addr); // アドレスの変更 + } + if (!name.equals(line.get(2))) { + line.set(2, name); // なまえの変更 + } + } + } + + try { + CardRegister.taglistFile.save(); + } + catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + // このダイアログウインドウを閉じる + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new WindowEvent(SaveDialog.this, WindowEvent.WINDOW_CLOSING)); + setVisible(false); + } + }); + JPanel southPanel = new JPanel(); + southPanel.add(okButton); + add(southPanel, BorderLayout.SOUTH); + + setVisible(true); + } + + /** + * Shows or hides the component depending on the boolean flag b. + * @param b if true, show the component; otherwise, hide the component. + * @see java.awt.Component#isVisible + */ + public void setVisible(boolean b) { + if (b) { + Rectangle bounds = getParent().getBounds(); + Rectangle abounds = getBounds(); + setLocation(bounds.x + (bounds.width - abounds.width)/ 2, + bounds.y + (bounds.height - abounds.height)/2); + } + super.setVisible(b); + } + + public void windowClosed(WindowEvent e) { + setVisible(false); + } + + public void windowActivated(WindowEvent arg0) { + } + + public void windowClosing(WindowEvent arg0) { + setVisible(false); + } + + public void windowDeactivated(WindowEvent arg0) { + } + + public void windowDeiconified(WindowEvent arg0) { + } + + public void windowIconified(WindowEvent arg0) { + } + + public void windowOpened(WindowEvent arg0) { + } +} diff --git a/src/hayashi/yuu/register/StartModePanel.java b/src/hayashi/yuu/register/StartModePanel.java new file mode 100644 index 0000000..83bed39 --- /dev/null +++ b/src/hayashi/yuu/register/StartModePanel.java @@ -0,0 +1,65 @@ +package hayashi.yuu.register; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; + +import java.awt.Font; +import java.awt.GridLayout; + +public class StartModePanel extends MainPanel +{ + /** + * コンストラクタ + * @param touchScreen 親フレーム + */ + public StartModePanel(TouchScreen touchScreen) { + super(); + this.parent = touchScreen; + setParentFrame(touchScreen); + + this.setSize(800, 300); + this.setLayout(new GridLayout(2, 1)); + img = true; + imageon = new JLabel(new ImageIcon("lib/card.gif")); + imageoff = new JLabel(); + imageLabel = imageon; + this.add(imageLabel); + text = new JLabel("IDカードをかざしてください。", JLabel.CENTER); + text.setFont(new Font("MS PGothic", Font.BOLD, 18)); + this.add(text); + } + + public void run() { + while(true) { + if (img) { + //this.remove(imageon); + imageLabel = imageoff; + //this.remove(text); + parent.repaint(); + this.setVisible(true); + img = false; + try { + Thread.sleep(300); + } catch (InterruptedException e) {} + } + else { + // this.add(imageon); + imageLabel = imageon; + //this.add(text); + parent.repaint(); + imageon.setVisible(true); + img = true; + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + } + } + } + + TouchScreen parent; + JLabel imageLabel; + JLabel imageon; + JLabel imageoff; + JLabel text; + boolean img = false; +} diff --git a/src/hayashi/yuu/register/TitlePanel.java b/src/hayashi/yuu/register/TitlePanel.java new file mode 100644 index 0000000..c1aa2e1 --- /dev/null +++ b/src/hayashi/yuu/register/TitlePanel.java @@ -0,0 +1,35 @@ +package hayashi.yuu.register; + +import java.awt.FlowLayout; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/** + * タッチパネルの上部に常時表示されるタイトルヘッダ + * + * 「proxSafe Commander3」のイメージ画像を表示する + *  filePath : ./lib/mainbanner2.jpg + * width: 800pix + * hight: 48pix + * + * @author hayashi + * + */ +public class TitlePanel extends JPanel { + static final String imagePath = "lib/mainbanner2.jpg"; + JLabel imageLabel; + JLabel terminalNameLabel; + + /** + * コンストラクタ + */ + public TitlePanel() { + super(); + this.setLayout(new FlowLayout()); + + imageLabel = new JLabel(); + imageLabel.setIcon(new ImageIcon(imagePath)); + add(imageLabel); + } +} diff --git a/src/hayashi/yuu/register/TouchScreen.java b/src/hayashi/yuu/register/TouchScreen.java new file mode 100644 index 0000000..616c40b --- /dev/null +++ b/src/hayashi/yuu/register/TouchScreen.java @@ -0,0 +1,187 @@ +package hayashi.yuu.register; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + + +/** + * 「タッチパネル画面」 + * + */ +public class TouchScreen extends JFrame implements Runnable +{ + MainPanel mainPanel; // キャビネット内のキータグ状況を表す + + /** + * コンストラクタ + * + * 画面サイズ: 800 x 600 + * + */ + public TouchScreen(String siteName) throws Exception { + super(); + this.setUndecorated(true); + + this.startModePanel = new StartModePanel(this); + + setLayout(new BorderLayout()); + this.setVisible(false); + this.setSize(800, 600); + + /* + * タイトルパネル + * 'proxSafe Commander3'のロゴイメージと、ターミナル名称 + * + * 画面サイズ: 800 x 600 + */ + TitlePanel titlePanel = new TitlePanel(); + add(BorderLayout.NORTH, titlePanel); + + /* + * メインパネル + * [ニュートラル表示]パネル + * + * 画面サイズ: 800 x ? + */ + printStartMessage(); + add(BorderLayout.CENTER, mainPanel); + + /* + * フッターパネル + * + */ + FooterPanel footerPanel = new FooterPanel(siteName); + add(BorderLayout.SOUTH, footerPanel); + setVisible(true); + + SymWindow aSymWindow = new SymWindow(); + addWindowListener(aSymWindow); + } + + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // + // Frame に関するメソッド + // + + public void init() { + setVisible(true); + //Thread threadA = new Thread(this); + //threadA.start(); + } + + public void setVisible(boolean b) { + if(b) { + // デスクトップ中央にJFrameを配置する + Dimension paneSize = this.getSize(); + Dimension screenSize = this.getToolkit().getScreenSize(); + this.setLocation((screenSize.width - paneSize.width) / 2, (screenSize.height - paneSize.height) / 2); + } + super.setVisible(b); + } + + public void addNotify() { + Dimension d = getSize(); + super.addNotify(); + 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); + } + } + + /** + * WindowClose 処理 + * @param event + */ + public void FrameClosing(WindowEvent event) { + // スレッドを停止する + setVisible(false); + dispose(); + } + + class SymWindow extends WindowAdapter + { + public void windowClosing(WindowEvent event) { + Object object = event.getSource(); + if(object == TouchScreen.this) { + FrameClosing(event); + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // + // モード に関するメソッド + // + protected StartModePanel startModePanel; + /* + protected UnregisteredModePanel unregisteredModePanel; + protected BusyModePanel busyModePanel; + */ + + /* + * スクリーン遷移モード + */ + public int screenMode = START_MODE; // 現在のスクリーンモードを保持する + static final int START_MODE = 0; // ニュートラル + static final int USER_MODE = 1; // ユーザー認証済み(キー選択) + static final int UNREGISTERED_MODE = 2; // 未登録カードモード + static final int BUSY_MODE = 3; // データ更新処理中モード + static final int KEYTAG_MODE = 4; // キータグ返却モード(AUTO_RETURN) + + + /* + * 「ニュートラル」モード + * new ImageIcon("lib/card.gif"), "IDカードをかざしてください。" + * + */ + public void printStartMessage() { + this.screenMode = TouchScreen.START_MODE; + + // 表示パネルを切り替える + if (this.mainPanel != null) { + this.remove(this.mainPanel); + } + + this.mainPanel = this.startModePanel; + this.add(BorderLayout.CENTER, mainPanel); + this.setVisible(true); + this.repaint(); + } + + + @Override + public void run() { + while (this.screenMode == TouchScreen.START_MODE) { + // 表示パネルを切り替える + if (this.mainPanel != null) { + this.remove(this.mainPanel); + this.mainPanel = null; + + this.setVisible(true); + //this.repaint(); + + try { + Thread.sleep(300); + } catch (InterruptedException e) {} + } + else { + this.mainPanel = this.startModePanel; + this.add(BorderLayout.CENTER, mainPanel); + + this.setVisible(true); + //this.repaint(); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) {} + } + } + } + +} \ No newline at end of file diff --git a/src/hayashi/yuu/register/exe16x16.png b/src/hayashi/yuu/register/exe16x16.png new file mode 100644 index 0000000..f485c84 --- /dev/null +++ b/src/hayashi/yuu/register/exe16x16.png Binary files differ diff --git a/src/hayashi/yuu/tools/DataConverter.java b/src/hayashi/yuu/tools/DataConverter.java new file mode 100644 index 0000000..a22d6dd --- /dev/null +++ b/src/hayashi/yuu/tools/DataConverter.java @@ -0,0 +1,71 @@ +package hayashi.yuu.tools; + +import java.util.ArrayList; + +public abstract class DataConverter { + /** + * ASCII文字列 + * @param data + * @return 文字列が戻る + */ + public static String toString(ArrayList byteArray) { + StringBuffer sbuf = new StringBuffer(); + for (Byte b : byteArray) { + sbuf.append(toHexString(b)); + } + return sbuf.toString(); + } + + /** + * ASCII文字列 + * @param data + * @return 文字列が戻る + */ + public static String toAsciiString(ArrayList byteArray) { + StringBuffer sbuf = new StringBuffer(); + for (Byte b : byteArray) { + sbuf.append(toChar(b)); + } + return sbuf.toString(); + } + + /** + * ASCII文字列 + * @param data + * @return 文字列が戻る + */ + public static String toAsciiString(ArrayList byteArray, int start, int leng) { + StringBuffer sbuf = new StringBuffer(); + for (int i = start; i < (start + leng); i++) { + sbuf.append(toChar(byteArray.get(i).intValue())); + } + return sbuf.toString(); + } + + /** + * 1バイト数値を16進文字列で表現する。 + * + * @param data + * @return 2文字の文字列が戻る + */ + public static String toHexString(int data) { + String hex = Integer.toHexString(data & 0x000000ff); + return (hex.length() < 2 ? "0" : "") + hex; + } + + /** + * バイト数値が表現している「ASCII文字」 + * @param data + * @return ASCII文字 + */ + public static char toChar(int data) { + for(int i = 0; i < pattern.length(); i++) { + if(pattern.charAt(i) == data) { + return pattern.charAt(i); + } + } + return '?'; + } + static StringBuffer pattern = new StringBuffer("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,/][@;:|^~+-=)('&%$#!_?*\\<>"); + +} diff --git a/src/hayashi/yuu/tools/PlaySound.java b/src/hayashi/yuu/tools/PlaySound.java new file mode 100644 index 0000000..ef5a81e --- /dev/null +++ b/src/hayashi/yuu/tools/PlaySound.java @@ -0,0 +1,96 @@ +package hayashi.yuu.tools; + +import java.io.File; +import java.io.IOException; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; + +public class PlaySound extends Thread +{ + static final String WAVE = "lib/belltree.aiff"; + //static final String WAVE = null; + + /** + * @param args + */ + public static void main(String[] args) { + try { + PlaySound obj = new PlaySound(); + for (int i=0; i < 5; i++) { + obj.start(); + try { + Thread.sleep(1000); // 1秒間停止 + } catch (InterruptedException e) {} + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private static final int EXTERNAL_BUFFER_SIZE = 128000; + private static AudioInputStream audioInputStream = null; + private static AudioFormat audioFormat = null; + + /** + * コンストラクタ + * @throws IOException + * @throws UnsupportedAudioFileException + * @throws LineUnavailableException + */ + public PlaySound() throws IOException, UnsupportedAudioFileException, LineUnavailableException { + super(); + if (PlaySound.WAVE != null) { + File soundFile = new File("lib/belltree.aiff"); + PlaySound.audioInputStream = AudioSystem.getAudioInputStream(soundFile); + PlaySound.audioFormat = PlaySound.audioInputStream.getFormat(); // オーディオ形式 + } + } + + @Override + public void run() { + if (PlaySound.WAVE == null) { + java.awt.Toolkit.getDefaultToolkit().beep(); + } + else { + try { + + // データラインの情報オブジェクトを生成 + DataLine.Info info = new DataLine.Info(SourceDataLine.class, PlaySound.audioFormat); + + // 指定されたデータライン情報に一致するラインを取得します + SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); + + // 指定されたオーディオ形式でラインを開きます + line.open(PlaySound.audioFormat); + + // ラインでのデータ入出力を可能にします + line.start(); + + int nBytesRead = 0; + byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; + while (nBytesRead != -1) { + // オーディオストリームからデータを読み込みます + nBytesRead = PlaySound.audioInputStream.read(abData, 0, abData.length); + if (nBytesRead >= 0) { + // オーディオデータをミキサーに書き込みます + line.write(abData, 0, nBytesRead); + } + } + + // ラインからキューに入っているデータを排出します + line.drain(); + line.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/hayashi/yuu/tools/SpeedMail.java b/src/hayashi/yuu/tools/SpeedMail.java new file mode 100644 index 0000000..d3e7f43 --- /dev/null +++ b/src/hayashi/yuu/tools/SpeedMail.java @@ -0,0 +1,64 @@ +package hayashi.yuu.tools; + +import hayashi.yuu.tools.mail.SendMail; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; + +import javax.mail.MessagingException; + +/** + * 標準のメール送信。 + * ただし、メール送信指示を与えるだけで、メール送信タスクは別スレッドで動作する。 + * @author hayashi + * + */ +public class SpeedMail extends SendMail implements Callable +{ + @SuppressWarnings("unchecked") + public static void main(String[] args) { + FutureTask task; + SpeedMail mail; + try { + mail = new SpeedMail("sendmail.properties"); + } + catch (Exception e1) { + e1.printStackTrace(); + return; + } + + try { + task = new FutureTask(mail); + } + catch (Exception fe) { + System.out.println(fe.toString()); + return; + } + + new Thread(task).start(); + + //---------------------------------------------------------------------- + // 送信完了を待つ + // SpeedMailを利用するなら以下の処理は要らないはず + //---------------- + try { + task.get(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + catch (ExecutionException e) { + e.printStackTrace(); + } + } + + public SpeedMail(String propFileName) throws Exception { + super(propFileName); + } + + public Object call() throws MessagingException, UnsupportedEncodingException { + send(); + return null; + } +} diff --git a/src/hayashi/yuu/tools/YuuLogFormatter.java b/src/hayashi/yuu/tools/YuuLogFormatter.java new file mode 100644 index 0000000..a30547d --- /dev/null +++ b/src/hayashi/yuu/tools/YuuLogFormatter.java @@ -0,0 +1,47 @@ +package hayashi.yuu.tools; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * シンプルなサンプルログフォーマッタ + */ +public class YuuLogFormatter extends Formatter { + private final SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + public String format(final LogRecord argLogRecord) { + final StringBuffer buf = new StringBuffer(); + + buf.append(sdFormat.format(new Date(argLogRecord.getMillis())) +" "); + + if (argLogRecord.getLevel() == Level.FINEST) { + buf.append("[FINEST]"); + } + else if (argLogRecord.getLevel() == Level.FINER) { + buf.append("[FINER]"); + } + else if (argLogRecord.getLevel() == Level.FINE) { + buf.append("[FINE]"); + } + else if (argLogRecord.getLevel() == Level.CONFIG) { + buf.append("[CONFIG]"); + } + else if (argLogRecord.getLevel() == Level.INFO) { + buf.append("[INFO]"); + } + else if (argLogRecord.getLevel() == Level.WARNING) { + buf.append("[WARN]"); + } + else if (argLogRecord.getLevel() == Level.SEVERE) { + buf.append("[SEVERE]"); + } + else { + buf.append(Integer.toString(argLogRecord.getLevel().intValue()) +" "); + } + buf.append(" "+ /* argLogRecord.getLoggerName() +" - "+ */ argLogRecord.getMessage() +"\n"); + return buf.toString(); + } +} \ No newline at end of file