SQLの窓

2014年05月29日


ドロップシャドウ / フリーフォントで簡単ロゴ作成

フリーフォントで簡単ロゴ作成に、ドロップシャドウ関連の機能補強を行いました。

以前までのドロップシャドウ





テキスト全体を少し薄く表現していましたが、他の機能との連携に必要なので、100% の濃さでテキストを表示するようにしました。

テキストが 100% の濃さのドロップシャドウ





さらに、今まではドロップシャドウの色をテキスト色に合わせていましたが、オプションとして常に黒くできるようにしました。

シャドウ色を常に黒くする





また、文字枠を使いながら、影を付加させる為に影の位置を補正できるようにしました

シャドウの位置を補正する





文字枠の補正にマイナスを指定できるようにしたので、文字をもう一つ複製したような表現が可能になりました。

三重シャドウ





フリーフォントで簡単ロゴ作成で上の画像を再現する

文字枠と背景色を同じにして、ドロップシャドウを調整すると以下のような表現も可能になりました





posted by lightbox at 2014-05-29 23:59 | WEBサービス | このブログの読者になる | 更新情報をチェックする

2014年05月27日


PHP : PDO のエラー処理

概要

PDO エラー処理には3通りあります。

(1) DO::ERRMODE_SILENT
最初はその名の通り、エラーが起きてもなにも起こりません。そのまま実行されますが、エラー情報は設定されていますし、戻り値も正しく返ります。一番簡単でバグさえなければ問題は発生しにくいですが、複雑な問題を確認する為には戻り値とメッセージを常に確認して正しいエラー処理を行う必要があります

(2) PDO::ERRMODE_WARNING
二つ目は、さらにPHPの通常のエラーメッセージを出力させるようにしたバージョンです。初期段階のデバッグに有効です

(3) PDO::ERRMODE_EXCEPTION
三つ目は、try 〜 catch を使うようにしたものですが、慣れていないと扱いは少し難しくなります。しかし、例外によりスクリプトが終了した際には、トランザクションは自動的に ロールバックされるそうです。

前者でどうなるかは未確認ですが、業務アプリケーションならばこちらを選択したほうが良いでしょう。個人の一般の WEB アプリならばそこまで神経質になる必要は無いと思いますので、デフォルトの ERRMODE_SILENT で良いと思います
<?php
$strDriver = "{SQL Native Client}";
$strTarget = "NIGHT_TCP";	// 別名
$strDB = "lightbox";
$strUser = "sa";
$strPass = "passwordpassword";

// **********************************************************
// 接続
// **********************************************************
$Cn = new PDO(
	"odbc:Driver=$strDriver;Server=$strTarget;" .
	"Database=$strDB;Uid=$strUser;Pwd=$strPass;");

	// デフォルトエラーモード
	$Cn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );

	// 存在しない列を更新
	$Query = "update [社員マスタ] set [生年月] = '2005/01/01'";
	$Query .= " where [社員コード] = '0001'";
	$ret = $Cn->exec( $Query );
	if ($ret===false) {
		print_r( $Cn->errorInfo() );
	}


	// エラー表示( デバッグに有効 )
	// 抑制する場合は、@$Cn->exec( $Query );
	$Cn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

	// 存在しない列を更新
	$Query = "update [社員マスタ] set [生年月] = '2005/01/01'";
	$Query .= " where [社員コード] = '0001'";
	$ret = $Cn->exec( $Query );
	if ($ret===false) {
		print_r( $Cn->errorInfo() );
	}

	// try catch 用
	$Cn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

	// 存在しない列を更新
	$Query = "update [社員マスタ] set [生年月] = '2005/01/01'";
	$Query .= " where [社員コード] = '0001'";
	try {
		$ret = $Cn->exec( $Query );
	}
	catch( PDOException $e ) {
		print $e->getMessage();
	}

$Cn = null;

?>



タグ:PDO PHP
posted by lightbox at 2014-05-27 17:25 | PHP + データベース | このブログの読者になる | 更新情報をチェックする

2014年05月23日


VBScript(WMI)によるイベント関数を WMI に登録するタイマー処理

VBScript(WSH) の WScript.CreateObject では、作成したオブジェクトのイベントを受け付ける関数を定義する事ができます。過去、ほとんどそのようなサンプルは現実には無かったのですが、WMI では少なくともタイマー処理として利用可能です。

