SQLの窓

2014年05月15日


Eclipse+WindowBuilder : データベースアプリケーション(社員マスタメンテ)の画面作成

Eclipse と WindowBuilder の機能を使ってできるだけ簡単にデータベースアプリケーションを作成します。『社員マスタメンテ』は、主キーが一つでシステム稼動の為に最初から必要な『マスターテーブル』の一つとして想定しています。本来は、『登録・修正・削除・一覧印刷』の機能を持つべきですが、ここでは一つのアプリケーションに一つの機能という事で簡潔にする為、『修正』のみに限定します。

データベースは、特別な環境を構築せずに使える MS Access( MDB ) を使用します。Java の接続を変更すれば、若干の SQL 変更で Oracle でも動作します。( 今回この記事では SQL を使用していませんが )
関連する記事

JDBC と ODBC を使った、オールマイティなデータベース接続サンプル
MDB で使用する社員マスタの CERATE 文は以下のようになります
create table [社員マスタ] (
	[社員コード] VARCHAR(4)
	,[氏名] VARCHAR(50)
	,[フリガナ] VARCHAR(50)
	,[所属] VARCHAR(4)
	,[性別] INT
	,[作成日] DATETIME
	,[更新日] DATETIME
	,[給与] INT
	,[手当] INT
	,[管理者] VARCHAR(4)
	,[生年月日] DATETIME
	,primary key([社員コード])
)

社員マスタを含んだ MDB ファイル(販売管理C.MDB)は以下からダウンロードできます


アプリケーション作成で最初に行うのは画面作成です。単純なレイアウトであれば、場合によっては、設計時に既に作成されている可能性もあります。ただ、ここではアプリケーションの基本機能として、いくつかの設定が必要になります。

その最も大きなものは『2会話処理』を前提とした、2会話目のコントロールの Disable 設定です。WindowBuilder では、Design のプロパティから設定できますが、結局はコードとなってコンストラクタで実行されます。

ですが、その前に JFrame を使った WindowBuilder のプロジェクトを作成する必要があります

WindowBuilder JFrame アプリケーションプロジェクト (1)

ワークスペースと Javaプロジェクト



何をするにも、ワークスペースと Javaプロジェクトは必要です。他からプロジェクトをインポートする場合にも、Eclipse 側でプロジェクトが必要です。


WindowBuilder JFrame アプリケーションプロジェクト (2)

JFrame クラスの作成と、JPanel の絶対レイアウト



JFrame の中に JPanel が作成され、JFrame がいわゆる Window の役目をします。JPanel は、コントロールのコンテナとして機能しますが、初期状態では『絶対レイアウト』にならないので、その設定までが基本操作になります


画面作成

以下のような画面を作成して、コードに入力した値に対応する社員のデータを更新する処理です。



コードと確認ボタンは第一会話グループで、初期状態として入力可能となります。それ以外は全て第二会話グループとなり、確認ボタンでエラーがなければ、第一会話グループを入力不可に変更して、第二会話グループの入力を可能にします。その際(第二会話グループへの移行直後)、初期フォーカスは氏名となります



第二会話グループを選択すると、共通となるプロパティが表示されるので、その中の enabled のチェックが外れた状態にします。

