SQLの窓

2016年05月07日


WindowBuilder テンプレートのテーブルコントロールに MySQL のデータを表示する

▼ テンプレートはこちらから
Eclipse 4.4 Pleiades + WindowBuilder テンプレート / アプリケーションウインドウとダイアログ



テンプレートにはあらかじめ Table コントロールを配置しています。元々のコードは上のリンク先を参照して下さい。こちらでは、追加として MySQL の mysql-connector-java-5.1.30-bin.jar をプロジェクト内に lib フォルダを作成してコピーしています。
※ ファイルシステムからコピーして、プロジェクトツリーからリフレッシュすると表示されます

その後、mysql-connector-java-5.1.30-bin.jar を右クリックして『ビルド・パス』を開くと追加のメニューが現れるので実行すると使えるようになります。

SQL をテキストファイルから読み込む static メソッド

TopWindow の中に追加して使います
	static String loadText(String name) throws Exception {

		FileInputStream fis = new FileInputStream(name);
		int size = fis.available();
		InputStreamReader isr = new InputStreamReader(fis);
		BufferedReader br = new BufferedReader(isr);
		StringBuffer all_string = new StringBuffer(size);
		String str = null;
		while ((str = br.readLine()) != null) {
			// 初回以外は前に改行を挿入する
			if (!all_string.toString().equals("")) {
				all_string.append("\n");
			}
			all_string.append(str);
		}
		br.close();

		return all_string.toString();

	}	
後は、Dialog1 の初期表示で MySQL からデータを読み込みます

Dialog1.java
import java.awt.GraphicsEnvironment;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;


public class Dialog1 extends Dialog {

	private int width = 800;
	private int height = 600;
	private Table table;
	private Connection con;
	private Statement stmt;
	private ResultSet rset;
	// *********************************
	// コンストラクタ
	// *********************************
	public Dialog1(Shell parentShell) {
		super(parentShell);
	}

	// *********************************
	// コントロールの追加
	// ※ Design での変更が反映されます
	// *********************************
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);

		// テーブルの作成
		table = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		// 列の作成
		TableColumn tableColumn = new TableColumn(table, SWT.NONE);
		tableColumn.setWidth(100);
		tableColumn.setText("名前");

		TableColumn tableColumn_1 = new TableColumn(table, SWT.NONE);
		tableColumn_1.setWidth(131);
		tableColumn_1.setText("詳細");
		String connectionString = "jdbc:mysql://localhost/lightbox?" +
				"user=root&password=パスワード";

		TableItem tableItem;
		String[] columnData = new String[2];
		try {
			con = DriverManager.getConnection(connectionString);
			stmt = con.createStatement();

			rset = stmt.executeQuery ( TopWindow.loadText("data/sql1.txt") );

			ResultSetMetaData rm = rset.getMetaData();
			int nCols = rm.getColumnCount();
			String[] data = new String[nCols];
			int i;

			while( rset.next() ) {
				for( i = 0; i < nCols; i++ ) {
					data[i] = rset.getString( i+1 );

					if ( i != 0 ) {
						System.out.print( "," );
					}
					System.out.print( data[i] );
				}
				System.out.println(  );
				
				columnData[0] = rset.getString("氏名");
				if ( rset.getString("管理者名") == null ) {
					columnData[1] = "管理者";
				}
				else {
					columnData[1] = String.format("%s の部下", rset.getString("管理者名") );
				}
				tableItem = new TableItem(table, SWT.NONE);
				tableItem.setText(columnData);
				
			}

			stmt.close();
			con.close();

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

		// 行の作成
//		TableItem tableItem = new TableItem(table, SWT.NONE);
//		data = new String[]{"山田","主任"};
//		tableItem.setText(data);
//
//		TableItem tableItem_1 = new TableItem(table, SWT.NONE);
//		data = new String[]{"鈴木","プロジェクトリーダ"};
//		tableItem_1.setText(data);


		return container;
	}

	
	// *********************************
	// ダイアログ専用のボタン
	// *********************************
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
				true);
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}

	// *********************************
	// Window サイズの初期設定
	// *********************************
	@Override
	protected Point getInitialSize() {
		// プライベート変数を使用してウインドウサイズを決定しています
		return new Point(width, height);
	}

	// *********************************
	// Window の初期位置
	// ※ デスクトップの中心
	// *********************************
	@Override
	protected Point getInitialLocation(Point initialSize) {

		GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();

		// デスクトップのサイズ
		Point windowSize = new Point(
				env.getMaximumWindowBounds().width,
				env.getMaximumWindowBounds().height);
		Point position = new Point(0,0);

		// デスクトップの中心に表示します
		return new Point(
			position.x + ((windowSize.x - width) / 2),
			position.y + ((windowSize.y - height) / 2)
		);

		/*	 親ウインドウの中心の場合 */
//		Point windowSize = this.getShell().getParent().getSize();
//		Point position = this.getShell().getParent().getLocation();
//
//		System.out.println(windowSize.x);
//
//		return new Point(
//			position.x + ((windowSize.x - width) / 2),
//			position.y + ((windowSize.y - height) / 2)
//		);

	}

}


