SQLの窓

2016年05月31日


Java、PHP、jQuery : 最近の記事と関連する記事のまとめ / インデックス

Java : WindowBuilder

HttpPost・JOption
Java WindowBuilder から超簡易掲示板(CSVタイプ)投稿

Google Gson・HttpGet・テーブル
WindowBuilder のテーブルコントロールにインターネットから JSON データを読み込んで処理するテンプレート

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

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



HttpGet クラス(ソースコード)
HttpPost クラス(ソースコード)


1からのプロジェクト作成方法


Java : Android Studio

<include>・HttpPost
tools.jar の callHttpGet のテストと include による画面再利用と HttpPost クラスで掲示板書き込み / Android Studio

コンボボックス・リスト処理
Android の Spinner に関するいろいろな実装と知識 / Android Studio


インターネット・画像
AsyncTask を継承して、Drawable を取得する専用クラスを作成する : Android Studio

ボタン
Android Studio でボタンの処理を追加する4つの方法 : Android Studio 2.0

第二画面
新しい Activity を追加して MainActivity より呼び出し、MainActivity に戻る処理

MessageBox
tools.jar を使用して MessageBox 処理

プロジェクト作成
tools.jar を使用して基本的なアクションを簡単に実装する


tools.jar ソースコード ( Tools.java, Tools2.java, TestArrayAdapter.java, AndroidTools.java )

NAVER
Android Studio : jar の作成と実行テスト
Android Studio の設定
Android Studio 予習開始!(良く使う機能・ショートカット・メニュー)


Java : コンソール

インターネット・アクセス
Java のコンソールで NAVER の RSS を取得して、title 部分を正規表現で加工して表示するサンプル

メール送信
java をコマンドプロンプトからビルドして実行するサンプル。( メール送信が初心者には楽しいはず )


PHP

DB・jQuery
PHP で 自家製 API を作成して jQuery の簡単なコードで更新処理を行うサンプル

掲示板・CSV・JSON
超簡易掲示板 : 保存タイプは CSV

掲示板・JSON
超簡易掲示板 ( JSON ) : PHP

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

trim・正規表現
PHP で漢字スペースと通常スペースのトリム


jQuery

音声認識・ブックマークレット
Google Chrome で音声認識の結果をブログの投稿テキストエリアに転送するブックマークレット

ブックマークレット
ブックマークレット IFRAME ユニット作成ツール

ブックマークレット
イラストAC用、一括タグ転送ブックマークレット

音声認識
Google Chrome での音声認識処理

Web Speech API
ほぼ、Google Chrome 限定ですが Web Speech API の現時点での実装と問題点回避方法

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

EASELJS
EASELJS を使用した画像の縮小とトリミングと角丸マスク / 画像は new Image でイベント処理して画像サイズを取得します

一覧・Picasa API
jQuery Columns を使って、Picasa API より アルバム一覧を表示する

jquery.ajax-combobox
jquery.ajax-combobox(オートコンプリートとドロップダウンリストを組み合わせたコンボボックス) を使用して、入力可能なコンボックス( しかもリストはページャ付き )

jquery.ajax-combobox
jquery.ajax-combobox で JSON をデータに使う場合、複数項目を検索対象にする為の簡単な改造


Kintone

kintone で画像を表示する / PC と スマホで少し違います。PC ではスペース項目、スマホでは、スマホ用ヘッダスペースを使用します

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

kintone API のトークンを使った PHP コードの注意点

kintone の開発者ライセンスを取得しました。一年有効で、見たところ4年ぐらい使えそうです


その他

A 要素と CSS だけでボタンを表現する 『BUTTONS』

BUTTON 要素と CSS だけでアイコンボタンを表現する 『BUTTONS』

utf8 文字ツール の 文字参照リンクの作成方法

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

IFRAME 内に外部の javascript を読み込んで画面を作成する / document.write での構築



posted by lightbox at 2016-05-31 13:48 | 記録 | このブログの読者になる | 更新情報をチェックする

Java のコンソールで NAVER の RSS を取得して、title 部分を正規表現で加工して表示するサンプル

java.util.regex.Matcher
java.util.regex.Pattern

groupCount で取得されるのは、部分一致した数なので、() を使用しなければ、戻り値は 0 となります。また、その場合は group() で取得できますし。group(0) でも取得できます。

なので、常に pattern に一致する文字列は group(0) です。group(n) で n が 1 以上は部分一致となります。
よって、部分一致のみのループは、for( int i = 1; i <= m.groupCount(); i++ ) となります。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Main {

	public static void main(String[] args) {
		
		Pattern p;
		Matcher m;
		int len;

		print("処理開始");

		// NAVER の RSS
		String str = httpGet("http://matome.naver.jp/feed/hot");

        // 部分一致の無い パターンを生成
        p = Pattern.compile("<title>.+?</title>");
        m = p.matcher(str);

        // 部分一致した数( 0 になります )
        len = m.groupCount();
        print( Integer.toString(len) );

        while(m.find()) {
        	// 部分一致は無いので、m.group() で パターン
        	// に対する全体一致を取得
       		System.out.println(m.group());
        }

		print("------------------------------------------");
        
        // 部分一致のあるパターンを生成
        p = Pattern.compile("<title>(.+?)</title>");
        m = p.matcher(str);

        // 部分一致した数 ( 1になります )
        len = m.groupCount();
        print( Integer.toString(len) );
        
        while(m.find()) {
        	// m.group(0) はパターンに対する全体一致なので
        	// 1 から始めて部分一致のみ表示
        	for( int i = 1; i < (len +1); i++) {
        		System.out.println(m.group(i));
        	}
        }
        
		print("------------------------------------------");
        
        // 部分一致のあるパターンを生成
        p = Pattern.compile("(<title>)(.+?)(</title>)");
        m = p.matcher(str);

        len = m.groupCount();
        print( Integer.toString(len) );

        String partsString;
        StringBuilder buffer;
        while(m.find()) {
    		buffer = new StringBuilder();
        	for( int i = 1; i < (len +1); i++) {

        		// title 開始タグ
        		if ( i == 1) {
        			buffer.append("『");
        		}
        		// title 内容
        		if ( i == 2) {
            		partsString = m.group(2);
            		// String クラスの正規表現置換
            		// 文の区切り的文字で改行
            		partsString = partsString.replaceAll("[。、.…!?]+", "\n");
        			buffer.append(partsString);
        		}
        		// title 終了タグ
        		if ( i == 3) {
        			buffer.append("』");
        		}
        	}
    		print(buffer.toString());
    		print("");
        }

	}
	
	// ********************************
	// データ表示用
	// ********************************
	public static void print( String s ) {
		System.out.println(s);
	}	

	// ********************************
	// static void main より呼び出す為の
	// static な インターネットアクセス関数 
	// ********************************
	public static String httpGet( String s ) {

		String result = "";

		try {
			URL url = new URL(s);

			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			http.setRequestMethod("GET");
			http.connect();
			InputStream is = http.getInputStream();

			InputStreamReader isr = new InputStreamReader(is,"UTF8");
			BufferedReader br = new BufferedReader(isr);
			String line_buffer;
			StringBuilder sb = new StringBuilder();

			while(null != (line_buffer = br.readLine() )) {

				sb.append(String.format("%s\n",line_buffer));

			}

			br.close();
			isr.close();
			is.close();

			result = sb.toString();

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

		return result;

	}	

}




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

2016年05月30日


PHP で 自家製 API を作成して jQuery の簡単なコードで更新処理を行うサンプル

以下のような『社員マスタ』を使って、まず PHP のコードを用意します。
create table `社員マスタ` (
	`社員コード` varchar(4)
	,`氏名` varchar(50)
	,`フリガナ` varchar(50)
	,`所属` varchar(4)
	,`性別` int
	,`作成日` datetime
	,`更新日` datetime
	,`給与` int
	,`手当` int
	,`管理者` varchar(4)
	,`生年月日` datetime
	,primary key(`社員コード`)
)


全てのデータが空でも、SQL 的にはエラーは起こりません。但し、エラーが発生した場合は、kj にエラーメッセージをセットし、furi に 更新 SQL をセットします。

dbdata_update_json.php
<?php
header( "Content-Type: application/json; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );
header( "Access-Control-Allow-Origin: *" );

// ***********************************************
// 初期設定
// ***********************************************
if ( $_GET["sdata"] == "" ) {
	$_GET["sdata"] = "{}";
}
$data = json_decode($_GET["sdata"]);
$data->type = "UPDATE";

// ***********************************************
// 利用変数設定
// ***********************************************
$json_type =  JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT;
$db_data_type = MYSQLI_ASSOC;
$_GET["sdata"] = str_replace("'","''",$_GET["sdata"]);
// -----------------------------------------------


// ***********************************************
// 接続情報
// ***********************************************
$server = 'localhost';
$db_name = 'lightbox';
$user = 'root';
$password = 'trustno1';
// -----------------------------------------------


// ***********************************************
// 接続
// ***********************************************
$connect = @ new mysqli($server, $user, $password, $db_name);
if ($connect->connect_error) {
	$data->status = "ERROR";
	$data->kj = "接続エラーです";
	print json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
	exit();
}
$connect->set_charset("utf8"); 
// -----------------------------------------------


// ***********************************************
// NULL 項目の対応
// ***********************************************
if ($data->kyuyo == '') {
	$data->kyuyo = "null";
}
if ($data->teate == '') {
	$data->teate = "null";
}
if ($data->seibetu == '') {
	$data->seibetu = "0";
}
if ($data->birth == '') {
	$data->birth = "null";
}
else {
	$data->birth = "'{$data->birth}'";
}
// -----------------------------------------------


// ***********************************************
// 更新 SQL
// ***********************************************
$query = <<< QUERY
update `社員マスタ` set 
	`氏名` = '{$data->kj}'
	,`フリガナ` = '{$data->furi}'
	,`性別` = {$data->seibetu}
	,`給与` = {$data->kyuyo}
	,`手当` = {$data->teate}
	,`所属` = '{$data->syozoku}'
	,`管理者` = '{$data->kanri}'
	,`生年月日` = $data->birth
 where
 `社員コード` = '{$data->scode}'
QUERY;
// -----------------------------------------------


// ***********************************************
// クエリ実行
// ***********************************************
$result = $connect->query($query); 
if ( !$result ) {
	$data->status = "ERROR";
	$data->kj = "クエリに誤りがあります";
	$data->furi = $query;
	print json_encode( $data, $json_type );
	exit();
}
else {
	$data->status = "SUCCESS";
}
// -----------------------------------------------


// ***********************************************
// 接続解除
// ***********************************************
$connect->close();
// -----------------------------------------------


// ***********************************************
// 結果
// ***********************************************
print json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);

// -----------------------------------------------

?>


PHP で Access-Control-Allow-Origin: * をセットしているので、どこに置いても JavaScript から呼び出し可能です。

以下のような簡単なコードで更新のテストが可能です。
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script>
$(function(){
	var sdata = {};
	$("#build").on("click", function(){
		$(".entry").find("input").each(function(idx){
			sdata[$(this).prop("id")] = $(this).val();
		});
		$("#result").text( JSON.stringify(sdata,null,"    ") );
	});
	$("#send").on("click", function(){
		var sdata = encodeURIComponent( $("#result").text() );
		$.get("http://localhost/log/easy_board/dbdata_update_json.php?sdata="+sdata ,function(data){
			console.dir(data);
		});
	});
});
</script>
<input id="build" type="button" value="JSON 文字列作成">
<input id="send" type="button" value="サーバ送信">
<pre class="entry">
<input id="scode"> scode
<input id="kj"> kj
<input id="furi"> furi
<input id="seibetu"> seibetu
<input id="kyuyo"> kyuyo
<input id="teate"> teate
<input id="syozoku"> syozoku
<input id="kanri"> kanri
<input id="birth"> birth
</pre>
<pre id="result">
</pre>



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

tools.jar の callHttpGet のテストと include による画面再利用と HttpPost クラスで掲示板書き込み / Android Studio

tools.jar

libs フォルダに保存して、右クリックから Add as Library を実行すると参照可能になります。

▼ ソースコード
Tools, Tools2, TestArrayAdapter, AndroidTools.java )

tools.jar は、気軽にアンドロイドのアプリケーションのテストができるように作成したライブラリです。Android の動作テストはとても時間がかかり、結構デリケートな部分が多いので、できればこのライブラリの中にあるような内容は適当にしたい事が多くあります。特に、商品では無く他人への説明や他の機能の習熟目的で使用し、自分自身は学生をターゲットにしており、授業で使用しています。

それらの中でも、特に面倒くさいのがインターネットに対するアクセスです。tools.jar では、GET アクセスは実装していますが、POST アクセスは実装していません。POST には POST するだけの意味がある時にしか利用されないので、ここで HttpPost クラスをソースで実装して 超簡易掲示板(CSV) を使って投稿するテストをしています。



画面を二つ使い、include でボタン3つの定義を両方で利用しています。
(Android Studio では、新しいアクティビティを作成すると、AndroidManifest も自動的に書き換えられます。)
※ 具体的なタイムアウト時の処理は行っていません(何も起きません)

 

MainActivity.java

次画面2ボタンでインターネットよりテキストデータを取得し(tools.jar の callHttpGet)、次画面に引き渡してテキストエリアに表示します。そこで投稿ボタンで実際の WEB に対する投稿(HttpPost) となります。
package lightbox.may.toolstest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import jp.android.work.Tools;

public class MainActivity extends AppCompatActivity {

	// テキストビュー( 表示用 )
	private TextView tv;

	// *****************************************
	// 初期画面構築
	// *****************************************
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 表示部分のインスタンスの取得
		tv = (TextView) MainActivity.this.findViewById(R.id.textView);

		// *****************************************
		// ボタン1 の設定
		// *****************************************
		Button btn1 = (Button)MainActivity.this.findViewById(R.id.button);
		btn1.setText("次画面");
		MainActivity.this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

			// 呼び出し番号 (1)
			Tools.callActivity(MainActivity.this,Main2Activity.class, 1);

			}

		});

		// *****************************************
		// ボタン2 の設定
		// インターネットのデータを次画面に引き渡す
		// *****************************************
		Button btn2 = (Button)MainActivity.this.findViewById(R.id.button2);
		btn2.setText("次画面2");
		btn2.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				Tools.callHttpGet(
					"http://toolbox.winofsql.jp/kumonoito.txt",
					"utf-8",
					new Tools.OnAsyncTaskListener() {
						@Override
						public void onAsyncTaskListener(String s) {
							Intent intent = new Intent(MainActivity.this, Main2Activity.class);
							intent.putExtra("requestCode",2);
							intent.putExtra("text",s);
							startActivityForResult(intent, 2);
						}
					});

			}

		});

		// *****************************************
		// ボタン3 の設定
		// ブラウザ呼び出し
		// *****************************************
		Button btn3 = (Button)MainActivity.this.findViewById(R.id.button3);
		btn3.setText("ブラウザ");
		btn3.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				Tools.callBrowser(MainActivity.this,"http://weather.yahoo.co.jp/weather/jp/27/6200.html");

			}

		});

	}

	// *****************************************
	// 第二画面から戻って来た時の処理
	// onActivityResult
	// *****************************************
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		Log.i("lightbox", String.format("呼び出し番号 : %d", requestCode)  );
		Log.i("lightbox", String.format("戻り番号 : %d", resultCode)  );

		if ( data != null ) {
			// 戻りデータの取得
			String returnData = data.getStringExtra("returnData");
			if (returnData != null) {
				// テキストビューに表示
				tv.setText(returnData);
			}
		}

	}
}


Main2Activity.java
package lightbox.may.toolstest;

import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Main2Activity extends AppCompatActivity {

	// 呼び出し番号
	private int requestCode;
	// テキストエリア
	private EditText et;

	// *****************************************
	// 初期画面構築
	// *****************************************
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main2);

		// 入力部分のインスタンスの取得
		et = (EditText) Main2Activity.this.findViewById(R.id.editText);

		// *****************************************
		// 前の画面から送られたデータの取得
		// *****************************************
		Intent intent = getIntent();

		// 1) テキストデータ
		String text = intent.getStringExtra("text");
		if ( text != null ) {
			et.setText(text);
		}
		// 2) 整数データ
		requestCode = intent.getIntExtra("requestCode", 0);
		if ( requestCode != 0 ) {
			Log.i("lightbox", String.format("呼び出し番号 : %d", requestCode));
		}

		// *****************************************
		// ボタン1 の設定
		// 整数のみを戻す
		// *****************************************
		Button btn1 = (Button)Main2Activity.this.findViewById(R.id.button);
		btn1.setText("戻る");
		btn1.setTextColor(Color.parseColor("#f84848"));
		btn1.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				// 戻り値のみ返す
				setResult(100);

				// 第二画面を終了して初期画面に戻る
				finish();

			}

		});

		// *****************************************
		// ボタン2 の設定
		// *****************************************
		Button btn2 = (Button)Main2Activity.this.findViewById(R.id.button2);
		btn2.setText("投稿");
		btn2.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				Intent intent = new Intent();
				setResult(200,intent);

				// エミュレータから PC の WEBサーバへアクセスする場合
//				String url = "http://10.0.2.2/log/easy_board/csvtype/board.php";

				// 実機を PC につないで、WiFi 接続を可能にした場合
				// 192.168.1.2 は PC の IPアドレス
				String url = "http://192.168.1.2/log/easy_board/csvtype/board.php";

				Map<String,String> url_param = new HashMap<String,String>();
				url_param.put("url", url);

				Map<String,String> param = new HashMap<String,String>();
				param.put("send", "send");
				param.put("subject", "テスト投稿");
				param.put("name", "ウインドウビルダー");
				param.put("text", et.getText().toString());
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
				param.put("datetime", sdf.format(new Date()));

				new AsyncTask<Map,Void,String>(){
					@Override
					protected String doInBackground(Map... params) {

						// 引数より URL 部分を取得
						String url = params[1].get("url").toString();

						Log.i("lightbox",url);

						// インターネットアクセス
						return HttpPost.execute(url, params[0], "utf-8");

					}

					@Override
					protected void onPostExecute(String s) {
						Log.i("lightbox",s);
						finish();

					}
				}.execute(param,url_param);



			}

		});

		// *****************************************
		// ボタン3 の設定
		// 整数と文字列を戻す
		// *****************************************
		Button btn3 = (Button)Main2Activity.this.findViewById(R.id.button3);
		btn3.setText("戻る+データ");
		btn3.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				// 渡す値
				Intent intent = new Intent();
				intent.putExtra("returnData", et.getText().toString());
				// 戻り値と値を返す
				setResult(300, intent);

				finish();

			}

		});

	}

}


ボタン部分の画面パーツ( action_buttons.xml )



デザインタブから <include> を選択できます。クリックすると参照可能な画面一覧が表示されるので、選択するとカーソルがコントロールを選択した状態になり、デザイン画面やツリーにドロップ可能になります。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1"
        android:id="@+id/button"
        android:layout_weight="1"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2"
        android:id="@+id/button2"
        android:layout_weight="1"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button3"
        android:id="@+id/button3"
        android:layout_weight="1"
        />

</LinearLayout>

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="lightbox.may.toolstest.MainActivity">


    <include
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        layout="@layout/action_buttons"
        android:id="@+id/include2"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollView"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/include2">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView"/>
    </ScrollView>
</RelativeLayout>


activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="lightbox.may.toolstest.Main2Activity">

    <include
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        layout="@layout/action_buttons"
        android:id="@+id/include"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inputType="textMultiLine"
        android:ems="10"
        android:id="@+id/editText"
        android:textSize="20dp"
        android:layout_below="@+id/include"
        android:layout_alignParentStart="true"
        android:gravity="top|left"/>

</RelativeLayout>



posted by lightbox at 2016-05-30 18:56 | Android Studio 2 | このブログの読者になる | 更新情報をチェックする

2016年05月29日


Java WindowBuilder から超簡易掲示板(CSVタイプ)投稿

HttpPost クラスのテストです。



超簡易掲示板(CSV)は以下からダウンロードできます。

超簡易掲示板 : 保存タイプは CSV

WindowBuilder 側では、複数行のテキストフィールドを使って単純投稿です。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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;
import org.eclipse.swt.widgets.Text;

import com.google.gson.Gson;


public class TopWindow extends ApplicationWindow {

	private int width = 600;
	private int height = 440;
	private Gson gson;
	private Text text;

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

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

		// ボタンの定義
		Button button = new Button(container, SWT.NONE);
		// ボタンのイベント
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {

				// プログラム開始時に実行すると、固まるので直前に
				try {
					UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
				} catch (ClassNotFoundException | InstantiationException
						| IllegalAccessException
						| UnsupportedLookAndFeelException e1) {
					e1.printStackTrace();
				}

				// 確認ダイアログ( OK_CANCEL )の表示
				int result = JOptionPane.showConfirmDialog(
						null,
						"データを POST しますか",
						"確認",
						JOptionPane.OK_CANCEL_OPTION,
						JOptionPane.QUESTION_MESSAGE);
				// OK を選択
				if ( result == JOptionPane.OK_OPTION ) {

					// POST データ
					Map<String,String> param = new HashMap<String,String>();
					param.put("send", "send");
					param.put("subject", "テスト投稿");
					param.put("name", "ウインドウビルダー");
					param.put("text", text.getText());
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
					param.put("datetime", sdf.format(new Date()));

					// インターネットアクセス
					String data = HttpPost.execute("http://localhost/log/easy_board/csvtype/board.php", param, "utf-8");
					// データを取得できた
					if ( !data.equals("") ) {
						// コンソールで確認
						System.out.println(data);
					}
				}
			}
		});
		button.setBounds(10, 10, 81, 28);
		button.setText("実行");
		
		text = new Text(container, SWT.BORDER | SWT.MULTI);
		text.setBounds(10, 44, 483, 341);


		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("タイトル文字列");

	}

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

}


プロジェクトを一から作る方法


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

超簡易掲示板 : 保存タイプは CSV





board.php、model.php、view.php の 3 ファイルで動作します。json.php が同梱されていますが、出力ファイルである board.csv を JSON 形式で取得する為のコードです。( JavaScript からアクセスする場合は、header( "Access-Control-Allow-Origin: *" ); を追加して下さい )

他のアプリケーションからのアクセスを簡単にテストできる仕様になっています。

board.php
<?php
// **************************************
// php.ini の output_buffering をチェックして
// 有効になっていた場合は、header の前に出力可能です
// **************************************

// **************************************
// 通常の HTML として出力します
// **************************************
header( "Content-Type: text/html; Charset=utf-8" );

// **************************************
// キャッシュを無効にするヘッダ
// ※ いろいろあるのは念のため
// **************************************
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **************************************
// 関数の定義を読み込みます
// **************************************
require_once("model.php");

// **************************************
// $_POST['send'] != "" は送信ボタンが
// クリックされた事を示します
// さらに、テキストエリアに何か入力され
// た場合に処理を行います
// **************************************
$_POST['text'] = preg_replace( "/^[ \s]+/u", "", $_POST['text'] );
$_POST['text'] = preg_replace( "/[ \s]+$/u", "", $_POST['text'] );
if ( $_POST['send'] != "" && $_POST['text'] != "" ) {

	// データの書き込み処理
	post_data();

}

// *************************************
// データの表示処理
// *************************************
disp_data();


// **************************************
// ▼ 以下は画面です。$log_text を
//    埋め込んでいます
// **************************************
require_once("view.php");
?>


model.php
<?php

// **************************************
// データの書き込み処理
// **************************************
function post_data() {

	// データを一括読み込み
	$log_text = @file_get_contents("board.csv");

	// **************************************
	// 本文中の改行コードを "\n" という
	// 文字列に変換しています
	// **************************************
	$_POST['text'] = str_replace("\r\n","\\n",$_POST['text']);
	$_POST['text'] = str_replace("\n","\\n", $_POST['text'] );
	$_POST['text'] = str_replace("\r","\\n", $_POST['text'] );

	// HTML 要素を無効にする
	$_POST['text'] = str_replace("<","&lt;",$_POST['text']);
	$_POST['text'] = str_replace(">","&gt;",$_POST['text']);

	// HTML 要素を無効にする
	$_POST['subject'] = str_replace("<","&lt;",$_POST['subject']);
	$_POST['subject'] = str_replace(">","&gt;",$_POST['subject']);
	$_POST['name'] = str_replace("<","&lt;",$_POST['name']);
	$_POST['name'] = str_replace(">","&gt;",$_POST['name']);

	// シングルクォートとダブルクォートとカンマ
	$_POST['text'] = str_replace("'","&#39;",$_POST['text']);
	$_POST['text'] = str_replace("\"","&#34;",$_POST['text']);
	$_POST['text'] = str_replace(",","&#44;",$_POST['text']);

	// シングルクォートとダブルクォートとカンマ
	$_POST['subject'] = str_replace("'","&#39;",$_POST['subject']);
	$_POST['subject'] = str_replace("\"","&#34;",$_POST['subject']);
	$_POST['subject'] = str_replace(",","&#44;",$_POST['subject']);
	$_POST['name'] = str_replace("'","&#39;",$_POST['name']);
	$_POST['name'] = str_replace("\"","&#34;",$_POST['name']);
	$_POST['name'] = str_replace(",","&#44;",$_POST['name']);

	$log_wk = "{$_POST['text']},{$_POST['subject']},{$_POST['name']},{$_POST['datetime']}";

	// **************************************
	// 前回データとの境界に改行コードを
	// 設定しています
	// **************************************
	$log_text = $log_wk . "\n" . $log_text;

	// 書き込み
	file_put_contents("./board.csv", $log_text );

	// GET メソッドで再表示します
	header( "Location: board.php" );
	exit();


}

// **************************************
// データの表示処理
// **************************************
function disp_data() {

	// 埋め込み用データを global 宣言
	global $log_text;

	// データを一括読み込み
	$rows = @file("./board.csv");
	// ファイルが存在しない場合
	if ( $rows === false ) {
		$log_text = "ここに投稿データが表示されます";
		return;
	}

	// 表示用の埋め込みに使用される文字列変数
	$log_text = "";
	foreach( $rows as $v ) {

		$data = explode(",", $v);

		// **************************************
		// 本文の改行は br 要素で表現します
		// **************************************
		$row = str_replace("\\n", "<br>\n", $data[0] );

		// **************************************
		// 行毎に表示 HTML を作成
		// **************************************
		$row = "<h3>{$data[1]}</h3>{$row}<br><span class='sb'>({$data[2]} : {$data[3]} )</span><br>";

		// **************************************
		// 記事の境界を hr 要素で表現します
		// **************************************
		$row .= "<hr>\n";

		// **************************************
		// 表示画面全体 を作成
		// **************************************
		$log_text .= $row;
	
	}


}

?>


行データの作成は、以下のように置き換えるとメンテナンスしやすくなります。また、この部分を別ファイルにして require するともっと使いやすくなるでしょう。
		// **************************************
		// 行毎に表示 HTML を作成
		// **************************************
		$row = <<<HTML
		<h3>{$data[1]}</h3>
		{$row}<br>
		<span class='sb'>({$data[2]} : {$data[3]} )</span><br>
HTML;


view.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<style>
* {
	font-family: "ヒラギノ角ゴPro W3","Hiragino Kaku Gothic Pro","メイリオ",Meiryo,"MS Pゴシック",Verdana,Arial,Helvetica,sans-serif;
}
body {
	margin: 5px;
}
form {
	padding-right: 5px;
}
.sb {
	font-size: 8px;
}
#text {
	height: 100px;
	width: 500px;
}
#subject,#name {
	width: 400px;
}

@media screen and (max-width:479px) {

	#text {
		width: 100%;
	}
	#subject,#name {
		width: 230px;
	}
	#line_control {
		display: none;
	}
}

</style>

<script>

$( function(){
	$("form").on("submit", function(){

		var dateNow = new Date();
		var dateString = 
			dateNow.getFullYear() + "/" + 
			("0"+(dateNow.getMonth()+1)).slice(-2)+ "/" + 
			("0"+(dateNow.getDate())).slice(-2);
		var timeString = 
			("0"+(dateNow.getHours())).slice(-2) + ":" + 
			("0"+(dateNow.getMinutes())).slice(-2) + ":" + 
			("0"+(dateNow.getSeconds())).slice(-2);

		$("#datetime").val( dateString + " " + timeString );

	});
});

</script>
</head>

<body>
<h3><a href="board.php" style="color:black;">超簡易掲示板 ( CSV )</a></h3>

<form method="POST">
	タイトル <input
		type="text"
		id ="subject"
		name="subject">
	<br>
	名  前 <input
		type="text"
		id ="name"
		name="name">
	<br>
	<textarea
		id ="text"
		name="text"></textarea>
	<input type="hidden"
		id="datetime"
		name="datetime">
	<br>
	<input
		type="submit"
		name="send"
		value="送信">
</form>
<br>

<?= $log_text ?>

</body>
</html>


json.php
<?php
// **************************************
// 通常の HTML として出力します
// **************************************
header( "Content-Type: application/json; charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// データを一括読み込み
$rows = @file("./board.csv");
// ファイルが存在しない場合
if ( $rows === false || $rows[0] == "" ) {
	print '{ "error": "ファイルが存在しません" }';
	exit();
}

// 全ての行用の JSON 用クラス作成
$json = new stdClass;
// 行データを格納する配列を作成
$json->item = array();

foreach( $rows as $v ) {

	$data = explode(",", $v);

	// 新しい行用のクラス作成
	$board_data = new stdClass;

	// text プロパティに 本文をセット
	$board_data->text = $data[0];
	// subject プロパティに タイトルをセット
	$board_data->subject = $data[1];
	// name プロパティに 名前をセット
	$board_data->name = $data[2];
	// subject プロパティに タイトルをセット
	$board_data->datetime = $data[3];

	// 配列の最後に投稿データをセット
	array_push ($json->item, $board_data);


}

print json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

?>




posted by lightbox at 2016-05-29 22:21 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする
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 終わり