それ以外の調整も必要ですが、以下のソースコードをそのまま使用すると、WindowBuilder が Design に同じものを表示してくれます
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class MainWindow extends JFrame {

	private JPanel contentPane;
	private JTextField syainCode;
	private JTextField syainName;
	private JTextField syainFuri;
	private JTextField syainSyozoku;
	private JTextField syainSyozokuName;
	private JComboBox<String> syainSex;
	private JTextField syainKyuyo;
	private JTextField syainTeate;
	private JTextField syainKanri;
	private JTextField syainKanriName;
	private JTextField syainBirth;
	private JButton checkButton;
	private JButton updateButton;
	private JButton cancelButton;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainWindow frame = new MainWindow();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainWindow() {
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowOpened(WindowEvent arg0) {
				MainWindow.this.setLocationRelativeTo(null);
			}
		});
		setResizable(false);
		setTitle("\u793E\u54E1\u30DE\u30B9\u30BF\u30E1\u30F3\u30C6");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 468, 331);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		syainCode = new JTextField();
		syainCode.setBounds(98, 29, 50, 19);
		contentPane.add(syainCode);
		syainCode.setColumns(10);
		
		syainName = new JTextField();
		syainName.setEnabled(false);
		syainName.setColumns(10);
		syainName.setBounds(98, 85, 202, 19);
		contentPane.add(syainName);
		
		syainFuri = new JTextField();
		syainFuri.setEnabled(false);
		syainFuri.setColumns(10);
		syainFuri.setBounds(98, 108, 202, 19);
		contentPane.add(syainFuri);
		
		syainSyozoku = new JTextField();
		syainSyozoku.setEnabled(false);
		syainSyozoku.setColumns(10);
		syainSyozoku.setBounds(98, 131, 42, 19);
		contentPane.add(syainSyozoku);
		
		syainSyozokuName = new JTextField();
		syainSyozokuName.setEditable(false);
		syainSyozokuName.setEnabled(false);
		syainSyozokuName.setColumns(10);
		syainSyozokuName.setBounds(153, 131, 147, 19);
		contentPane.add(syainSyozokuName);
		
		syainSex = new JComboBox<String>();
		syainSex.setEnabled(false);
		syainSex.setModel(new DefaultComboBoxModel<String>(new String[] {"\u7537\u6027", "\u5973\u6027"}));
		syainSex.setBounds(98, 154, 80, 19);
		contentPane.add(syainSex);
		
		syainKyuyo = new JTextField();
		syainKyuyo.setEnabled(false);
		syainKyuyo.setColumns(10);
		syainKyuyo.setBounds(98, 177, 96, 19);
		contentPane.add(syainKyuyo);
		
		syainTeate = new JTextField();
		syainTeate.setEnabled(false);
		syainTeate.setColumns(10);
		syainTeate.setBounds(98, 200, 96, 19);
		contentPane.add(syainTeate);
		
		syainKanri = new JTextField();
		syainKanri.setEnabled(false);
		syainKanri.setColumns(10);
		syainKanri.setBounds(98, 223, 42, 19);
		contentPane.add(syainKanri);
		
		syainKanriName = new JTextField();
		syainKanriName.setEditable(false);
		syainKanriName.setEnabled(false);
		syainKanriName.setColumns(10);
		syainKanriName.setBounds(153, 223, 147, 19);
		contentPane.add(syainKanriName);
		
		syainBirth = new JTextField();
		syainBirth.setEnabled(false);
		syainBirth.setColumns(10);
		syainBirth.setBounds(98, 246, 82, 19);
		contentPane.add(syainBirth);
		
		checkButton = new JButton("\u78BA\u8A8D");
		checkButton.setBounds(333, 28, 106, 21);
		contentPane.add(checkButton);
		
		updateButton = new JButton("\u66F4\u65B0");
		updateButton.setEnabled(false);
		updateButton.setBounds(333, 209, 106, 21);
		contentPane.add(updateButton);
		
		cancelButton = new JButton("\u30AD\u30E3\u30F3\u30BB\u30EB");
		cancelButton.setEnabled(false);
		cancelButton.setBounds(333, 247, 106, 21);
		contentPane.add(cancelButton);
		
		JLabel label = new JLabel("\u30B3\u30FC\u30C9");
		label.setBounds(31, 32, 67, 13);
		contentPane.add(label);
		
		JLabel label_1 = new JLabel("\u6C0F\u540D");
		label_1.setBounds(31, 88, 67, 13);
		contentPane.add(label_1);
		
		JLabel label_2 = new JLabel("\u30D5\u30EA\u30AC\u30CA");
		label_2.setBounds(31, 111, 67, 13);
		contentPane.add(label_2);
		
		JLabel label_3 = new JLabel("\u751F\u5E74\u6708\u65E5");
		label_3.setBounds(31, 249, 67, 13);
		contentPane.add(label_3);
		
		JLabel label_4 = new JLabel("\u6240\u5C5E");
		label_4.setBounds(31, 134, 67, 13);
		contentPane.add(label_4);
		
		JLabel label_5 = new JLabel("\u6027\u5225");
		label_5.setBounds(31, 157, 67, 13);
		contentPane.add(label_5);
		
		JLabel label_6 = new JLabel("\u7D66\u4E0E");
		label_6.setBounds(31, 180, 67, 13);
		contentPane.add(label_6);
		
		Component label_7 = new JLabel("\u624B\u5F53");
		label_7.setBounds(31, 203, 67, 13);
		contentPane.add(label_7);
		
		JLabel label_8 = new JLabel("\u7BA1\u7406\u8005");
		label_8.setBounds(31, 226, 67, 13);
		contentPane.add(label_8);	
	}

}

その他の設定

■ windowOpened イベントを追加し、表示ウインドウを中央に表示する
※ public void setLocationRelativeTo(Component c)
■ JFrame のタイトル文字列を設定する。
※ public void setTitle(String title)
■ ウインドウ枠のサイズ変更をできないようにする
※ public void setResizable(boolean resizable)
■ JLabel をローカル変数として定義し、それ以外は フィールドとして定義する

▼ このアイコンで、ローカルとフィールドの切り替えができます

※ 但し、ローカルから参照されているフィールドは、ローカルには戻せません


変数名の変更と、変数の定義位置の変更



プロパティウインドウの Variable プロパティを変更すると、ソース上で使用されている変数名が自動的に全て変更されます。デフォルトでは、WindowBuilder が作成するので、後からシステムの命名規則を元に変更するといいと思います。整理の為に、変数の順序もコンポーネントウインドウでドラッグする事によって変更可能です。

クラス名の変更

パッケージエクスプローラで選択して F2 キーで変更用のウインドウが表示されます


※ 選択して、右クリックの『リファクタリング』の中にもあります

コントロールの複製

ある程度プロパティを変更したものをそのまま複製したい場合は、デザイン画面上で選択して、CTRL+C から CTRL + V を実行すると、プロパティの複製されたコントロールを貼り付ける事のできるカーソルに変化します。
( ESC で解除 )


関連する記事


posted by lightbox at 2014-05-15 23:15 | Java | このブログの読者になる | 更新情報をチェックする

2014年05月10日


Eclipse + WindowBuilder : JDBC と ODBC を使った、オールマイティなデータベース接続サンプル( MySQL / SQLServer / Oracle / Postgres / MS Access)

2014/05/10
■ 更新処理を追加
■ キャンセル処理を追加
■ MDB を同梱( 初期選択を ODBC + MS Access )
■ 変数名整備、その他ユーザインターフェイスの基本機能を装備
インポートは、Java プロジェクトを作成して、src フォルダの一つ上位のフォルダを選択します。( 最初にクリーンして、WindowBuilder でメインソースを選択して、Design タブを開きます ) 前提条件 ワークスペースのキャラクタセットが UTF-8 である事 ( Eclipse.ini に、-Dfile.encoding=utf-8 を設定すると常にワークスペースが UTF-8 になります ) キャラクタセットについて 細かい話をすると、RDBMS 単位に実装が違うので、サンプルの内容で解ると思いますが、基本的には JDBC で接続する場合は特に意識する必要無く接続できると思います。ソースを UTF-8 にしているのは、Pleiades の日本語化で、Java のドキュメントも日本語化されますが、それを正しく見るために UTF-8 である必要があるからです。 ODBC 接続は少しやっかいで、古い アプリケーションが内部コードを持たずにそのまま SHIFT_JIS で作成されている場合でも正しく接続できるように設計しているので、UTF-8 環境から実行する場合いろいろ RDBMS 毎に設定が違ったりしますが、JDBC-ODBC ブリッジ の場合、キャラクタセットのパラメータが拡張で用意されているので、たいていはそれで調整されます( ソースを見ていただくと、RDBMS 側の設定が必要な例外があるのが解ると思いますが ) JLabel2 と JButton2 について これは、コントロールのフォントをプロパティから変更するのが面倒な理由で作成したものです。WindowBuilder のパレットに単純に追加してもダメだったので実装はフォントのみです。 いろいろやっているうちに、WindowBuilder のコンポーネントとしてインポートしても存在できるようになりました。 結局、JButton2 と JLable2 の設定がプロパティの初期値として反映されています( 内容を変更した後は一旦終了しないとうまくいかないような気もします )。コンポーネントの追加は、Custom category を右クリックすると可能ですが( Add Component )、Custom category を定義する為の『org.eclipse.wb.swing.wbp-palette.xml』は、WindowBuilder の以下のツールで雛形を作成します( Swing toolkit ) これで作成すると、フォルダを作成して自動的にファイルも作成してくれます。但し、内容はあくまでサンプルなので、自分のクラスとして書き換える必要があります。そして、正しく書き換えてから、右クリックの Add Component で実際のクラスを登録します。 さらに詳細はこちらの PDF に記述されています その他 更新ボタンの内容は実装していません。アクションの切り替えを WindowBuilder からできるので、テストの為に枠組みのみ実装しています。 2014/05/10 : 更新処理を追加しました 関連する重要な記事 Eclipse + WindowBuilder : Design タブが表示されなくなった時の対処 コンポーネントのテキスト定義部分はこのソースでは日本語になっていますが、実際は 『\u793E\u54E1\u540D』というような Unicode の 16進表現になります。( ソースとして解りにくいので書き換えてあります )
// import は省略しています

public class Main extends JFrame {

	private JPanel contentPane;
	private JTextField codeData;
	private JTextField nameData;
	private JTextField txtPassword;
	private final Action actionCheck = new SwingActionCheck();
	private final Action actionUpdate = new SwingActionUpdate();
	private JComboBox<String> jdbc_odbc;
	private JComboBox<String> rdbms;
	
	private String currentDir = null;
	private JButton2 check_button;
	private JButton2 update_button;
	private JButton2 cance_button;
	private final Action actionCancel = new SwingActionCancel();

	private Connection con = null;
	private Statement stmt = null;
	private ResultSet rset = null;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Throwable e) {
			e.printStackTrace();
		}
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Main() {
		
		// Enter キーで次のフォーカスへ移動する
		KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
		Set<AWTKeyStroke> forwardKeys = new HashSet<AWTKeyStroke>(focusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
		forwardKeys.add(KeyStroke.getAWTKeyStroke(KeyEvent.VK_ENTER, 0));
		focusManager.setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
			
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowActivated(WindowEvent arg0) {
				// ウインドウを中央に
				Main.this.setLocationRelativeTo(null);
				
				// 初期コンボボックスの内容
				rdbms.setModel(new DefaultComboBoxModel<String>(new String[]
						{"MySQL", "Oracle", "SQLServer", "MS Access", "Postgres"}));
				// MS Access を選択
				rdbms.setSelectedIndex(3);
				
				// フォーカスを入力フィールドに
				codeData.requestFocusInWindow();
				
				currentDir = System.getProperty("user.dir");
				System.out.println("プロジェクトのフォルダ : " + currentDir);				
			}
		});
		setTitle("JDBC / ODBC / \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u63A5\u7D9A\u30B5\u30F3\u30D7\u30EB");
		setResizable(false);
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		codeData = new JTextField();
		codeData.addFocusListener(new FocusAdapter() {
			// フォーカスを失った時に入力内容を編集する
			@Override
			public void focusLost(FocusEvent arg0) {
				String save_string;
				String edited_string;
				try {
					edited_string = String.format("%04d", Integer.parseInt(codeData.getText()) );
					codeData.setText(edited_string);
				} catch (NumberFormatException e) {
					//e.printStackTrace();
				}
			}
		});
		codeData.setBounds(107, 71, 68, 19);
		contentPane.add(codeData);
		codeData.setColumns(10);
		
		nameData = new JTextField();
		nameData.setEnabled(false);
		nameData.setBounds(107, 124, 270, 19);
		contentPane.add(nameData);
		nameData.setColumns(10);
		
		check_button = new JButton2();
		check_button.setAction(actionCheck);
		check_button.setText("確認");
		check_button.setBounds(201, 68, 69, 27);
		contentPane.add(check_button);
		
		update_button = new JButton2();
		update_button.setAction(actionUpdate);
		update_button.setEnabled(false);
		update_button.setText("更新");
		update_button.setBounds(280, 188, 96, 27);
		contentPane.add(update_button);
		
		cance_button = new JButton2();
		cance_button.setAction(actionCancel);
		cance_button.setText("\u30AD\u30E3\u30F3\u30BB\u30EB");
		cance_button.setEnabled(false);
		cance_button.setBounds(280, 225, 96, 27);
		contentPane.add(cance_button);
		
		jdbc_odbc = new JComboBox<String>();
		jdbc_odbc.addPopupMenuListener(new PopupMenuListener() {
			public void popupMenuCanceled(PopupMenuEvent arg0) {
			}
			public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
				rdbms.setSelectedIndex(-1);
			}
			public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
			}
		});
		jdbc_odbc.setModel(new DefaultComboBoxModel<String>(new String[] {"JDBC", "ODBC"}));
		jdbc_odbc.setSelectedIndex(1);
		jdbc_odbc.setBounds(29, 27, 83, 19);
		contentPane.add(jdbc_odbc);
		
		rdbms = new JComboBox<String>();
		rdbms.addPopupMenuListener(new PopupMenuListener() {
			public void popupMenuCanceled(PopupMenuEvent arg0) {
			}
			public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
			}
			// コンボボックスを開いた時に発生するイベント
			public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
				rdbms.removeAllItems();
				if (jdbc_odbc.getSelectedItem().equals("JDBC")){
					// JDBC では、MS Access は存在しない
					rdbms.setModel(new DefaultComboBoxModel<String>(new String[]
							{"MySQL", "Oracle", "SQLServer",  "Postgres"}));
				}
				if (jdbc_odbc.getSelectedItem().equals("ODBC")){
					rdbms.setModel(new DefaultComboBoxModel<String>(new String[]
							{"MySQL", "Oracle", "SQLServer", "MS Access", "Postgres"}));
				}
			}
		});
		rdbms.setBounds(124, 27, 110, 19);
		contentPane.add(rdbms);
		{
			txtPassword = new JTextField();
			txtPassword.setText("password");
			txtPassword.setBounds(336, 27, 96, 19);
			contentPane.add(txtPassword);
			txtPassword.setColumns(10);
		}
		
		JLabel2 label2_0 = new JLabel2();
		label2_0.setText("パスワード");
		label2_0.setBounds(265, 28, 68, 19);
		contentPane.add(label2_0);
		
		JLabel2 label2_1 = new JLabel2();
		label2_1.setText("コード");
		label2_1.setBounds(29, 72, 52, 19);
		contentPane.add(label2_1);
		
		JLabel2 label2_2 = new JLabel2();
		label2_2.setText("社員名");
		label2_2.setBounds(29, 125, 52, 19);
		contentPane.add(label2_2);
	}

	// 会話用 ボタンアクション 1
	private class SwingActionCheck extends AbstractAction {
		public SwingActionCheck() {
			putValue(NAME, "確認");
			putValue(SHORT_DESCRIPTION, "社員コードを入力して下さい");
		}

		public void actionPerformed(ActionEvent e) {
		
			getConnect();
			
			try {
				
				stmt = con.createStatement();
				String scode = codeData.getText();
				rset = stmt.executeQuery ( "select * from 社員マスタ where 社員コード = '" + scode + "'" );
				if ( rset.next() ) {
					nameData.setText(rset.getString( "氏名" ));
					
					update_button.setEnabled(true);
					nameData.setEnabled(true);
					cance_button.setEnabled(true);
					
					check_button.setEnabled(false);
					codeData.setEnabled(false);
					jdbc_odbc.setEnabled(false);
					rdbms.setEnabled(false);
					txtPassword.setEnabled(false);
					
					nameData.requestFocusInWindow();
					nameData.selectAll();
					
				}
				else {
					JOptionPane.showMessageDialog(contentPane, "入力した社員コードは存在しません");
					codeData.requestFocusInWindow();
					codeData.selectAll();
				}
				
				rset.close();
				stmt.close();
				con.close();
				
			} catch (Exception e1) {
				// TODO 
				e1.printStackTrace();
			}
			
		}

	}
	
	private boolean getConnect() {
		
		boolean connect_result = true;
		
		String pass = txtPassword.getText();
		
		// TODO 自動生成されたメソッド・スタブ
		// JDBC か ODBC か
		String targetDbc = (String)jdbc_odbc.getSelectedItem();
		String targetRdbms = (String)rdbms.getSelectedItem();

		
		String connectionString = "";

		// *********************************************
		// ODBC 用接続文字列
		// *********************************************

		if (targetDbc.equals("ODBC")) {
			if (targetRdbms.equals("SQLServer")) {
				// SQLServer
				connectionString = "Provider=MSDASQL"
						+ ";Driver={SQL Server Native Client 11.0}"
						+ ";SERVER=.\\sqlexpress" + ";DATABASE=lightbox"
						+ ";UID=sa" + ";PWD=" + pass + ";";
			}
			if (targetRdbms.equals("MySQL")) {
				// MySQL
				connectionString = "Provider=MSDASQL"
						+ ";Driver={MySQL ODBC 5.3 Unicode Driver}"
						+ ";SERVER=localhost" + ";DATABASE=lightbox"
						+ ";UID=root" + ";PWD=" + pass + ";Charset=cp932";
			}
			if (targetRdbms.equals("MS Access")) {
				// MDB
				connectionString = "Provider=MSDASQL"
						+ ";Driver={Microsoft Access Driver (*.mdb)}"
						+ ";Dbq=" + currentDir + "\\data\\販売管理C.mdb" + ";";
			}
			if (targetRdbms.equals("Oracle")) {
				// Oracle
				connectionString = "Provider=MSDASQL"
						+ ";Driver={Oracle in XE}" + ";DBQ=localhost:1521/XE"
						+ ";UID=lightbox" + ";PWD=" + pass + ";";
			}
			if (targetRdbms.equals("Postgres")) {
				// PostgreSQL
				connectionString = "Provider=MSDASQL"
						+ ";Driver={PostgreSQL ODBC Driver(UNICODE)}"
						+ ";Servername=localhost" + ";Port=5432"
						+ ";Database=lightbox" + ";UID=postgres"
						+ ";PWD=" + pass + ";";
			}
		}
		
		try {
			if (targetDbc.equals("ODBC")) {
				Properties prop = new Properties();
				prop.put("charSet", "MS932");
				System.out.println(connectionString);
				con = DriverManager.getConnection("jdbc:odbc:"+connectionString, prop);
			}
			else {

				// *********************************************
				// JDBC 用接続文字列
				// *********************************************
				
				if (targetRdbms.equals("MySQL")) {
					// MySQL
					// mysql-connector-java-5.1.30-bin.jar
					con = DriverManager.getConnection("jdbc:mysql://localhost/lightbox?" +
						"user=root&password="+pass);
				}

				if (targetRdbms.equals("Oracle")) {
					// Oracle
					// ojdbc6.jar
					con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/xe","lightbox",pass);
				}
				
				if (targetRdbms.equals("SQLServer")) {
					// SQLServer
					// sqljdbc4.jar
					String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
						"databaseName=lightbox;user=sa;password="+pass+";";
					con = DriverManager.getConnection(connectionUrl);
				}

				if (targetRdbms.equals("PostgreSQL")) {
					// PostgreSQL
					// postgresql-9.3-1100.jdbc4.jar
					String connectionUrl = "jdbc:postgresql://localhost:5432/lightbox" +
	 					"?user=postgres&password="+pass+"&charSet=utf-8;";
					con = DriverManager.getConnection(connectionUrl);
				}
				
			}
			
		} catch (Exception e1) {
			// TODO 
			e1.printStackTrace();
			connect_result = false;
		}
		
		return false;
	}
	
	// 会話用 ボタンアクション 2
	private class SwingActionUpdate extends AbstractAction {
		public SwingActionUpdate() {
			putValue(NAME, "更新");
			putValue(SHORT_DESCRIPTION, "Some short description");
		}
		public void actionPerformed(ActionEvent e) {
			
			int result = JOptionPane.showConfirmDialog(contentPane, "更新してよろしいですか?", "更新確認", JOptionPane.OK_CANCEL_OPTION);
			if ( result == JOptionPane.CANCEL_OPTION) {
				return;
			}

			getConnect();
			
			try {
				
				stmt = con.createStatement();
				String scode = codeData.getText();
				String sname = nameData.getText();
				String sql = "update 社員マスタ set 氏名 = '" + sname + "' where 社員コード = '" + scode + "'";
				result = stmt.executeUpdate(sql);
				
				actionCancel.actionPerformed(null);
				
				stmt.close();
				con.close();
				
				JOptionPane.showMessageDialog(contentPane, "更新処理が実行されました");
				
				
			} catch (Exception e1) {
				// TODO 
				e1.printStackTrace();
			}
			
			
		}
	}
	private class SwingActionCancel extends AbstractAction {
		public SwingActionCancel() {
			putValue(NAME, "キャンセル");
			putValue(SHORT_DESCRIPTION, "Some short description");
		}
		public void actionPerformed(ActionEvent e) {
			
			update_button.setEnabled(false);
			nameData.setEnabled(false);
			cance_button.setEnabled(false);
			
			check_button.setEnabled(true);
			codeData.setEnabled(true);
			jdbc_odbc.setEnabled(true);
			rdbms.setEnabled(true);
			txtPassword.setEnabled(true);
			
			nameData.setText("");
			
			codeData.requestFocusInWindow();
			codeData.selectAll();
			
		}
	}
}