CreateObject メソッドで strPrefix 引数を指定すると、接続されたオブジェクトが作成されます。これは、オブジェクトのイベントを同期させる場合に便利です。オブジェクトの出力インターフェイスは、オブジェクト作成後にスクリプト ファイルに接続されます。イベント処理関数は、このプリフィックスとイベント名を組み合わせた名前になります。オブジェクト作成時に strPrefix 引数を指定しなかった場合は、ConnectObject メソッドを使ってオブジェクトのイベントを同期させることができます。オブジェクトがイベントを発行すると、WSH は strPrefix + イベント名という形式の名前を持つサブルーチンを呼び出します。たとえば、strPrefix が MYOBJ であり、オブジェクトが OnBegin というイベントを発行した場合、Windows Script Host はスクリプト内の MYOBJ_OnBegin という名前のサブルーチンを呼び出します
タイマー処理
' ********************************************************************
' このセクションは、cscript.exe で処理を強制させるものです
' ********************************************************************
str = WScript.FullName
str = Right( str, 11 )
str = Ucase( str )
if str <> "CSCRIPT.EXE" then
	str = WScript.ScriptFullName
	Set WshShell = CreateObject( "WScript.Shell" )
	Call WshShell.Run( "cmd.exe /c cscript.exe """ & str & """ & pause", 3 )
	WScript.Quit
end if

' ********************************************************************
' 秒単位のログを表示するかどうかのフラグです
' ********************************************************************
Dim Disp : Disp = True	' False にすると、秒単位の表示はしなくなります

' ********************************************************************
' WMI のイベントの定義
' ********************************************************************
Set SINK = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
objWMIService.ExecNotificationQueryAsync _
 SINK, _
 "SELECT * FROM  __InstanceModificationEvent " & _
 "WHERE TargetInstance ISA 'Win32_LocalTime'"

Wscript.Echo "タイマー処理を開始します"
' ********************************************************************
' 停止する為のイベントの定義
' ********************************************************************
Set objMonitor = objWMIService.ExecNotificationQuery( _
	"select * from __InstanceModificationEvent " & _
	"where TargetInstance isa 'Win32_LocalTime' " & _
	" and TargetInstance.Year = 0" _
)

' Wscript.Echo "TargetInstance.Year は 0 にならないので、次の行より後の処理は実行されません"
Set objLatestEvent = objMonitor.NextEvent 
Wscript.Echo "ここは実行されません"

' ********************************************************************
' この処理は、WbemScripting.SWbemSink から呼び出されます
' ********************************************************************
Sub SINK_OnObjectReady(objLatestEvent, objAsyncContext)

	' 10秒毎の処理
	if objLatestEvent.TargetInstance.Second MOD 10 = 0 then
		' ここが 10秒毎に呼び出されます
		Wscript.Echo "秒の余りが 0 の場合にここが実行されます"
		Wscript.Echo "分や時間を使用すると、長いスパンの定期処理に使えます"
	end if

	if Disp then
		' 秒単位に呼び出されるこのルーチンで毎回表示
		Wscript.Echo "Time: " & _
			objLatestEvent.TargetInstance.Hour & ":" & _
			objLatestEvent.TargetInstance.Minute & ":" & _
			objLatestEvent.TargetInstance.Second
	end if
End Sub






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

TCPDF で非埋め込み型として『メイリオ』を使う手順

1) コマンドブロンプトで、C:\Windows\Fonts に入る


2) COPY コマンドで、meiryo.ttc を適当な場所へコピーする


3) UniteTTC をダウンロードして、UniteTTC.exe meiryo.ttc を実行する


4) 4つに分解されますが、meiryo001.TTF が通常の メイリオなので meiryo001.ttf に変更( 全て小文字 )
5) TCPDF の tools フォルダに meiryo001.ttf を移動

6) c:\php\php.exe tcpdf_addfont.php -t CID0JP -i meiryo001.ttf を実行
( c:\php\php.exe は 通常の Windows 用 コマンドプロンプト用 PHP )

7) "インストールフォルダ\tcpdf_6_0_080\tcpdf\fonts\meiryo001.php" が作成される
( ここでのテストは tcpdf_6_0_080 )
8) サンプルの example_038.php の $pdf->SetFont('cid0jp', '', 40); を $pdf->SetFont('meiryo001', '', 40); に変更
9) 実行


※ Excel で表示して書体を比較しています

meiryo001.php の先頭は以下のようにっていて、書体名は Meiryo となっています
<?php
// TCPDF FONT FILE DESCRIPTION
$type='cidfont0';
$name='Meiryo';
$up=-100;
$ut=50;
$dw=1000;
$diff='';
$originalsize=8594960;
// Japanese
$enc='UniJIS-UTF16-H';
$cidinfo=array('Registry'=>'Adobe', 'Ordering'=>'Japan1','Supplement'=>5);
include(dirname(__FILE__).'/uni2cid_aj16.php');


関連する記事
posted by lightbox at 2014-05-23 03:02 | PHP + PDF | このブログの読者になる | 更新情報をチェックする

2014年05月22日


Eclipse+WindowBuilder : DBアプリケーション(社員マスタメンテ)の更新(データ修正)処理

入力チェックが正しく完了した後に、画面データから UPDATE 構文によって SQL の 更新処理を作成して実行します。UPDATE 構文で更新される行は 1 行のみであり、主キーでその行が限定されます

社員マスタ
列名 型名 最大桁 主キー 型説明
1 社員コード VARCHAR 4 1 Null で終了する Unicode 文字列
2 氏名 VARCHAR 50   Null で終了する Unicode 文字列
3 フリガナ VARCHAR 50   Null で終了する Unicode 文字列
4 所属 VARCHAR 4   Null で終了する Unicode 文字列
5 性別 INT     4 バイトの符号付き整数
6 作成日 DATETIME     日付値
7 更新日 DATETIME     日付値
8 給与 INT     4 バイトの符号付き整数
9 手当 INT     4 バイトの符号付き整数
10 管理者 VARCHAR 4   Null で終了する Unicode 文字列
11 生年月日 DATETIME     日付値
更新処理を実行する為に入力をチェックを行っていますが、かならず更新前には操作しているユーザに確認を求める必要があります。それがなければ、意図せぬ更新処理作業を行ってしまう事が十分に考えられます。更新処理はシステムによって重大な処理であり、入力者の不注意で問題が起きるような可能性は最大限排除する必要があります。
			// ここに更新処理を記述する
			int result = JOptionPane.showConfirmDialog(contentPane, "更新してよろしいですか?", "更新確認", JOptionPane.OK_CANCEL_OPTION);
			if ( result == JOptionPane.CANCEL_OPTION) {
				rdbms.close();
				return;
			}

			try {
				
				String scode = syainCode.getText();
				String sname = syainName.getText();
				String ssyozoku = syainSyozoku.getText();
				int ssex = syainSex.getSelectedIndex();
				String skyuyo = syainKyuyo.getText();
				String steate = syainTeate.getText();
				String skanri = syainKanri.getText();
				String sbirth = syainBirth.getText();
						
				String sql = "";
				sql += "update 社員マスタ set";
				sql += " 氏名 = '" + sname + "',";
				sql += " 所属 = '" + ssyozoku + "',";
				sql += " 性別 = " + ssex + ",";
				sql += " 給与 = " + skyuyo + ",";
				if ( steate.trim().equals("") ) {
					sql += " 手当 = NULL,";
				}
				else {
					sql += " 手当 = " + steate + ",";
				}
				if ( skanri.trim().equals("") ) {
					sql += " 管理者 = NULL,";
				}
				else {
					sql += " 管理者 = '" + skanri + "',";
				}
				if ( sbirth.trim().equals("") ) {
					sql += " 生年月日 = NULL,";
				}
				else {
					sql += " 生年月日 = '" + sbirth + "',";
				}
				sql += " 更新日 = now()";
				sql += " where 社員コード = '" + scode + "'";
				System.out.println(sql);
				result = rdbms.stmt.executeUpdate(sql);
				System.out.println("更新件数 : " + result);
				JOptionPane.showMessageDialog(contentPane, "更新処理が実行されました");

				passControl.clearDetailes();			
				passControl.pass1Enable();			
				
				
			} catch (Exception ex) {
				ex.printStackTrace();
			}
			
			
			rdbms.close();
このコード上に、データベースへの接続処理が見えていませんが、直前に他のテーブルの行データの参照の為、既に接続済みです。また、SQLを作成する為に、入力フィールドの状況をチェックしていますが、本来の更新前のチェックで、全ての問題点が排除されているという前提でのコードとなっています。( 例 : 入力フィールドに数値以外の値や漢字スペースは含まれていない )

ここでは、SQL 文を文字列連結で作成していますが、これでは後からのメンテナンス性が悪いので、ベースとなる一文としての SQL 文をテキストで外部に作成して、データ部分を入力値で置き換えるようなクラスまたはメソッドを作成する必要があります。

関連する記事


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

VBScript : スクリプトを終了しないようにする

目的としてはいろいろ考えられますが、ここではよく使われる Sleep の代わりになり、ずっと待ち状態になる方法を紹介します。実際は、時分秒を指定して指定した時刻にのみ処理を開始する事もできます(そのほうが現実的です)。
Do
	WScript.Sleep 10000
Loop

関連する記事

VBScript : 30秒後のイベント処理
VBScript : 10秒毎に処理を実行する( 時刻指定も可能 )
Cron の代替え : VBScript で非同期別スレッドタイマー処理
' このセクションは、cscript.exe で処理を強制させるものです
str = WScript.FullName
str = Right( str, 11 )
str = Ucase( str )
if str <> "CSCRIPT.EXE" then
	str = WScript.ScriptFullName
	Set WshShell = CreateObject( "WScript.Shell" )
	Call WshShell.Run( "cmd.exe /c cscript.exe """ & str & """ & pause", 3 )
	WScript.Quit
end if

' WMI の処理の為のオブジェクトを取得
Set obj = GetObject("winmgmts:\\.\root\cimv2")
' イベントの定義
Set objMonitor = obj.ExecNotificationQuery( _
	"select * from __InstanceModificationEvent " & _
	"where TargetInstance isa 'Win32_LocalTime' " & _
	" and TargetInstance.Year = 0" _
)

Wscript.Echo "TargetInstance.Year は 0 にならないので、次の行より後の処理は実行されません"
Set objLatestEvent = objMonitor.NextEvent 
Wscript.Echo "ここは実行されません"

プロバティとしては以下が使用できます
class Win32_LocalTime : Win32_CurrentTime
{
  uint32 Day;
  uint32 DayOfWeek;
  uint32 Hour;
  uint32 Milliseconds;
  uint32 Minute;
  uint32 Month;
  uint32 Quarter;
  uint32 Second;
  uint32 WeekInMonth;
  uint32 Year;
};


▼ 実際に select * from Win32_LocalTime で取得したサンプルです
DayDayOfWeekHourMillisecondsMinuteMonthQuarterSecondWeekInMonthYear
2241949522242014



タグ:VBScript WMI
posted by lightbox at 2014-05-22 20:55 | VBS + WMI | このブログの読者になる | 更新情報をチェックする

jQuery + Shadowbox.js + Three.js で『画像を蝶のように飛翔させる』デモ表示

Three.js のネタ元は、canvas_geometry_birds です。あちらは鳥オブジェクトですが、少し変更して平面の画像を使えるように改造しています 

2014/05/22 : 画像のカスタマイズ方法です

結局、open_three.js は、ただ jQuery のプラグインとして IFRAME の中身を作っているだけなので、を外部にする必要は特にありません。以下のように実装すれば、背景画像は簡単に変更する事ができます。

とりあえず画像を変えてみたい場合は、こちらに 3D イラストのフリー素材があるので、画像をクリックして大きく表示して、大きな画像を右クリックして URL を取得して使ってみて下さい。( 下にあるソースでは、15行目で指定しています )

蝶の画像は、背景透過の PNG の必要があるので、フリーフォントで簡単ロゴ作成で作成して、Google のギャラリーにアップロードして使用していただくといいと思います。( 下にあるソースでは、12行目で指定しています )

※ ここでは、jQuery を 1.11.0 にしていますが(4行目)、古い IE だと動作しないかもしれないので、古いバージョンを使用しています。
<script>
// このページに jQuery が無い場合にロード
if ( !window.jQuery ) {
	document.write("<"+"script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js\"></"+"script>");
}
// ▼ 以下は Shadowbox と Three.js のコードロードします
</script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/sbx33/loadShadowbox.js"></script>
<script type="text/javascript">
// jQuery でボタンのイベントを取得して、好きな画像を飛ばします
$(function(){
	$("#start_button").openThree("http://winofsql.jp/image/s60_2.png");
});
// ここで背景画像を指定します
var img_url = "https://lh4.googleusercontent.com/-n2hqoMHMJfk/U2JsTXjEtbI/AAAAAAAATV0/hQZ5Oc_RIqA/s1200/uf3_001.jpg";
$.fn.extend({
	openThree: function(openThree_Param) {
		$(this).bind('click', function() {

			Shadowbox.open({ 
				player: 'iframe', 
				content: 'about:blank', 
				options: { 
					onFinish: function() {
						setTimeout(  function() {
							var doc = document.getElementById("sb-player").contentWindow.document;
							doc.write("<"+"style> body { background:url("+img_url+"); } </"+"style>");

							doc.write("<"+"script type=\"text/javascript\" src=\"https://lightbox.sakura.ne.jp/demo/three/three.min57.js\"></"+"script>");
							doc.write("<"+"script type=\"text/javascript\">image_url='" + openThree_Param + "';</"+"script>");
							doc.write("<"+"script type=\"text/javascript\" src=\"https://lightbox.sakura.ne.jp/demo/three/birds.js\"></"+"script>");
							doc.close();
						},100 );
					}
				} 
	
			}); 

		});
		return this;
	}
});
</script>

<button id="start_button">開始</button>

※ このコードをオンラインでテストしたい場合は、こちらから実行できます。このソースコードの右上ツールバーの中の左から2番目のアイコンでクリップボードにコピーされますので、リンク先で貼り付けて『新しく開く』ボタンをクリックしていただくとデモ画面が表示されます


以下は元々の記事です

※ 実行のクリックは、ページが完全にロードしてからでないと動作しないので注意して下さい。

ページ上のコンテンツに対して、jQueryのプラグインを作って、さらにそのプラグインでクリックイベントを登録して Three.js のデモ画面を Shadowbox.js が開いた IFRAME のウインドウに表示します
<script>
if ( !window.jQuery ) {
	document.write("<"+"script src=\"//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js\"></"+"script>");

}
</script>
<script type="text/javascript" src="http://lightbox.on.coocan.jp/sbx33/loadShadowbox.js"></script>
<script type="text/javascript" src="https://lightbox.sakura.ne.jp/demo/three/open_three.js"></script>
<script type="text/javascript">
$(function(){
	$("#code140208003926").openThree($("#code140208003926").children("img").attr("src"));
	$("#code140208003927").openThree("http://winofsql.jp/image/s60_2.png");
	$("#code140208003928").openThree($("#code140208003928").attr("src"));
});
</script>

<button id="code140208003926"><img src="http://winofsql.jp/image/s60_1.png" /></button>
<button id="code140208003927"><img src="http://winofsql.jp/image/s60_2.png" /></button>
<input id="code140208003928" type="image" src="http://winofsql.jp/image/s60_3.png" style="border: solid 1px #000000;border-radius:10px;" />

loadShadowbox.js
if ( !window['lightboxTool'] ) {
	window.lightboxTool = {};
}
if ( !window.lightboxTool.initShadowbox ) {
	window.lightboxTool.initShadowbox = function ( ) {
		Shadowbox.init();
	}
}

(function() {
var str;
var userAgent = window.navigator.userAgent.toLowerCase();
if ( !window.Shadowbox ) {

	str="";
	str+="<link rel=\"stylesheet\" type=\"text/css\" href=\"http://lightbox.on.coocan.jp/sbx33/shadowbox.css\"> \n";
	str+="<"+"script type=\"text/javascript\" src=\"http://lightbox.on.coocan.jp/sbx33/shadowbox.js\" charset=\"utf-8\"></"+"script> ";
	document.write(str);

	if (window.attachEvent){
		window.attachEvent('onload', lightboxTool.initShadowbox );
	}
	else {
		window.addEventListener('load', lightboxTool.initShadowbox, false);
	}

}
})();



open_three.js
$.fn.extend({
	openThree: function(openThree_Param) {
		$(this).bind('click', function() {

			Shadowbox.open({ 
				player: 'iframe', 
				content: 'about:blank', 
				options: { 
					onFinish: function() {
						setTimeout(  function() {
							var doc = document.getElementById("sb-player").contentWindow.document;
							doc.write("<"+"style> body { background-color:#fff; } </"+"style>");

							doc.write("<"+"script type=\"text/javascript\" src=\"https://lightbox.sakura.ne.jp/demo/three/three.min57.js\"></"+"script>");
							doc.write("<"+"script type=\"text/javascript\">image_url='" + openThree_Param + "';</"+"script>");
							doc.write("<"+"script type=\"text/javascript\" src=\"https://lightbox.sakura.ne.jp/demo/three/birds.js\"></"+"script>");
							doc.close();
						},100 );
					}
				} 
	
			}); 

		});
		return this;
	}
});

見せたいのは、Three.js の 3D のデモ画面ですが、Three.js の実行はページの一部で実行するのはとても難しい問題があります。しかし、IFRAME 内に表示すればたいていの問題は解決します。



ただ、IFRAME を使う場合殆どの場合は、外部ドメインにページを作っておいて src 属性でその URL を指定するのが通常です。しかし、それではいろいろ管理が面倒で拡張性が無いので JavaScript の document.write で動的に書き出しています。この方法は昔から Google 等が行っていますし、完全なクロスブラウジングです。

書き出すものも、javascript のライブラリにまとめて SCRIPT 要素のまま書き出します。この際少しルールがあり、依存するライブラリは別々の SCRIPT 要素内から書き出す必要があります。それさえ守れば特に問題も無く動作するのですが、書き出す為の文字列を作るのが手作業では無理があるので自作のツールで行っています。

実装そのものは、jQuery のプラグインでまとめています。こうしておくと好きなコンテンツのクリックイベントとしてデモを表示する事ができます。画像は、プラグインの『openThree』の引数として渡すようになっています。

動作環境は、やはり Google Chrome 推奨です。

※ 背景は、ソースコードからは変えてあります


posted by lightbox at 2014-05-22 12:54 | Three.js & typeface | このブログの読者になる | 更新情報をチェックする

2014年05月20日


立体文字枠サークルテキスト / フリーフォントで簡単ロゴ作成

ここ一ヶ月ほどで、
▼『画像合成機能』( 画像は変更ボタンをクリックすると表示されます )


▼『サークルテキスト機能』


▼『文字枠機能』を追加して来ましたが、


文字枠を付加する際に、上下左右いずれかに長さ調整をする事で影のようになり、立体的にみせれるようになりました。

▼ 以下に白舟シリーズでのサンプルの一覧のリンクを用意しました。





posted by lightbox at 2014-05-20 23:29 | WEBサービス | このブログの読者になる | 更新情報をチェックする

2014年05月17日


Eclipse+WindowBuilder : DBアプリケーション(社員マスタメンテ)の入力チェック

private class UpdateAction extends AbstractAction の全体ソース

入力チェックは、エラー処理も含めて『画面のあるアプリケーション』の仕様の中核となるものです(入力チェック・画面編集・更新処理が中核)

その中でも最も実装が多くなる事が予想されるのが入力チェックで、マスタメンテのような単純な一つの表に対する更新ではあまり他の関連性をチェックする事はありませんが、システムとして整合性を保つ為や、使用するユーザが迷う事無く作業を完了させるために必要な重要な機能となります。

ここでの処理のシナリオとしては、更新ボタンをクリックした直後に入力チェックを一つづつ行い、エラーがあると認識できたらメッセージボックスでエラー内容を表示し、そのエラーの起こったフィールドにフォーカスを移動して入力内容を全て選択状態にした後メソッドを抜けます。

全てのチェックを通り抜けないと更新処理は行いません。

社員マスタメンテで通常考えられる入力チェックは以下のようなものです( 実際は複合される可能性があります )
(1) 必須入力チェック
(2) 入力文字数チェック
(3) 数値チェック
(4) 日付チェック
(5) 他テーブル参照チェック
必須入力チェック
			// 必須チェック
			String inputString = null;
			inputString = syainName.getText();
			inputString = inputString.replaceAll(" ", "");	// 漢字スペースを除去
			if ( inputString.trim().equals("") ) {	// スペースを除去してなにも無い場合
				JOptionPane.showMessageDialog(
						contentPane,
						"必須入力です",
						"エラー",
						JOptionPane.ERROR_MESSAGE);
				syainName.setText("");	// 空白文字があっても無いようにする
				syainName.requestFocusInWindow();
				syainName.selectAll();
				return;
			}


入力文字数チェック
			// 文字数チェック
			int len = 0;
			len = (syainName.getText()).length();
			if ( len > 50 ) {
				JOptionPane.showMessageDialog(
						contentPane,
						"文字数が長すぎます",
						"エラー",
						JOptionPane.ERROR_MESSAGE);
				syainName.requestFocusInWindow();
				syainName.selectAll();
				return;
			}


数値チェック
			// 数値チェック
			int num = 0;
			try {
				num = Integer.parseInt(syainSyozoku.getText());
			} catch (Exception ex) {
				num = -1;
			}
			if ( num < 0 ) {
				JOptionPane.showMessageDialog(
						contentPane,
						"正しい数字を入力して下さい",
						"エラー",
						JOptionPane.ERROR_MESSAGE);
				syainSyozoku.requestFocusInWindow();
				syainSyozoku.selectAll();
				return;
			}


日付チェック
			// 日付チェック
			String birth = syainBirth.getText();
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
			dateFormat.setLenient(false);
			Date date = null;
			try {
				date = dateFormat.parse(birth);
			} catch (Exception ex) {
				date = null;
			}
			if ( date == null ) {
				JOptionPane.showMessageDialog(
						contentPane,
						"日付が正しくありません",
						"エラー",
						JOptionPane.ERROR_MESSAGE);
				syainBirth.requestFocusInWindow();
				syainBirth.selectAll();
				return;
			}


他テーブル参照チェック
			if ( !rdbms.getConnect() ) {
				JOptionPane.showMessageDialog(
						contentPane,
						"データベースに接続できませんでした\nシステム管理者に連絡してください",
						"エラー",
						JOptionPane.ERROR_MESSAGE);
				syainCode.requestFocusInWindow();
				syainCode.selectAll();
				return;
			}
			
			// 参照チェック
			try {
				
				rdbms.stmt = rdbms.con.createStatement();
				String scode = syainSyozoku.getText();
				String query = "";
				query += "select *";
				query += " from コード名称マスタ";
				query += " where コード名称マスタ.区分 = 2";
				query += " and コード  = '" + scode + "'";				
				System.out.println(query);
				rdbms.rset = rdbms.stmt.executeQuery ( query );
				if ( rdbms.rset.next() ) {
					syainSyozokuName.setText(rdbms.rset.getString( "名称" ));
				}
				else {
					JOptionPane.showMessageDialog(
							contentPane,
							"入力したコードは存在しませんでした",
							"エラー",
							JOptionPane.ERROR_MESSAGE);
					syainSyozoku.requestFocusInWindow();
					syainSyozoku.selectAll();
					rdbms.close();
					return;
				}
				
			} catch (Exception ex) {
				ex.printStackTrace();
			}		


関連する記事


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

Eclipse+WindowBuilder : DBアプリケーション(社員マスタメンテ)の二会話画面制御

アプリケーションにおける『会話数』は、ウインドウ数にあたり、2会話目を終了するか、キャンセルしない限り1会話目の結果を変更する事ができないというルールを守る事によって、矛盾の無いデータの処理を行う事が可能になります。

その為に必要な一般的な処理として、1会話目の画面状態の作成、1会話目の画面状態から2会話の画面状態への変更( 画面遷移 )、2会話目の画面に表示されたものを全て消去して初期化する、という3つの処理が必要になりますPassControl クラス
	private class PassControl {

		// 第一会話を使用可能にし、第二会話を使用不能にする
		// フォーカスコントロール
		public void pass1Enable() {
			
			syainCode.setEnabled(true);
			checkButton.setEnabled(true);

			syainName.setEnabled(false);
			syainFuri.setEnabled(false);
			syainSyozoku.setEnabled(false);
			syainSex.setEnabled(false);
			syainKyuyo.setEnabled(false);
			syainTeate.setEnabled(false);
			syainKanri.setEnabled(false);
			syainBirth.setEnabled(false);

			updateButton.setEnabled(false);
			cancelButton.setEnabled(false);
			
			syainCode.selectAll();
			syainCode.requestFocusInWindow();			
		}

		// 第二会話を使用可能にし、第一会話を使用不能にする
		// フォーカスコントロール
		public void pass2Enable() {

			syainCode.setEnabled(false);
			checkButton.setEnabled(false);

			syainName.setEnabled(true);
			syainFuri.setEnabled(true);
			syainSyozoku.setEnabled(true);
			syainSex.setEnabled(true);
			syainKyuyo.setEnabled(true);
			syainTeate.setEnabled(true);
			syainKanri.setEnabled(true);
			syainBirth.setEnabled(true);
			
			updateButton.setEnabled(true);
			cancelButton.setEnabled(true);

			syainName.selectAll();
			syainName.requestFocusInWindow();			
			
		}

		// 第二会話の入力項目をクリアする
		// 選択コントロール
		public void clearDetailes() {
			
			syainSyozokuName.setEditable(false);
			syainSyozokuName.setEnabled(true);
			syainSyozokuName.setFocusable(false);
			syainKanriName.setEditable(false);
			syainKanriName.setEnabled(true);
			syainKanriName.setFocusable(false);

			syainName.setText("");
			syainFuri.setText("");
			syainSyozoku.setText("");
			syainSyozokuName.setText("");
			// コンボボックス非選択
			syainSex.setSelectedIndex(-1);
			syainKyuyo.setText("");
			syainTeate.setText("");
			syainKanri.setText("");
			syainKanriName.setText("");
			syainBirth.setText("");
			
		}

	}

PassControl クラスは、機能をまとめたものであり、メソッドを実行する事が目的なので、private で作成します。( メソッドを3つ作成しても大差はありません )

Eclipse で private クラスを作成するには、手作業で書いたほうが早いですが、一般的なクラス作成のダイアログで『エンクロージング型』にチェックする事で対話的にブロックを作成できます。


ブロックのソース上の位置は、『アウトラインウインドウ』でドラッグして変更できます。

※ インスタンスは、private 変数として定義すると同時に作成しています

初期画面は、passControl.clearDetailes(); と passControl.pass1Enable(); で作成され、キャンセルボタンでも、passControl.clearDetailes(); と passControl.pass1Enable(); が実行されます。社員マスタの内容が表示された時にのみ、passControl.pass2Enable() が実行されます。

その他の画面コントロール

(1) Enter キーを TAB キーと同等に扱い、次のフィールドへの移動に使用する
		addWindowListener(new WindowAdapter() {
			
			@Override
			public void windowOpened(WindowEvent arg0) {
				MainWindow.this.setLocationRelativeTo(null);

				// 接続文字列を作成して、Rdbms のインスタンスを作成
				currentDir = System.getProperty("user.dir");
				String connectionString = "Provider=MSDASQL"
				+ ";Driver={Microsoft Access Driver (*.mdb)}"
				+ ";Dbq=" + currentDir + "\\data\\販売管理C.mdb" + ";";
				rdbms = new Rdbms( connectionString );
				System.out.println(connectionString);
				
				passControl.clearDetailes();
				passControl.pass1Enable();
				
				// 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);
			}
		});


(2) 表示用の入力しない JTextField は、setEnabled を使わない
			// 所属名 編集不可
			syainSyozokuName.setEditable(false);
			// 所属名 使用可
			syainSyozokuName.setEnabled(true);
			// 所属名 フォーカスなし
			syainSyozokuName.setFocusable(false);
			// 管理者名 編集不可
			syainKanriName.setEditable(false);
			// 管理者名 使用可
			syainKanriName.setEnabled(true);
			// 管理者名 フォーカスなし
			syainKanriName.setFocusable(false);

setEnabled を使うと、表示内容が見にくい(画面上のコードが disable で内容が見にくいのが解ると思います)ので、編集不可にしてフォーカスが移動しないようにしています。

また、タブオーダーを指定する事ができないので、ボタンの位置を変更しました。




関連する記事


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

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

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

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

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


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

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

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

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

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


Windows
container 終わり

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

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり