SQLの窓

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 | このブログの読者になる | 更新情報をチェックする

2013年06月17日


SQL 文へのデータバインド用 public class GetSQL

やり方としてはごく一般的なものですが、プログラマ初心者の発想には無いものだと思われます。
import java.util.Iterator;
import java.util.Map;

public class GetSQL {
	
	private String target;

	public GetSQL(String target) {
		this.target = target;
	}

	public String buildSQL(Map<String,String> rdata) {
		String result = target;
		
		Iterator<String> it =  rdata.keySet().iterator();
		String key = null;
		String value = null;
		String data = null;
		while(it.hasNext()) {
			key = it.next().toString();
			data = "$" + key;
			value = rdata.get(key);
			result = result.replace(data, value);
		}		
		return result;
	}

}

▼ 以下使用方法


replace メソッドは、正規表現では無く CharSequence での処理ですが、二箇所の $insert_date が一度の実行で置き換えられています。


posted by lightbox at 2013-06-17 17:00 | 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 終わり