関連する記事


posted by lightbox at 2014-05-10 22:37 | Java | このブログの読者になる | 更新情報をチェックする

2014年05月05日


Eclipse + WindowBuilder : Design タブが表示されなくなった時の対処

原因は解りませんが、Eclipse がソースを標準のエディタで開いてしまっている事が原因なので、専用の WindowBuilder エディタで開き直すことで元に戻ります。同時に二つのエディタを使え無いので、いったん標準のエディタで開いたタブを閉じて、以下の位置より開きなおして下さい。



これについては、Eclipse の英文の FAQ で記述があります。

WindowBuilder Pro FAQ

上記リンク先に、メニューがあるので『What can I do if I don't see the Design tab when I edit a window?』をクリックします

Eclipse remembers the last editor type used with a file. If you don't see the Design tab, that means that you are using the standard Eclipse Java Editor rather than the WindowBuilder Editor. Open the file with the WindowBuilder Editor and you will see both the Source and Design tabs. Note that Eclipse will only let you have a file open with one editor at a time, so you may need to close any existing editor before opening it with the WindowBuilder Editor.
関連する記事


posted by lightbox at 2014-05-05 00:40 | Java | このブログの読者になる | 更新情報をチェックする

2014年04月29日


Eclipse のパンくずリスト(breadcrumb) をワークスペースの設定ファイルで非表示にする



Eclipse で『CTRL+SHIFT+L』でショートカットキーの一覧が表示されますが、その中に『パンくずリスト』と言う項目があります。



この項目は、『ナビゲート』メニューにもありますが、表示した後元に戻す項目がありません。インターネットで調べると、ツールバーに削除する項目がある( あった? ) という旨の記事を見つける事ができるのですが、自分の環境でそのようなアイコンを確認できていません。( ADT Build: v22.2.1-833290 )



ですが、Eclipse ではワークスペース単位で設定ファイルが書き込まれているのでそこを修正して非表示に変更できます。

▼ 場所
ワークスペースフォルダ\.metadata\.plugins\org.eclipse.core.runtime\.settings
▼ ファイル
org.eclipse.jdt.ui.prefs
▼ 内容( エントリ )
breadcrumb.org.eclipse.jdt.ui.JavaPerspective=true

この内容を false にしてやると表示しなくなります



関連する記事


posted by lightbox at 2014-04-29 14:04 | Java | このブログの読者になる | 更新情報をチェックする

2013年09月25日


Java : Eclipse 実行の System.in.read(buff) でコンソール入力



Eclipse のコンソールで入力し、その内容で処理を行うと楽に処理のテストが可能です。画像の水色の部分が入力部分ですが、Enter で、改行コードを含めて入力されます( Windows で \r\n を確認しました )

通常のコマンドプロンプトとの違いは、Enter 後、カーソルが次の入力部分に移動しないところです。ですから、CTRL + END で自分で移動する必要があります。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;

import com.google.gson.Gson;

public class HttpAndGet {