▼ 外部ファイルの SQL 
select a.*, b.氏名 as 管理者名 from 社員マスタ a
left outer join 社員マスタ b
on a.管理者 = b.社員コード
▼ テーブルの create 文
create table `社員マスタ` (
	`社員コード` VARCHAR(4)
	,`氏名` VARCHAR(50)
	,`フリガナ` VARCHAR(50)
	,`所属` VARCHAR(4)
	,`性別` INT
	,`作成日` DATETIME
	,`更新日` DATETIME
	,`給与` INT
	,`手当` INT
	,`管理者` varchar(4)
	,`生年月日` DATETIME
	,primary key(`社員コード`)
)
関連する記事 MySQL 5.6 : テストデータ自動作成スクリプト
posted by lightbox at 2016-05-07 23:41 | java : WindowBuilder | このブログの読者になる | 更新情報をチェックする

Eclipse 4.4 Pleiades + WindowBuilder テンプレート / アプリケーションウインドウとダイアログ / インポート手順





Eclipse 4.4 Pleiades はベクターからダウンロードして解凍すればすぐに使えます。
※ 4.5 は動作しないので、4.4を使用します

プロジェクトを一から作る方法はこちらから参照できますが、とても面倒ですし展開されるテンプレートが英語コメントなのでこちらのテンプレート(コメントを日本語で入力しました)でサクっと作ってしまいます。

インポート

インポートは、『既存プロジェクトをワークスペースへ』を選択して下さい。



その後、アーカイブファイルの選択をするだけです



但し、このままでは WindowBulder エディタでソースが開かれないので、右クリックの『次で開く』から『WindowBuilder エディタ』を選択します



Window 配置について

初期配置に違和感を感じる場合は、新たにパースペクティブから 『Java』を選びます。

 

そして、『タスクリスト』と『アウトライン』は閉じるといいでしょう(復活は、ウインドウメニューの『ビューの表示』)



フォントの変更

Java のエディタと通常のテキストエディタとコンソールのフォントを変更します。

ウインドウの『設定』で設定ウインドウを開いて、左上のフィルター入力に『フォント』と入力します。

▼ Java

フォントがすぐ変更されない場合は、いったんソースタブを閉じてもう一度開きます

▼ デバッグ


▼ 基本


TopWindow.java

ウインドウアプリケーションでは、ブラウザコントロールに WEB ページを表示しています。デフォルトでは、URL を使用してページを表示しますが、getType 変数の中身を変更すると、HttpGet クラスを使用して、HTML データを取得してブラウザに表示します。

ダイアログボタンをクリックすると、ダイアログを開いてテーブルコントロールにデータを表示します。また、タイトルの設定や、アイコンの設定を configureShell で行っています。
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


public class TopWindow extends ApplicationWindow {

	private String getType = "browser";
	// Run Code の PHP サンプルの URL
	private String url = "http://rextester.com/CPAFA49735";
	private int width = 800;
	private int height = 980;
	private Browser browser;

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

	// *********************************
	// コントロールの追加
	// ※ Design での変更が反映されます
	// *********************************
	@Override
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);

		// ▼ Design にから作成された記述
		Button button = new Button(container, SWT.NONE);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				// ▼ ボタンが押された時の処理( 後からコードを追加 )
				System.out.println("ボタンがクリックされました");

				// プライベート変数の getType の内容で処理を変えるようにしています
				if ( getType.equals("browser") ) {
					browser.setUrl(url);
					System.out.println("Browser に url をセットして表示しました");
				}
				else {
					// インターネットからデータを取り出しています
					String s = HttpGet.execute(url, "utf-8");
					browser.setText(s);
					System.out.println("Browser に HTML をセットして表示しました");
				}
			}
		});
		button.setBounds(10, 10, 81, 28);
		button.setText("ブラウザ表示");

		browser = new Browser(container, SWT.NONE);
		browser.setBounds(10, 44, 750, 850);

		Button button_1 = new Button(container, SWT.NONE);
		button_1.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				// ダイアログを表示します
				Dialog1 dialog = new Dialog1(getShell());
				int result = dialog.open();
				System.out.println(result);
			}
		});
		button_1.setBounds(117, 10, 81, 28);
		button_1.setText("ダイアログ");

		return container;
	}

	// *********************************
	// アプリケーションの開始
	// *********************************
	public static void main(String args[]) {
		try {
			// 自分自身(TopWindow) の作成
			TopWindow window = new TopWindow();
			// open を実行したら、Window を閉じるまで次の行を実行しない
			window.setBlockOnOpen(true);
			window.open();
			// Window を閉じたら以下を実行してアプリケーションを終了する
			Display.getCurrent().dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// *********************************
	// Window の初期設定
	// *********************************
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);

		// タイトルの設定
		newShell.setText("タイトル文字列");

		// アイコンの設定
		ImageData id = new ImageData("image/lightbox.png");
		Image img = new Image(newShell.getDisplay(), id);
		newShell.setImage(img);

	}

	// *********************************
	// Window サイズの初期設定
	// *********************************
	@Override
	protected Point getInitialSize() {
		// プライベート変数を使用してウインドウサイズを決定しています
		return new Point(width, height);
	}
}



Dialog1

ここでは、テーブルコントロールを配置して、仮のデータをセットしています。このパターンを応用する事によって、外部からのデータをループ処理で一覧表示する事が可能になります。
import java.awt.GraphicsEnvironment;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

public class Dialog1 extends Dialog {

	private int width = 800;
	private int height = 600;
	private Table table;

	// *********************************
	// コンストラクタ
	// *********************************
	public Dialog1(Shell parentShell) {
		super(parentShell);
	}

	// *********************************
	// コントロールの追加
	// ※ Design での変更が反映されます
	// *********************************
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);

		// テーブルの作成
		table = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		// 列の作成
		TableColumn tableColumn = new TableColumn(table, SWT.NONE);
		tableColumn.setWidth(100);
		tableColumn.setText("名前");

		TableColumn tableColumn_1 = new TableColumn(table, SWT.NONE);
		tableColumn_1.setWidth(131);
		tableColumn_1.setText("詳細");

		String[] data;

		// 行の作成
		TableItem tableItem = new TableItem(table, SWT.NONE);
		data = new String[]{"山田","主任"};
		tableItem.setText(data);

		TableItem tableItem_1 = new TableItem(table, SWT.NONE);
		data = new String[]{"鈴木","プロジェクトリーダ"};
		tableItem_1.setText(data);


		return container;
	}

	// *********************************
	// ダイアログ専用のボタン
	// *********************************
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
				true);
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}

	// *********************************
	// Window サイズの初期設定
	// *********************************
	@Override
	protected Point getInitialSize() {
		// プライベート変数を使用してウインドウサイズを決定しています
		return new Point(width, height);
	}

	// *********************************
	// Window の初期位置
	// ※ デスクトップの中心
	// *********************************
	@Override
	protected Point getInitialLocation(Point initialSize) {

		GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();

		// デスクトップのサイズ
		Point windowSize = new Point(
				env.getMaximumWindowBounds().width,
				env.getMaximumWindowBounds().height);
		Point position = new Point(0,0);

		// デスクトップの中心に表示します
		return new Point(
			position.x + ((windowSize.x - width) / 2),
			position.y + ((windowSize.y - height) / 2)
		);

		/*	 親ウインドウの中心の場合 */
//		Point windowSize = this.getShell().getParent().getSize();
//		Point position = this.getShell().getParent().getLocation();
//
//		System.out.println(windowSize.x);
//
//		return new Point(
//			position.x + ((windowSize.x - width) / 2),
//			position.y + ((windowSize.y - height) / 2)
//		);

	}

}


HttpGet

インターネットより、テキストデータを取得します
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


public class HttpGet {

	// **********************************************
	// 指定した URL へ 任意の charset で処理
	// **********************************************
	public static String execute(String targetUrl,String targetCharset) {

		StringBuffer web_data = new StringBuffer();

		try {

			// **********************************************
			// インターネットへの接続
			// **********************************************
			// 読み込む WEB上のターゲット
			URL url = new URL(targetUrl);
			// 接続オブジェクト
			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			// GET メソッド
			http.setRequestMethod("GET");
			// 接続
			http.connect();

			// **********************************************
			// ストリームとして読み込む準備
			// **********************************************
			// 以下読み込み3点セット InputStream / InputStreamReader / BufferedReader
			InputStream input_stream = http.getInputStream();
			// UTF-8 でリーダーを作成
			InputStreamReader input_stream_reader = new InputStreamReader(input_stream, targetCharset);
			// 行単位で読み込む為の準備
			BufferedReader buffered_reader = new BufferedReader(input_stream_reader);

			// **********************************************
			// 行の一括読み込み
			// **********************************************
			String line_buffer = null;
			// BufferedReader は、readLine が null を返すと読み込み終了
			while ( null != (line_buffer = buffered_reader.readLine() ) ) {
				// コマンドプロンプトに表示
				web_data.append( line_buffer );
				web_data.append( "\n" );
			}

			// **********************************************
			// 接続解除
			// **********************************************
			http.disconnect();
		}
		catch(Exception e) {
			// 失敗
			System.out.println( "インターネットへのアクセスに失敗しました" );
			e.printStackTrace();
		}
		return web_data.toString();
	}

}




posted by lightbox at 2016-05-07 18:46 | java : WindowBuilder | このブログの読者になる | 更新情報をチェックする

2016年05月06日


kintone JavaScript API で ルックアップ先が更新された場合の参照元を全て更新する

kintone のドキュメントは欲しいものを探しにくい欠点があるのですが、その中でも一番重要な『ルックアップの一括更新』について解説しているページのタイトルが『第11回 REST APIを利用したレコード更新』となっていて気がつきにくくなっている上に、少しバグっています(その通りに実装したら不具合が出た)

▼ 以下がこちらで作成したサンプルコードです。
// *****************************************
// (function(){実行コード})() は JavaSript 
// におけるブロックの実行
// *****************************************
(function() {
	"use strict";

	var target = null;
 
	// レコード一覧画面で更新した場合のイベント
	kintone.events.on('app.record.index.edit.submit', function(event) {

		console.log("レコード一覧画面の event オブジェクト");
		console.dir( event );

		// ルックアップを実装している対象 appid
		var appid = 23;
		// 今回更新したルックアップが参照している値
		// ※ 一般フィールドの場合、要重複不可設定
		var target = event.record.レコード番号R.value;

		var manager = new KintoneRecordManager;
		manager.getRecords(appid, target, function(records) {

			console.log("レコードの取得後のイベント");
			// 取得した全レコードの表示
			console.dir(records);

			// レコード取得後の処理
			updateLookup(appid, createPutRecords(records));
			// 空にしておかないと、次の UI での処理で残ってしまう
			KintoneRecordManager.prototype.records = [];
			KintoneRecordManager.prototype.offset = 0;

		});


	});

	// レコード編集画面
	kintone.events.on('app.record.edit.submit', function(event) {

		console.log("レコード編集画面の event オブジェクト");
		console.dir( event );

		// ルックアップを実装している対象 appid
		var appid = 23;
		// 今回更新したルックアップが参照している値
		// ※ 一般フィールドの場合、要重複不可設定
		var target = event.record.レコード番号R.value;

		var manager = new KintoneRecordManager;
		manager.getRecords(appid, target, function(records) {

			console.log("レコードの取得後のイベント");
			// 取得した全レコードの表示
			console.dir(records);

			// レコード取得後の処理
			updateLookup(appid, createPutRecords(records));
			// 空にしておかないと、次の UI での処理で残ってしまう
			KintoneRecordManager.prototype.records = [];
			KintoneRecordManager.prototype.offset = 0;

		});


	});
 
	// *****************************************
	// kintoneと通信を行うクラス
	// *****************************************
	var KintoneRecordManager = (function() {

		// これがこの中で作成される KintoneRecordManager
		function KintoneRecordManager() {
		}

		// プロパティの定義
		KintoneRecordManager.prototype.records = [];	// 取得したレコード
		KintoneRecordManager.prototype.limit = 2;		// 一回あたりの最大取得件数
		KintoneRecordManager.prototype.offset = 0;		// オフセット


		// すべてのレコード取得する メソッドの定義
		KintoneRecordManager.prototype.getRecords = function(appid, target, callback) {

			console.log("appid : " + appid);
			console.log("target : " + target);

			// kintone.api (REST APIリクエストを送信)
			kintone.api(
				// kintone REST APIのパス または kintone.api.urlで取得したURL
				kintone.api.url('/k/v1/records', true),
				// 使用するHTTPメソッド
				'GET',
				// APIに渡すパラメータ
				{
					app: appid,
					// 参照条件
					// ※ ここではフィールドコードを固定で定義するようにしています
					query: 'LUP_参照コード = "'+ target + '" ' + (' limit ' + this.limit + ' offset ' + this.offset)
				},
				// APIの呼び出しが成功したら実行されるコールバック関数
				// ※ function を return しているので、この中がコールバック処理です
				(function(_this) {
					return function(res) {

						console.log("kintone.api の callback が呼び出されました:" + appid + ":" + target);

						// ここからがコールバック処理
						var len;

						// KintoneRecordManager のプロパティに新しいレコードを追加
						Array.prototype.push.apply(_this.records, res.records);
						// 今回取得したレコード数
						len = res.records.length;

						console.log("今回取得したレコード数:" + len);

						// KintoneRecordManager のプロパティ全レコード数をセット
						_this.offset += len;

						// 読み込み件数制限付きで、全件読む方法
						if (len < _this.limit) { // まだレコードがあるか?

							// 全件読み込んだので、callback を呼び出す
							if (callback !== null) {
								callback(_this.records); // レコード取得後のcallback
							}
						}
						else {
							// まだレコードが残っているので、offset 以降を再度呼び出して処理する
							_this.getRecords(appid, target, callback); // 自分自身をコール
						}
					};
				// this は KintoneRecordManager なので、処理内の _this が KintoneRecordManager
				})(this)
			);
		};

		// この処理の中で作成した KintoneRecordManager 関数を外の KintoneRecordManager 変数に設定する事になります
		return KintoneRecordManager;
	})();


	// *****************************************
	// 更新用オブジェクトの配列を作成するメソッド
	// *****************************************
	function createPutRecords(records) {
		var putRecords = [];
		for (var i = 0, l = records.length; i < l; i++) {
			var record = records[i];
			putRecords[i] = {
				id: record['$id'].value,
				record: {
					"LUP_参照コード" : {
						value: record.LUP_参照コード.value
					}
				}
			};
		}

		// 更新用オブジェクトの配列
		console.dir("putRecords:" + putRecords);

		return putRecords;
	}

	// *****************************************
	// 更新用 API を呼び出すメソッド
	// *****************************************
	function updateLookup(appId, records) {
		// KintoneRecordManager.prototype.limit で割り切れるレコード数の場合
		// 最後に records.length == 0 で呼ばれる
		if ( records.length != 0 ) {
			kintone.api(

				// kintone REST APIのパス または kintone.api.urlで取得したURL
				kintone.api.url('/k/v1/records', true),
				// 使用するHTTPメソッド
				'PUT',
				// APIに渡すパラメータ
				{
					app: appId,
					records: records
				},
				function(resp) {
					// 更新完了時の処理
				}

			);
		}
	}

})();

オリジナルのソースコードからはとても解りにくいであろう、JavaScript 特有の記述が理解しやすいように記述してコメントを付加しています。

▼ 関連する API ページ
kintone.api と kintone.api.url
( その他 : kintone.api.urlForGet、kintone.getRequestToke )


要点

ここでは、参照するアプリ(テーブル)のレコード番号をキーに使用していますが、一般フィールドをキーとする場合、重複不可の設定が必要です。

レコード一覧画面で、直接変更する時と1レコードの表示にしてから変更する時とでは別々のイベント定義が必要です。

ルックアップを実装している対象 appid は現在一つだけ使用していますが、一般的な実装ではここは配列になるべきです。また、その場合は getRecords の完了部分で、次の呼び出しが必要になるので、それなりの改造とテストが必要になります。具体的には、全件読み込んだ後の callback を呼び出す部分で次の appid の呼び出しとなると思います。その場合、引数の appid は、他のプロパティと同様に、prototype で定義すれば良いと思います

参照(検索)用の フィールドコードを固定で定義して使用していますが、汎用的にするにはプロパティ定義か引数定義にします。

JavaScript では function を、処理を格納した変数や値の定義として多用します。例えば、無名 function の場合は return function(){} として処理を戻り値としたり、有名 function では、function name(){} として name という変数を定義してそれを return name として処理を戻り値として返したりしています。

▼ kintone.api.url では、最後のパラメータが省略されているので注意して下さい。
ゲストスペース内でtrueを指定する場合、REST APIの実行に必要なゲストスペース用のURIが返されます。
デフォルトはfalseです。


posted by lightbox at 2016-05-06 17:18 | kintone | このブログの読者になる | 更新情報をチェックする

2016年05月05日


PHP で HTML数値エンティティを、目的のキャラクタセットの文字列に変換する

テキストエディタが優秀な場合は、直接ソースに書いてもいいのですが、古いエディタだと UTF-8 の文字列を直接書けない場合もあります。もちろん、数値データから文字列化する処理に有効ですが、マニュアルには肝心の『変換するコード領域を指定する配列』の説明がありません

以下は簡単なサンプルですが、0x2A6D5 のほうは変換されず、0x2A6D6 のほうは変換されます
	$convmap = array(0x0, 0x2A6D5, 0, 0xFFFFF);
	$wk = mb_decode_numericentity("&#173782;", $convmap, 'UTF-8');	
	print $wk;

	$convmap = array(0x0, 0x2A6D6, 0, 0xFFFFF);
	$wk = mb_decode_numericentity("&#173782;", $convmap, 'UTF-8');	
	print $wk;

0x0 から 0x2A6D6 の範囲のみ変換します。0 はオフセットなので通常は 0 として使いません( 0x2A6D5 では、1 にすれば変換対象になります )。最後の 0xFFFFF はマスクなので、そのまま利用するという意味で全てのフラグが on である 0xFFFFF を使用しています

0x2A6D6 の漢字に関しては、こちらより確認して下さい



𪛖


タグ:PHP
posted by lightbox at 2016-05-05 19:38 | PHP + ベーシック | このブログの読者になる | 更新情報をチェックする

レンタルサーバで PHP のバージョンを 5.4 から 5.6 に変更する時の注意事項

PHP 5.4 までは default_charset に値が入っていませんでした。しかし、5.6 では default_charset = UTF-8 となるので日本語が化ける可能性がとても多くなります。そこで、php.ini の中に以下のように設定を追加します
default_charset = 

こうすると、PHP 5.4 と同じ no_value 設定になります( phpinfo 関数で確認します )



但し、その php ファイルが参照できる範囲に別の個別の php.ini があると、その設定で全て上書きされるので注意して下さい。



posted by lightbox at 2016-05-05 14:36 | PHP | このブログの読者になる | 更新情報をチェックする

2016年05月03日


EASELJS を使用した画像の分割と分割されたエリア毎のアニメーション / createjs.Ticker の reset と init はうまく動きませんでした



createjs.Ticker でアニメーション用のループを作成するので、一旦実行すると CPU 負荷が少しかかった状態になります。そのリセットとかしたかったですけれど、createjs.Ticker の reset と init はうまく動きませんでした。

4分割固定で処理していますが、何分割でもできるようなパラメータ設定になっています。配列の数と、分割の割り算のところを引数にすればいいですね。

EASELJS で作成した Bitmap を TWEENJS でサンプルどおりに動かしてみました
※ 回転はあとから追加です。同時に元の座標に戻しています

<script>
if ( typeof createjs === 'undefined' ) {
	document.write("<"+"script src=\"https://code.createjs.com/easeljs-0.8.2.min.js\"></"+"script>");
	document.write("<"+"script src=\"https://code.createjs.com/tweenjs-0.6.2.min.js\"></"+"script>");
}
</script>

<script>
var bitmap = Array(),bitmap_all,rect = Array();
var tick = false;

$(function(){

	$("#tm_action_05103").on("click", function(){

		if ( !tick ) {
			// アニメーション開始
			createjs.Ticker.addEventListener("tick", stage1);
			tick = true;
		}

		for( i = 0; i < 4; i++ ) {
			bitmap[i].rotation = 0;
			createjs.Tween.get(bitmap[i], {loop: false})
				.to({x: 400}, 1000, createjs.Ease.getPowInOut(4))
				.to({alpha: 0, y: 75}, 500, createjs.Ease.getPowInOut(2))
				.to({alpha: 0, y: 125}, 100)
				.to({alpha: 1, y: 100}, 500, createjs.Ease.getPowInOut(2))
				.to({x: (i%2)*(bitmap_all.image.width/2), y: (parseInt((i/2)))*(bitmap_all.image.height/2), rotation:360 },
					800, createjs.Ease.getPowInOut(2))
				.call(function(){
					console.log("アニメーション終了(一応)");
				});
		}

	});

});
</script>
<input type="button" value="アニメーション" id="tm_action_05103">
<br>
<canvas id="load_area1" width="600" height="450" style='border:1px solid #000000'></canvas>
<script>
var stage1 = new createjs.Stage("load_area1");


img = new Image()
img.onload = function() {

	bitmap_all = new createjs.Bitmap(this);

	// トリミング用 bitmap
	for( i = 0; i < 4; i++ ) {
		bitmap[i] = new createjs.Bitmap(this);

		rect[i] = new createjs.Rectangle(
			(i%2)*(bitmap_all.image.width/2), 
			(parseInt((i/2)))*(bitmap_all.image.height/2), 
			bitmap_all.image.width/2, 
			bitmap_all.image.height/2
		);
		bitmap[i].sourceRect = rect[i];
		bitmap[i].x = (i%2)*(bitmap_all.image.width/2);
		bitmap[i].y = (parseInt((i/2)))*(bitmap_all.image.height/2);

		stage1.addChild(bitmap[i]);
	}

	// 最初の表示
	stage1.update();

}
img.src = "https://lh3.googleusercontent.com/-A5QW2HTze84/VyNZEIwxh4I/AAAAAAAAeRE/-rCcFQmsKawDMRrV6logONKz0i6LVhtYACCo/s600/wing_elf.jpg";

</script>


posted by lightbox at 2016-05-03 21:14 | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする
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 終わり