	public static void main(String[] args) {

		// コマンドを入力する為の 128 バイトのバッファ
		byte[] line = new byte[128];
		// コマンド部分を抽出する文字列
		String command = "";
		int i_len = 0;
		// 終了コマンド
		while( !(command.toUpperCase().equals("Q")) ) {
			
			try {
				// プロンプト出力
				System.out.print("java>");
				// 入力( 改行付きで入力 )
				i_len = System.in.read(line);
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			try {
				// 入力内容を文字列に変換して、入力文を取り出す
				command = (new String(line, "SJIS")).substring(0, i_len);
				// コマンドのみに変換
				command = command.trim();
				
			} catch (UnsupportedEncodingException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
			
			// コマンド処理( 大文字小文字を区別しない )
			if ( command.toUpperCase().equals("HTTPGET") ) {
				HttpGet();
			}
			// MS932 で判断
			if ( command.equals("強制終了") ) {
				System.out.print("強制終了します");
				System.exit(0);
			}
			
		}
		
		System.out.print("プログラムを終了しました");
		
	}

	// ******************************************************************
	// JSON を インターネットから取得する
	// ******************************************************************
	public static void HttpGet() {
		
		System.out.println("HttpGet を実行中です");
		
		String json_string = "";
		
		try {
			// JSON の URL
			URL url = new URL("http://toolbox.winofsql.jp/json/sample2.json");
			// 接続オブジェクト
			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			http.setRequestMethod("GET");
			// 接続 
			http.connect();
			
			// http から InputStream を取得する
			InputStream i_stream = http.getInputStream();
			
			// InputStream から リーダを作成する( キャラクタセットを指定 )
			// UTF-8 でリーダーを作成( インターネット上のデータが UTF-8 なので )
			InputStreamReader i_stream_reader = new InputStreamReader(i_stream, "UTF-8");
			
			// リーダを行単位で読み込める BufferedReader を使って全ての文字列を取得する )
			BufferedReader buffer_reader = new BufferedReader(i_stream_reader);
			json_string = new TextReader().getText(buffer_reader); 
			
			// 全て閉じる
			buffer_reader.close();
			i_stream_reader.close();
			i_stream.close();
			http.disconnect();
			
		}
		catch( Exception e ) {
			e.printStackTrace();
			json_string = "{ \"winofsql\" : [\"error\"] }";
		}
		
		// Gson を作成
		Gson gson = new Gson();
		
		// 全体の文字列を JSON_ENTRY クラスに投入
		// ( 未定義のものは無視されます )
		JSON_ENTRY je = gson.fromJson(json_string,JSON_ENTRY.class);

		// 一覧表示
		for( int i = 0; i < je.winofsql.length; i++ ) {
			System.out.println(je.winofsql[i]);
		}
		
	}

	// ******************************************************************
	// BufferedReader から テキストを取得
	// ******************************************************************
	static class TextReader {
		public String getText(BufferedReader br) throws IOException {

			String result_string = "";
			String line_buffer = null;   
			// BufferedReader は、readLine が null を返すと読み込み終了   
			while ( null != (line_buffer = br.readLine() ) ) {   
				result_string += line_buffer;
			}
			
			return result_string;
		
		}
	}
	
	static class JSON_ENTRY {
		String[] winofsql;
	}

}

▲ このテストは、JSON の入力と Gson を使った デシリアライズです。

▲ のコードでは、バイナリで読み込んで、new String( buff ) で文字列変換していましたが、以下のコードでは、BufferedReader を使って readLine しています。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;


public class NioGet {

	public static void main(String[] args) {
		// コマンドを入力する為の 128 バイトのバッファ
		byte[] line = new byte[128];
		// コマンド部分を抽出する文字列
		String command = "";
		int i_len = 0;
		// 終了コマンドは "q"
		while( !command.equals("q") ) {
			
			try {
				// プロンプト出力
				System.out.print("java>");
				// 入力
				command = (new BufferedReader( new InputStreamReader(System.in, "SJIS") )).readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			// コマンド処理( 大文字小文字を区別しない )
			if ( command.toUpperCase().equals("GET") ) {
				JsonGetFromFile();
			}
		}
		
		System.out.print("プログラムを終了しました");

	}
	
	public static void JsonGetFromFile() {
		
		FileSystem fs = FileSystems.getDefault();
		byte[] file_dataFiles = null;
		
		Path target = fs.getPath("C:\\user\\lightbox\\java2\\JSON\\sample1\\JsonGet2\\file\\json.txt");
		try {
			file_dataFiles = Files.readAllBytes(target);
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		
		String string_file_data = new String(file_dataFiles);
		System.out.println(string_file_data);
		
		print_json(string_file_data);
		
		// Gson を作成
		Gson gson = new Gson();
		
		// 全体の文字列を JSON_ENTRY クラスに投入
		// ( 未定義のものは無視されます )
		JSON_ENTRY je = gson.fromJson(string_file_data,JSON_ENTRY.class);
		// 固定フォーマットであればこの方法が確実
		System.out.println(je.id);
		System.out.println(je.description);
		System.out.println(je.status.text);
		// 存在する場合のみ出力
		if ( je.status.abc != null ) {
			System.out.println(je.status.abc);
		}
	}

	// デシリアライズ用のクラス
	static class JSON_ENTRY {
		String id;
		String description;
		JSON_STATUS status;
	}
	static class JSON_STATUS {
		String text;
		String abc;
	}
	
	
	public static void print_json( String json_string ) {
		
		// パーサーを取得
		JsonParser jp = new JsonParser();
		// 文字列をパース
		JsonElement je = jp.parse(json_string);

		// key と value を取得する為に、JsonObject から、entrySet メソッドを実行
		Set<Map.Entry<String, JsonElement>> entrySet = je.getAsJsonObject().entrySet();

		// イテレータを取得
		Iterator<Map.Entry<String, JsonElement>> it = entrySet.iterator();

		// 一覧表示
		while(it.hasNext())
		{
			Map.Entry<String, JsonElement> entry = it.next();

			String key = entry.getKey();
			JsonElement value = entry.getValue();

			System.out.print(key+" : ");
			if ( value.isJsonObject() ) {
				System.out.println("【OBJ】-->" );
				
				print_json( value.toString() );
			}
			else {
				if ( value.isJsonNull() ) {
					System.out.println("NULL");
				}
				else {
					if ( value.isJsonArray() ) {
						JsonArray ja = (JsonArray)value;
						System.out.println("【ARRAY】-->" );
						print_json_array(ja);
					}
					else {
						System.out.println(value.getAsString());
					}
				}
			}
		}

	}
	
	public static void print_json_array( JsonArray ja ) {
		
		for( int i = 0; i < ja.size(); i++ ) {
			if ( ja.get(i).isJsonObject() ) {
				print_json( ja.get(i).toString() );
			}
			if ( ja.get(i).isJsonNull() ) {
				System.out.println("NULL");
			}
			if ( ja.get(i).isJsonArray() ) {
				print_json_array( (JsonArray)ja.get(i) );
			}
			if ( ja.get(i).isJsonPrimitive() ) {
				System.out.println(ja.get(i).getAsString());
			}
		}
		
	}


}

このテストは、System.nio を使った、ファイルの一括読み込みと、Gson を使った JSON の一覧処理です


posted by lightbox at 2013-09-25 20:32 | Java | このブログの読者になる | 更新情報をチェックする

2013年09月03日


iText( itextpdf-5.4.3 / Java ) で簡単に PDF 出力をする。

作成した PDF へのリンク


ビルド用バッチファイル
prompt java$G
setlocal
set PATH=C:\Program Files\Java\jdk1.6.0_24\bin;%PATH%
set CLASSPATH=.;itextpdf-5.4.3.jar

javac Main.java

endlocal
実行用バッチファイル
prompt java$G
setlocal
set PATH=C:\Program Files\Java\jdk1.6.0_24\bin;%PATH%
set CLASSPATH=.;itextpdf-5.4.3.jar

REM 実行
java Main

endlocal
iText ダウンロード iText メインページ iText ドキュメント iText サンプルページ ダウンロードした itextpdf-5.4.3.jar は、テストコードと同じディレクトリに置いて、JDK のインストール先(ここでは C:\Program Files\Java\jdk1.6.0_24)を書き換えてビルドすれば、実行後 pdftest.pdf が作成されます。
// http://api.itextpdf.com/itext/index.html?com/itextpdf/text/pdf/ColumnText.html
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.*;

import java.io.FileOutputStream;

public class Main {

	// *****************************************************
	// エントリポイント
	// *****************************************************
	public static void main(String[] args) {
		Main thisClass = new Main();
	}

	// *****************************************************
	// コンストラクタ
	// *****************************************************
	public Main() {
		super();
		my_acton();
	}

	// *****************************************************
	// 初期処理
	// *****************************************************
	private void my_acton() {

		System.out.println("処理開始");


		String pdf = "pdftest.pdf";

		Document doc = new Document(); 

		try {
			// 出力先を指定し、文書をPDFとして出力
			PdfWriter pw = PdfWriter.getInstance(doc, new FileOutputStream(pdf));
			// 出力開始
			doc.open();

			// 日本語フォントの設定

			// メイリオ
			Font font = new Font(
				BaseFont.createFont(
					"C:\\WINDOWS\\Fonts\\meiryo.ttc,0",
					BaseFont.IDENTITY_H,
					BaseFont.EMBEDDED));

			// メイリオボールド
			Font font2 = new Font(
				BaseFont.createFont(
					"C:\\WINDOWS\\Fonts\\meiryob.ttc,0",
					BaseFont.IDENTITY_H,
					BaseFont.EMBEDDED));


			// *****************************************************************
			// 座標指定する為のオブジェクト
			// *****************************************************************
			// 一番上のレイヤー
			PdfContentByte pcb = pw.getDirectContent();

			// 一番上のレイヤーに直線を引く
			pcb.moveTo( 0, 820 );
			pcb.lineTo( 595, 820 );
			pcb.stroke();

			ColumnText ct = new ColumnText(pcb);

			Phrase myText = null;
			String line_text = null;

			int x1 = 400;
			int x2 = 595;

			line_text = "1234567890123456789012345678901234567890";

			myText = new Phrase(line_text,font);
			ct.setSimpleColumn(
				myText,
				x1,0,		// 書き込み対象の左下の座標
				x2, 810,	// 書き込み対象の右上の座標
				20,			// 行間
				Element.ALIGN_LEFT
			);
			ct.go();

			line_text = "ニ行目";

			myText = new Phrase(line_text,font);
			ct.setSimpleColumn(
				myText,
				x1,0,
				x2, 750,
				0,
				Element.ALIGN_LEFT
			);
			ct.go();

			line_text = "三行目";

			myText = new Phrase(line_text,font);
			ct.setSimpleColumn(
				myText,
				x1,0,
				x2, 735,
				0,
				Element.ALIGN_LEFT
			);
			ct.go();

			line_text = "四行目";

			// *****************************************************************
			// 右寄せ
			// *****************************************************************
			int right_offset = 50;
			myText = new Phrase(line_text,font);
			ct.setSimpleColumn(
				myText,
				x1,0,
				x2-right_offset, 720,
				0,
				Element.ALIGN_LEFT
			);
			ct.go();

			int top = 700;
			myText = new Phrase("left:"+doc.getPageSize().getLeft(),font2);
			ct.setSimpleColumn(
				myText,
				x1, 0,
				x2-right_offset, top,
				0,
				Element.ALIGN_RIGHT
			);
			ct.go();

			top -= 10;
			myText = new Phrase("right:"+doc.getPageSize().getRight(),font2);
			ct.setSimpleColumn(
				myText,
				x1, 0,
				x2-right_offset, top,
				0,
				Element.ALIGN_RIGHT
			);
			ct.go();

			top -= 10;
			myText = new Phrase("top:"+doc.getPageSize().getTop(),font2);
			ct.setSimpleColumn(
				myText,
				x1,0,
				x2-right_offset, top,
				0,
				Element.ALIGN_RIGHT
			);
			ct.go();

			top -= 10;
			myText = new Phrase("bottom:"+doc.getPageSize().getBottom(),font2);
			ct.setSimpleColumn(
				myText,
				x1,0,
				x2-right_offset, top,
				0,
				Element.ALIGN_RIGHT
			);
			ct.go();

			// *****************************************************************
			// 真ん中のレイヤー( 通常の文字列や画像・グラフィックの追加 )
			// *****************************************************************

			Image img = Image.getInstance("_img.jpg");
			img.setAbsolutePosition(140, 620);
			img.scalePercent(50);
			doc.add(img);

			doc.add( new Paragraph(" ", font) );	// 改行
			doc.add( new Paragraph(" ", font) );
			doc.add( new Paragraph(" ", font) );
			doc.add( new Paragraph(" ", font) );
			doc.add( new Paragraph(" ", font) );

			doc.add( new Paragraph("文を 一行出力", font) );
			doc.add( new Paragraph("文を 一行出力", font) );
			doc.add( new Paragraph("文を 一行出力", font) );
			doc.add( new Paragraph("文を 一行出力", font) );
			doc.add( new Paragraph("文を 一行出力", font) );

			doc.add( new Paragraph(" ", font) );

			Paragraph p = new Paragraph();
			for (int i = 0; i < 25; i++) {
				p.add(
					new Chunk(
						"日本語表示の一般テキストを繰り返し表示しています。"
						,font
					)
				);
			}
			doc.add(p);

			// 出力終了
			doc.close();

		}
		catch (Exception e) {
			e.printStackTrace();
		}


		System.out.println("処理終了");

	}

}

メイリオについて

meiryo.ttc,0 を meiryo.ttc,1 にすればメイリオイタリックになります。(ボールドのほうも同様です)

レイヤーについて

レイヤーはもう一枚、一番下にありますが通常の文書では必要無いと思います。

setSimpleColumn について

矩形を指定しますが、開始が左下隅で、終了が右上隅になります。6番目の引数は行間を示し、矩形からあふれるばあいに使用される行間です。

ページのサイズ について

真ん中のレイヤーである、Document に対して以下のメソッドを実行して取得しています
getPageSize().getLeft()
getPageSize().getRight()
getPageSize().getTop()
getPageSize().getBottom()

Document 内の改行について

doc.add( new Paragraph(" ", font) ); で改行します( スペースを出力します )

一般的な出力について

単純なテキスト印刷の場合であれば、Document のみで問題無いと思いますが、文書としてのフォーマットを固定部分として定義して、中身にテキストを出力するように場合、getDirectContent を使って取得した PdfContentByte を使って出力すると良いと思います。もう一枚のレイヤーは、さらに背景にバリエーションを与える必要がある場合に使用するといいと思います。( getDirectContentUnder() で取得します )


posted by lightbox at 2013-09-03 15:50 | Java | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり