(windows 10版)
Java言語は1990年初頭にジェームス・ゴスリン(James Gosling)博士によって開発された言語として有名です。Java言語の仕様としては、C言語やC++言語から受け継がれていると見られる文法規則もたくさんあるようですので、C言語やC++言語になじみの深いユーザーにとっては、理解しやすいところも多いのではないかと考えられます。
かつてC言語は構造化言語、関数・手続き型と呼ばれていましたが、C++言語ではこれをベースにクラスという概念を取り入れました。また、さらに多くの機能を持つクラスライブラリーというものを充実させた結果、C++では言語はかなり複雑、難解な部分も散見されます。これに対してJava言語ではC++言語のクラス、構造体、共用体を一元化した「クラス」として統一的に使用できるように設計してありますので、コードを眺めてみると非常にすっきりとした感じを受けます。
さらに、Java言語では文字や画像をはじめ、音声などのマルチメディアを簡単に操作できるようなクラスライブラリーが提供されています。筆者も日ごろJava言語をよく利用しているというわけではありませんが、今回の「プログラム言語で日本語多めに」というテーマで、近年愛好者が急増しているJava言語を取り上げてみたいと思います。
詳しいJava言語の文法などについては、各自で専門書などを参考にされたらよいかと思います。今回試行した環境はオラクル社から提供されているJDK8 をダウンロードしたものを使っております。これもインストール方法については、同社のインストール手順書などを参考にしてください。またJava言語が実行できる環境で、FLEXやC言語の処理系が動くような環境設定(パスが通るようにすることなど)が必要です。
また、C++言語編と同じように、日本語で書かれたJava言語ファイルの名前を仮にファイル1.jjavaとすると
>jjava ファイル1
というバッチコマンドによりファイル1.javaを生成し、さらに翻訳(javacによるコンパイル)を行い、Javaバイトコード(中間コード)であるファイル1.classを生成します。
jjavaというFLEXで作成された日本語カスタマイザー実行プログラムは、C++言語の場合とほとんど同じ仕様です。この中間コードを実行するためには以下のように入力すれば、Javaインタープリターによりプログラムが実行されます。
>java ファイル1
ここで、日本語定義の領域がかなり大きくなってきましたので、Java言語編ではC++言語編と同様、自分でよく使う予約語や演算子などの日本語定義部分をプログラムとは別に、外部である程度まとめて宣言できるようにしておきます。そして処理するときにバッチコマンドの機能を利用して、宣言ファイルと日本語Javaファイルを結合して、日本語定義部分を通常のJava言語に置き換えをするということにしました。
以下は、別に定義した日本語Java宣言ファイル「std_include.jjava」の内容です。
#日本語定義 整数型 "int"
#日本語定義 文字型 "char"
#日本語定義 実数型 "float"
#日本語定義 論理型 "boolean"
#日本語定義 型なし "void"
#日本語定義 全域で使用可 "public"
#日本語定義 仲間内で使用可 "private"
#日本語定義 派生の仲間まで使用可 "protected"
#日本語定義 一つの実体だけ "static"
#日本語定義 引き継ぎ "extends"
#日本語定義 実装 "implements"
#日本語定義 もし "if"
#日本語定義 それ以外 "else"
#日本語定義 戻る "return"
#日本語定義 繰り返し "while"
#日本語定義 反復 "for"
#日本語定義 後判定反復 "do"
#日本語定義 対象作成 "new"
#日本語定義 振り分け "switch"
#日本語定義 場合分け "case"
#日本語定義 振り分け終了 "break"
#日本語定義 真 "true"
#日本語定義 偽 "false"
#日本語定義 かつ "&&"
#日本語定義 または "||"
// クラス関係
#日本語定義 はじまり "main"
#日本語定義 仲間の集まり "class"
#日本語定義 文字列の仲間 "String"
#日本語定義 窓枠の仲間 "Frame"
#日本語定義 字体の仲間 "Font"
#日本語定義 図画の仲間 "Graphics"
#日本語定義 文書領域の仲間 "TextArea"
#日本語定義 メニュー欄の仲間 "MenuBar"
#日本語定義 メニュー中項目の仲間 "Menu"
#日本語定義 メニュー小項目の仲間 "MenuItem"
#日本語定義 二次元図画の仲間 "Graphics2D"
#日本語定義 窓処理の仲間を呼ぶ "import java.awt.*"
#日本語定義 出来事処理の仲間を呼ぶ "import java.awt.event.*"
#日本語定義 いろいろと使える仲間を呼ぶ "import java.util.*"
#日本語定義 データ転送の仲間を呼ぶ "import java.awt.datatransfer.*"
#日本語定義 図形描画の仲間を呼ぶ "import java.awt.geom.*"
#日本語定義 窓枠を適応させる仲間 "WindowAdapter"
#日本語定義 動作に対するご用聞き "ActionListener"
#日本語定義 キー入力に対するご用聞き "KeyListener"
#日本語定義 動作に伴うでき事の仲間 "ActionEvent"
#日本語定義 整数の仲間 "Integer"
#日本語定義 整数値 "intValue()"
#日本語定義 文字列を整数に変換 "Integer.valueOf"
#日本語定義 表示する "System.out.println"
#日本語定義 終了する "System.exit(0)"
#日本語定義 窓枠ご用聞きの追加 "addWindowListener"
#日本語定義 動作ご用聞きの追加 "addActionListener"
#日本語定義 項目ご用聞きの追加 "addItemListener"
#日本語定義 キー入力ご用聞きの追加 "addKeyListener"
#日本語定義 動作が実行されたとき "actionPerformed"
#日本語定義 窓枠を閉じる "windowClosing( WindowEvent win_evnt )"
これ以降の例題では、プログラム内に上記の日本語定義の部分はありません。
はじめに、例U10-1として西暦年を入力し、その年がうるう年かどうかを判定するプログラムを示します。Windows版の同じプログラムで「剰余計算」に「%」として定義していたものをubuntu版では「%%」としています。 また、最近のjava処理系は変数名、関数名、クラス名などに日本語を直接使っても問題なく処理してくれますので、プログラム中に日本語カスタマイザーの自動変数定義は使っていません。
// 西暦を入力し、その年がうるう年かどうかを判定する
#日本語定義 例題10─1 "ex1"
#日本語定義 うるう年である "1"
#日本語定義 うるう年ではない "0"
#日本語定義 がうるう年である "== 1"
#日本語定義 剰余計算 "%%"
#日本語定義 が割り切れる "== 0"
#日本語定義 ならば " "
仲間の集まり 例題10─1{
全域で使用可 一つの実体だけ 型なし はじまり( 文字列の仲間 引数[] )
{
整数の仲間 年のデータ = 文字列を整数に変換( 引数[0] ) ;
文字列の仲間 結果表示[] = {"うるう年ではない","うるう年である"};
表示する( "西暦" + 年のデータ.整数値 + "年は" + 結果表示[うるう年の判定( 年のデータ.整数値 )] );
}
一つの実体だけ 整数型 うるう年の判定(整数型 その年)
{
もし ( ( その年 剰余計算 400)が割り切れる ) ならば { 戻る うるう年である;}
それ以外 もし ( ( その年 剰余計算 100)が割り切れる ) ならば { 戻る うるう年ではない;}
それ以外 もし ( ( その年 剰余計算 4)が割り切れる ) ならば { 戻る うるう年である;}
戻る うるう年ではない;
}
}
例10─1
Java言語では豊富なクラスライブラリーが提供されておりますので、それをどういうふうに使いこなしていくのかが、使う人の力量ということになるのではないでしょうか。 また、最近のJava処理系では「 整数の仲間 年のデータ = 対象作成 整数の仲間( 引数[0] )」と書くと、推奨されていないというメッセージが出るようになりました。 これは「整数の仲間 年のデータ = 文字列を整数に変換( 引数[0] )」というように書き換えないといけないようです。 これは次のようなJava言語のコードに展開されます。(注:実際にはstd_include.jjava中の「// クラス関係」という注釈文字列が残りますが、この部分は割愛しています)
// 西暦を入力し、その年がうるう年かどうかを判定する
class ex1{
public static void main( String 引数[]
)
{
Integer 年のデータ = Integer.valueOf( 引数[0] ) ;
String 結果表示[] = {"うるう年ではない","うるう年である"};
System.out.println( "西暦" + 年のデータ.intValue() + "年は" + 結果表示[うるう年の判定(
年のデータ.intValue() )] );
}
static int うるう年の判定(int その年)
{
if ( ( その年 % 400)== 0 ) { return 1;}
else if ( ( その年 % 100)== 0 ) { return 0;}
else if ( ( その年 % 4)== 0 ) { return 1;}
return 0;
}
}
例10─1を展開したもの
次は例10-1のプログラムを実行させ、西暦を2000年、2019年、2020年としたときの結果です。
次の例は、平成1年(西暦1989年)の1月1日が日曜日であったことを利用して、指定した日の曜日を求めるプログラムです。西暦と年月日を入力すると、曜日と元号を表示するプログラムです。 ただし、1989年は平成元年ではありますが昭和の最後の週の年でもありますので、元号は「昭和64年/平成元年」としています。また、2019年の元号は「平成31年/令和元年」としています。 なお、1989年より小さい西暦年や2099年より大きい西暦年を入力するとプログラムは終了するようにもしています。
西暦から直接曜日を求める公式は世の中にあるようですが、今回はそれとは違ったアルゴリズムを用いております。まず1年365日は7で割った余りを求めると1になります。つまり、うるう年がなければ1年たつと曜日が1日ずれることになります。さらに、各月についても、うるう年がなければ毎月それぞれ規則的にずれます。このうるう年のずれについては、また別に計算して最後にすべての補正値を合計します。そして、この補正値の合計を7で割った余りを求めれば、指定した年月日の曜日が求められます。
年の補正値は、毎年1を足すだけで求められますが、月の補正値は表を用いております。しかし、うるう年の計算だけは、平成12年が西暦2000年という特殊な年ですので、毎年うるう年かどうかの判定を行い補正値を加算させました。
今回は、仲間の集まり(クラス)をいくつか分けて作成することにしました。また、宣言されているクラス内からだけアクセスすることができる仲間内で使用可(private)というアクセス修飾子を使ってデータのカプセル化を行っております。
また、パッケージ宣言というものを使用して、いくつかの独立したクラスファイルを同じディレクトリ内にまとめるようにします。パッケージ名は、「ex2」としました。まず「ex2」というディレクトリを作成して、その中に以下の日本語Javaプログラムである「ex2.jjava」を書き込みます。コンパイルは以下のように
>jjava ex2\ex2
と入力するとコンパイルできます。
//1989年(平成元年)1月1日が日曜日であったことを利用して、指定した日の曜日を求める
#日本語定義 例題10─2 "ex2"
#日本語定義 年のデータ "y_val"
#日本語定義 月のデータ "m_val"
#日本語定義 日のデータ "d_val"
#日本語定義 ならば " "
#日本語定義 の個数が正常 ".length == 3"
#日本語定義 年月日が正常範囲である
#日本語定義 曜日の表示データ
#日本語定義 例題10─2のファイルをまとめる "package ex2"
例題10─2のファイルをまとめる;
仲間の集まり 例題10─2{
全域で使用可 一つの実体だけ 型なし はじまり( 文字列の仲間[] 引数
) {
もし ( 引数の個数が正常 )
ならば {
整数の仲間 年のデータ = 文字列を整数に変換( 引数[0] ) ;
整数の仲間 月のデータ = 文字列を整数に変換( 引数[1] ) ;
整数の仲間 日のデータ = 文字列を整数に変換( 引数[2] ) ;
うるう年計算の仲間 うるうの介 = 対象作成 うるう年計算の仲間();
もし ( うるうの介.年月日が正常範囲である( 年のデータ.整数値, 月のデータ.整数値, 日のデータ.整数値 ) )
ならば {
表示する( "西暦" +年のデータ.整数値 + "年" + 月のデータ.整数値 + "月" + 日のデータ.整数値 + "日は" );
日数計算の仲間 日数太郎 = 対象作成 日数計算の仲間();
整数型 合計補正日数 =
日数太郎.補正日数を求める( 年のデータ.整数値, 月のデータ.整数値,日のデータ.整数値 );
曜日の仲間 曜日の丸= 対象作成 曜日の仲間();
表示する( 曜日の丸.曜日の表示データ(合計補正日数 剰余計算 7 ) + "曜日です" );
もし ( 平成元年である ) ならば {
表示する( "また" + 年のデータ.整数値 + "年は" + "昭和64年/平成元年です");
}
それ以外 もし ( 平成である ) ならば {
表示する( "また" + 年のデータ.整数値 + "年は" + "平成" + (年のデータ - 1988) + "年です");
}
それ以外 もし ( 令和元年である ) ならば {
表示する( "また" + 年のデータ.整数値 + "年は" + "平成31年/令和元年です");
}
それ以外 ならば {
表示する( "また" + 年のデータ.整数値 + "年は" + "令和" + (年のデータ - 2018) + "年です");
}
}
}
}
}
#日本語定義 うるう年計算の仲間 "ex2$urutoshi"
#日本語定義 うるう年である "true"
#日本語定義 うるう年ではない "false"
#日本語定義 がうるう年である "== true"
#日本語定義 剰余計算 "%%"
#日本語定義 が割り切れる "== 0"
#日本語定義 が割り切れない "!= 0"
#日本語定義 年が正常範囲 "((1989 <= y_val)&&(y_val <= 2099))"
#日本語定義 月が正常範囲 "((1 <= m_val)&&(m_val <= 12))"
#日本語定義 平成元年である "(y_val == 1989)"
#日本語定義 平成である "((1989 < y_val)&&(y_val < 2019))"
#日本語定義 令和元年である "(y_val == 2019)"
仲間の集まり うるう年計算の仲間 {
仲間内で使用可
整数型 補正日数 = 0;
整数型 月の最大日数[] = { 31, 28, 31, 30, 31,
30, 31, 31, 30, 31, 30, 31 };
全域で使用可
論理型 うるう年の判定(整数型 その年) {
もし ( ( (その年 剰余計算 4)が割り切れる ) かつ
( (その年 剰余計算 100)が割り切れない) または
( (その年 剰余計算 400)が割り切れる ) )
ならば { 戻る うるう年である; }
それ以外 ならば 戻る うるう年ではない;
}
整数型 うるう年の補正( 整数型 年のデータ, 整数型 月のデータ ) {
整数型 補正日数= 0;
もし ( ( うるう年の判定( 年のデータ ) がうるう年である ) かつ ( 月のデータ <= 2 ) )
ならば 補正日数 = -1;
反復 ( 整数型 その年 = 1989; その年 <= ( 年のデータ ); ++その年 ) {
もし ( うるう年の判定( その年 ) がうるう年である ) ならば ++補正日数;
}
戻る(補正日数);
}
論理型 年月日が正常範囲である( 整数型 年のデータ, 整数型
月のデータ, 整数型 日のデータ ) {
もし ( 年が正常範囲 かつ 月が正常範囲 かつ ( 1 <= 日のデータ ) )
ならば {
もし ( ( 日のデータ <= 29 ) かつ ( 月のデータ == 2 ) かつ うるう年の判定( 年のデータ ) )
ならば { 戻る 真; }
それ以外 もし ( 日のデータ <= 月の最大日数[月のデータ-1] )
ならば { 戻る 真; }
}
戻る 偽;
}
}
#日本語定義 曜日の仲間 "ex2$youbi"
仲間の集まり 曜日の仲間 {
仲間内で使用可
文字列の仲間 七つの曜日[] =
{"日","月","火","水","木","金","土",};
全域で使用可
文字列の仲間 曜日の表示データ(整数型 その日) {
戻る 七つの曜日[その日];
}
}
#日本語定義 日数計算の仲間 "ex2$7_youbi"
仲間の集まり 日数計算の仲間 {
仲間内で使用可
整数型 月の補正日数[] = { 0, 3, 3, 6, 1, 4, 6,
2, 5, 0, 3, 5 };
整数型 合計補正日数;
全域で使用可
整数型 補正日数を求める( 整数型 その年, 整数型 その月, 整数型
その日 ) {
うるう年計算の仲間 うるうの介 = 対象作成 うるう年計算の仲間();
合計補正日数 = (その年 - 1989) + 月の補正日数[その月-1]
+ その日 - 1 + うるうの介.うるう年の補正(その年,その月);
戻る 合計補正日数;
}
}
例10─2
例10─2では、少し入力のチェックにもこだわってみました。引数の数が違ったり、年、月、日が範囲外のものを入力しても計算は行われません。しかし、数字以外のものを入力すると、システムからエラーメッセージが返されますが、これは「try」、「catch」、「throw」という例外処理によりプログラム側で解決もできますが、今回は割愛させていただきます。これは次のようなJava言語のコードに展開されます。
//1989年(平成元年)1月1日が日曜日であったことを利用して、指定した日の曜日を求める
package ex2;
class ex2{
public static void main( String[] 引数 ) {
if ( 引数.length == 3 )
{
Integer y_val = Integer.valueOf( 引数[0] ) ;
Integer m_val = Integer.valueOf( 引数[1] ) ;
Integer d_val = Integer.valueOf( 引数[2] ) ;
ex2$urutoshi うるうの介 = new ex2$urutoshi();
if ( うるうの介.jp_str_0( y_val.intValue(), m_val.intValue(), d_val.intValue() ) )
{
System.out.println( "西暦" +y_val.intValue() + "年" + m_val.intValue() + "月" +
d_val.intValue() + "日は" );
ex2$7_youbi 日数太郎 = new ex2$7_youbi();
int 合計補正日数 =
日数太郎.補正日数を求める( y_val.intValue(), m_val.intValue(),d_val.intValue() );
ex2$youbi 曜日の丸= new ex2$youbi();
System.out.println( 曜日の丸.jp_str_1(合計補正日数 % 7 ) + "曜日です" );
if ( (y_val == 1989) ) {
System.out.println( "また" + y_val.intValue() + "年は" + "昭和64年/平成元年です");
}
else if ( ((1989 < y_val)&&(y_val < 2019)) ) {
System.out.println( "また" + y_val.intValue() + "年は" + "平成" + (y_val - 1988) +
"年です");
}
else if ( (y_val == 2019) ) {
System.out.println( "また" + y_val.intValue() + "年は" + "平成31年/令和元年です");
}
else {
System.out.println( "また" + y_val.intValue() + "年は" + "令和" + (y_val - 2018) +
"年です");
}
}
}
}
}
class ex2$urutoshi {
private
int 補正日数 = 0;
int 月の最大日数[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public
boolean うるう年の判定(int その年) {
if ( ( (その年 % 4)== 0 ) &&
( (その年 % 100)!= 0) ||
( (その年 % 400)== 0 ) )
{ return true; }
else return false;
}
int うるう年の補正( int y_val, int m_val ) {
int 補正日数= 0;
if ( ( うるう年の判定( y_val ) == true ) && ( m_val <= 2 ) )
補正日数 = -1;
for ( int その年 = 1989; その年 <= ( y_val ); ++その年 ) {
if ( うるう年の判定( その年 ) == true ) ++補正日数;
}
return(補正日数);
}
boolean jp_str_0( int y_val, int m_val, int d_val ) {
if ( ((1989 <= y_val)&&(y_val <= 2099)) && ((1 <= m_val)&&(m_val <= 12)) && ( 1
<= d_val ) )
{
if ( ( d_val <= 29 ) && ( m_val == 2 ) && うるう年の判定( y_val ) )
{ return true; }
else if ( d_val <= 月の最大日数[m_val-1] )
{ return true; }
}
return false;
}
}
class ex2$youbi {
private
String 七つの曜日[] = {"日","月","火","水","木","金","土",};
public
String jp_str_1(int その日) {
return 七つの曜日[その日];
}
}
class ex2$7_youbi {
private
int 月の補正日数[] = { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 };
int 合計補正日数;
public
int 補正日数を求める( int その年, int その月, int その日 ) {
ex2$urutoshi うるうの介 = new ex2$urutoshi();
合計補正日数 = (その年 - 1989) + 月の補正日数[その月-1]
+ その日 - 1 + うるうの介.うるう年の補正(その年,その月);
return 合計補正日数;
}
}
例10─2を展開したもの
例10─2のプログラムで平成1年1月8日、平成12年(西暦2000年)2月29日、平成18年(西暦2006年)2月3日、さらに天皇陛下の御退位により、 平成最後の日となる平成31年(西暦2019年)4月30日、令和2年(西暦2020年)6月15日としたときの実行結果です。
パッケージ内にまとめられたプログラムの実行は、以下のように「パッケージ名.プログラム名」で実行できます。
次に例10-3として、現在の時間を読み出して、それを江戸時代の時間の読み方である「刻」として表示するプログラムを示します。これはC言語編での例題から日本語プログラムを参考にして作ってみました。
また、このプログラムの実行結果をフレームといういわゆるGUI(グラフィック・ユーザー・インターフェース)の部品を利用して表示をしてみました。
// 現在の刻を表示する
窓処理の仲間を呼ぶ;
出来事処理の仲間を呼ぶ;
いろいろと使える仲間を呼ぶ;
#日本語定義 例題10─3 "ex3"
#日本語定義 題名を設定する "setTitle"
#日本語定義 大きさを設定する "setSize"
#日本語定義 可視かどうかを設定 "setVisible"
全域で使用可 仲間の集まり 例題10─3 引き継ぎ 窓枠の仲間 {
全域で使用可 一つの実体だけ 型なし はじまり( 文字列の仲間 引数[]
) {
窓枠の仲間 窓際族 = 対象作成 例題10─3();
窓際族.題名を設定する("今の刻を表示する");
窓際族.大きさを設定する(600,200);
窓際族.可視かどうかを設定( 真 );
}
例題10─3(){ 窓枠ご用聞きの追加( 対象作成 派遣くん()); }
仲間の集まり 派遣くん 引き継ぎ 窓枠を適応させる仲間 {
全域で使用可 型なし 窓枠を閉じる { 終了する; }
}
#日本語定義 領域に描画する "paint"
#日本語定義 傾斜太文字 "Font.ITALIC|Font.BOLD"
#日本語定義 青色 "Color.blue"
#日本語定義 文字を描く "drawString"
#日本語定義 字体を設定する "setFont"
#日本語定義 色を設定する "setColor"
全域で使用可 型なし 領域に描画する( 図画の仲間 絵なりくん ) {
文字列の仲間 文字列零 = "今の刻は";
文字列の仲間 文字列一 = "子刻(ねのこく)です。";
文字列の仲間 文字列二 = "丑刻(うしのこく)です。";
文字列の仲間 文字列三 = "寅刻(とらのこく)です。";
文字列の仲間 文字列四 = "卯刻(うのこく)です。";
文字列の仲間 文字列五 = "辰刻(たつのこく)です。";
文字列の仲間 文字列六 = "巳刻(みのこく)です。";
文字列の仲間 文字列七 = "午刻(うまのこく)です。";
文字列の仲間 文字列八 = "未刻(ひつじのこく)です。";
文字列の仲間 文字列九 = "申刻(さるのこく)です。";
文字列の仲間 文字列十 = "酉刻(とりのこく)です。";
文字列の仲間 文字列十一 = "戌刻(いぬのこく)です。";
文字列の仲間 文字列十二 = "亥刻(いのこく)です。¥n";
字体の仲間 文字蔵さん = 対象作成 字体の仲間( "Serif", 傾斜太文字, 30 );
絵なりくん.字体を設定する( 文字蔵さん );
絵なりくん.色を設定する( 青色 );
絵なりくん.文字を描く( 文字列零, 220, 100 );
現在の時刻を取り出す;
振り分け( 現在時刻 / 2 ) {
場合分け 子刻: { 絵なりくん.文字を描く(文字列一, 120,150); }; 振り分け終了;
場合分け 丑刻: { 絵なりくん.文字を描く(文字列二, 120,150); }; 振り分け終了;
場合分け 寅刻: { 絵なりくん.文字を描く(文字列三, 120,150); }; 振り分け終了;
場合分け 卯刻: { 絵なりくん.文字を描く(文字列四, 120,150); }; 振り分け終了;
場合分け 辰刻: { 絵なりくん.文字を描く(文字列五, 120,150); }; 振り分け終了;
場合分け 巳刻: { 絵なりくん.文字を描く(文字列六, 120,150); }; 振り分け終了;
場合分け 午刻: { 絵なりくん.文字を描く(文字列七, 120,150); }; 振り分け終了;
場合分け 未刻: { 絵なりくん.文字を描く(文字列八, 120,150); }; 振り分け終了;
場合分け 申刻: { 絵なりくん.文字を描く(文字列九, 120,150); }; 振り分け終了;
場合分け 酉刻: { 絵なりくん.文字を描く(文字列十, 120,150); }; 振り分け終了;
場合分け 戌刻: { 絵なりくん.文字を描く(文字列十一,120,150); }; 振り分け終了;
場合分け 亥刻: { 絵なりくん.文字を描く(文字列十二,120,150); }; 振り分け終了;
}
}
}
#日本語定義 現在の時刻を取り出す "Calendar rightNow = Calendar.getInstance()"
#日本語定義 現在時刻 "rightNow.get(rightNow.HOUR_OF_DAY)"
#日本語定義 子刻 "0"
#日本語定義 丑刻 "1"
#日本語定義 寅刻 "2"
#日本語定義 卯刻 "3"
#日本語定義 辰刻 "4"
#日本語定義 巳刻 "5"
#日本語定義 午刻 "6"
#日本語定義 未刻 "7"
#日本語定義 申刻 "8"
#日本語定義 酉刻 "9"
#日本語定義 戌刻 "10"
#日本語定義 亥刻 "11"
#日本語定義 文字列零
#日本語定義 文字列一
#日本語定義 文字列二
#日本語定義 文字列三
#日本語定義 文字列四
#日本語定義 文字列五
#日本語定義 文字列六
#日本語定義 文字列七
#日本語定義 文字列八
#日本語定義 文字列九
#日本語定義 文字列十
#日本語定義 文字列十一
#日本語定義 文字列十二
例10─3
細かい文法的なところはJava言語関係の資料を見ていただければ分かると思いますが、Javaではおびただしい量のクラスライブラリーがメーカーから供給されています。これがすべて英語表記であり、それぞれのクラスで使用されている単語を見ても、とてもよく似た語句を使ってあるものがいくつも見受けられます。ここでうまく日本語定義を用いることで、混乱しやすい部分をプログラマーが後で見てもすぐに思い出すことができるようにする効果もあるのではないかと考えております。これは次のようなJava言語のコードに展開されます。
// 現在の刻を表示する
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class ex3 extends Frame {
public static void main( String 引数[]
) {
Frame 窓際族 = new ex3();
窓際族.setTitle("今の刻を表示する");
窓際族.setSize(600,200);
窓際族.setVisible( true );
}
ex3(){ addWindowListener( new
派遣くん()); }
class 派遣くん extends WindowAdapter {
public void windowClosing( WindowEvent win_evnt ) { System.exit(0); }
}
public void paint( Graphics 絵なりくん ) {
String jp_str_0 = "今の刻は";
String jp_str_1 = "子刻(ねのこく)です。";
String jp_str_2 = "丑刻(うしのこく)です。";
String jp_str_3 = "寅刻(とらのこく)です。";
String jp_str_4 = "卯刻(うのこく)です。";
String jp_str_5 = "辰刻(たつのこく)です。";
String jp_str_6 = "巳刻(みのこく)です。";
String jp_str_7 = "午刻(うまのこく)です。";
String jp_str_8 = "未刻(ひつじのこく)です。";
String jp_str_9 = "申刻(さるのこく)です。";
String jp_str_10 = "酉刻(とりのこく)です。";
String jp_str_11 = "戌刻(いぬのこく)です。";
String jp_str_12 = "亥刻(いのこく)です。¥n";
Font 文字蔵さん = new Font( "Serif", Font.ITALIC|Font.BOLD, 30 );
絵なりくん.setFont( 文字蔵さん );
絵なりくん.setColor( Color.blue );
絵なりくん.drawString( jp_str_0, 220, 100 );
Calendar rightNow = Calendar.getInstance();
switch( rightNow.get(rightNow.HOUR_OF_DAY) / 2 ) {
case 0: { 絵なりくん.drawString(jp_str_1, 120,150); }; break;
case 1: { 絵なりくん.drawString(jp_str_2, 120,150); }; break;
case 2: { 絵なりくん.drawString(jp_str_3, 120,150); }; break;
case 3: { 絵なりくん.drawString(jp_str_4, 120,150); }; break;
case 4: { 絵なりくん.drawString(jp_str_5, 120,150); }; break;
case 5: { 絵なりくん.drawString(jp_str_6, 120,150); }; break;
case 6: { 絵なりくん.drawString(jp_str_7, 120,150); }; break;
case 7: { 絵なりくん.drawString(jp_str_8, 120,150); }; break;
case 8: { 絵なりくん.drawString(jp_str_9, 120,150); }; break;
case 9: { 絵なりくん.drawString(jp_str_10, 120,150); }; break;
case 10: { 絵なりくん.drawString(jp_str_11,120,150); }; break;
case 11: { 絵なりくん.drawString(jp_str_12,120,150); }; break;
}
}
}
例10─3を展開したもの
このように日本語カスタマイザーの自動変数定義と、Java言語で変数名を直接日本語で記述できる部分を併用してみましたが、何ら問題なく使用できます。 例10─3のプログラムを実行させたときの結果は以下のようになります。(これは午前5時ごろに実行しました)
次の例題は、簡単なメモ紙を作ってみました。これはファイルを読み込むことも、保存することもできません。ただデスクトップに表示しておくだけのものですが、Windows10上ではマウスの右クリックの機能を使い、ほかのワープロやインターネットブラウザーなどから文書をコピーしてこのメモ紙に貼り付けることもできます。
// 簡単なテキスト編集ができるメモ紙を作る
窓処理の仲間を呼ぶ;
出来事処理の仲間を呼ぶ;
データ転送の仲間を呼ぶ;
#日本語定義 例題10─4 "ex4"
全域で使用可 仲間の集まり 例題10─4 引き継ぎ 窓枠の仲間
実装 動作に対するご用聞き
{
文書領域の仲間 文書小僧 = 対象作成 文書領域の仲間();
全域で使用可 一つの実体だけ 型なし はじまり( 文字列の仲間 引数[] )
{
窓枠の仲間 窓際族 = 対象作成 例題10─4();
窓際族.題名を設定する( "簡単なメモ紙" );
窓際族.大きさを設定する( 600, 400 );
窓際族.窓枠を表示する;
}
例題10─4(){
字体を設定する( 対象作成 字体の仲間( 字体名, 字体の種類, 字体の大きさ1 ) );
メニュー欄の仲間 欄丸 = 対象作成 メニュー欄の仲間();
メニュー中項目の仲間 中太 = 対象作成 メニュー中項目の仲間("ファイル");
メニュー小項目の仲間 小太 = 対象作成 メニュー小項目の仲間( "終 了" );
小太.動作ご用聞きの追加( ここ );
中太.項目を追加する( 小太 );
欄丸.項目を追加する(中太);
メニュー欄を作成する( 欄丸 );
文書小僧.字体を設定する( 対象作成 字体の仲間( 字体名, 字体の種類, 字体の大きさ2 ) );
窓枠に追加する( 文書小僧 );
窓枠ご用聞きの追加( 対象作成 派遣くん() );
}
仲間の集まり 派遣くん 引き継ぎ 窓枠を適応させる仲間 {
全域で使用可 型なし 窓枠を閉じる { 終了する; }
}
全域で使用可 型なし 動作が実行されたとき( 動作に伴うでき事の仲間 起こった蔵 ){
もし ( 起こった蔵.実行された命令を取り出す() == "終 了" ) 終了する;
}
}
#日本語定義 題名を設定する "setTitle"
#日本語定義 大きさを設定する "setSize"
#日本語定義 窓枠を表示する "setVisible(true)"
#日本語定義 窓枠に追加する "add"
#日本語定義 字体を設定する "setFont"
#日本語定義 項目を追加する "add"
#日本語定義 ここ "this"
#日本語定義 が等しい ".equals"
#日本語定義 ならば " "
#日本語定義 メニュー欄を作成する "setMenuBar"
#日本語定義 実行された命令を取り出す "getActionCommand"
#日本語定義 字体名 "\"serif\""
#日本語定義 字体の大きさ1 "12"
#日本語定義 字体の大きさ2 "18"
#日本語定義 字体の種類 "Font.PLAIN"
例10─4
これも文法的な細かいところは関係資料を見ていただければ分かると思いますが、コードの量としては、非常に少なく書くことができました。しかし、字数によって自動的にスクロールもできるようになりますので、かなり本格的な機能は持っているようです。デスクトップ上にちょっとしたメモ紙として置いておくこともできると思います。これは次のようなJava言語のコードに展開されます。
// 簡単なテキスト編集ができるメモ紙を作る
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
public class ex4 extends Frame
implements ActionListener
{
TextArea 文書小僧 = new TextArea();
public static void main( String 引数[]
)
{
Frame 窓際族 = new ex4();
窓際族.setTitle( "簡単なメモ紙" );
窓際族.setSize( 600, 400 );
窓際族.setVisible(true);
}
ex4(){
setFont( new Font( "serif", Font.PLAIN, 12 ) );
MenuBar 欄丸 = new MenuBar();
Menu 中太 = new Menu("ファイル");
MenuItem 小太 = new MenuItem( "終 了" );
小太.addActionListener( this );
中太.add( 小太 );
欄丸.add(中太);
setMenuBar( 欄丸 );
文書小僧.setFont( new Font( "serif", Font.PLAIN, 18 ) );
add( 文書小僧 );
addWindowListener( new 派遣くん() );
}
class 派遣くん extends WindowAdapter {
public void windowClosing( WindowEvent win_evnt ) { System.exit(0); }
}
public void actionPerformed(
ActionEvent 起こった蔵 ){
if ( 起こった蔵.getActionCommand() == "終 了" ) System.exit(0);
}
}
例U10─4を展開したもの
例U10─4のプログラムを実行させたときの結果です。
ウィンドウの右上隅にある終了ボタンをクリックしても終了できますが、メニューバーの「ファイル」をマウスでクリックすると「終了」という項目が表示されますので、これを選択して終了することもできます。
次の例題は二次元の図形を描画するプログラムです。今回は縁起をかついで三段飾りもちを描いてみます。 これもWindows版Java言語編の例題から日本語プログラムをほぼそのまま持ってきました。
// 三段飾り餅を描く
窓処理の仲間を呼ぶ;
出来事処理の仲間を呼ぶ;
図形描画の仲間を呼ぶ;
#日本語定義 例題10─5 "ex5"
#日本語定義 題名を設定する "setTitle"
#日本語定義 大きさを設定する "setSize"
#日本語定義 背景色を設定する "setBackground"
#日本語定義 窓枠を表示する "setVisible(true)"
#日本語定義 領域に描画する "paint"
#日本語定義 楕円形を描画する "Ellipse2D.Float"
#日本語定義 矩形を描画する "Rectangle2D.Float"
#日本語定義 属性を設定する "setPaint"
#日本語定義 塗りつぶす "fill"
全域で使用可 仲間の集まり 例題10─5 引き継ぎ 窓枠の仲間{
全域で使用可 一つの実体だけ 型なし はじまり( 文字列の仲間 引数[]
) {
窓枠の仲間 窓際族 = 対象作成 例題10─5();
窓際族.題名を設定する("三段飾りもち");
窓際族.大きさを設定する(500,400);
窓際族.背景色を設定する(肌色);
窓際族.窓枠を表示する;
}
例題10─5(){ 窓枠ご用聞きの追加( 対象作成 派遣くん()); }
仲間の集まり 派遣くん 引き継ぎ 窓枠を適応させる仲間 {
全域で使用可 型なし 窓枠を閉じる { 終了する; }
}
全域で使用可 型なし 領域に描画する( 図画の仲間 絵なりくん ) {
二次元図画の仲間 絵美ちゃん = ( 二次元図画の仲間 ) 絵なりくん;
絵美ちゃん.属性を設定する(紅色);
絵美ちゃん.塗りつぶす(対象作成 楕円形を描画する(150,160,200,50));
絵美ちゃん.属性を設定する(灰白色);
絵美ちゃん.塗りつぶす(対象作成 楕円形を描画する(175,110,150,50));
絵美ちゃん.属性を設定する(草色);
絵美ちゃん.塗りつぶす(対象作成 楕円形を描画する(200,60,100,50));
絵美ちゃん.属性を設定する(茶色);
絵美ちゃん.塗りつぶす(対象作成 矩形を描画する(150,200,200,20));
絵美ちゃん.塗りつぶす(対象作成 矩形を描画する(200,220,100,100));
絵美ちゃん.属性を設定する(肌色);
絵美ちゃん.塗りつぶす(対象作成 楕円形を描画する(225,225,50,50));
}
}
#日本語定義 肌色 "new Color(210,202,68)"
#日本語定義 茶色 "new Color(186,125,50)"
#日本語定義 紅色 "new Color(55,94,55)"
#日本語定義 灰白色 "new Color(184,213,184)"
#日本語定義 草色 "new Color(237,85,160)"
例10─5
複雑な色はRGB3色を0~255までの数値で指定します。これは次のようなJava言語のコードに展開されます。
// 三段飾り餅を描く
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class ex5 extends Frame{
public static void main( String jp_str_2[] ) {
Frame jp_str_0 = new ex5();
jp_str_0.setTitle("三段飾り餅");
jp_str_0.setSize(500,400);
jp_str_0.setBackground(new Color(210,202,68));
jp_str_0.setVisible(true);
}
ex5(){ addWindowListener( new jp_str_1()); }
class jp_str_1 extends WindowAdapter {
public void windowClosing( WindowEvent win_evnt ) { System.exit(0); }
}
public void paint( Graphics jp_str_3 ) {
Graphics2D jp_str_4 = ( Graphics2D ) jp_str_3;
jp_str_4.setPaint(new Color(55,94,55));
jp_str_4.fill(new Ellipse2D.Float(150,160,200,50));
jp_str_4.setPaint(new Color(184,213,184));
jp_str_4.fill(new Ellipse2D.Float(175,110,150,50));
jp_str_4.setPaint(new Color(237,85,160));
jp_str_4.fill(new Ellipse2D.Float(200,60,100,50));
jp_str_4.setPaint(new Color(186,125,50));
jp_str_4.fill(new Rectangle2D.Float(150,200,200,20));
jp_str_4.fill(new Rectangle2D.Float(200,220,100,100));
jp_str_4.setPaint(new Color(210,202,68));
jp_str_4.fill(new Ellipse2D.Float(225,225,50,50));
}
}
例10─5を展開したもの
例10─5のプログラムを実行させたときの結果です。
π
の計算
次の例題はC言語編、C++言語編でもやりましたが、任意の桁数、円周率π
を求めるプログラムをJava版として移植してみました。これも日本語ベースでコードの移植を行いましたので、かなり
短時間でスムーズにできたのではないかと感じました。
プログラムはC言語編やC++言語編と同様に二つに分かれており、メインの部分はこの例題10─6です。また、もう一つのクラスファイルは
実際に長いπ
を求めるための詳細な計算部分です。それぞれ別々のクラスファイルとして翻訳(コンパイル)しておきます。
今回も長いπ
を計算をする詳細なクラスファイルについては掲載は差し控えておりますが、興味のある方はC言語編の参考資料として掲げております書籍を見ていただければ分かると思います。また、結果の表示については例題10─4の簡単なメモ紙に表示するようにし
ました。
// マチンの公式を使用して、任意の桁数πの値を計算するプログラム
窓処理の仲間を呼ぶ;
出来事処理の仲間を呼ぶ;
データ転送の仲間を呼ぶ;
#日本語定義 例題10─6 "ex6"
全域で使用可 仲間の集まり 例題10─6 引き継ぎ 窓枠の仲間
実装 動作に対するご用聞き
{
文書領域の仲間 文書小僧 = 対象作成 文書領域の仲間();
全域で使用可 一つの実体だけ 型なし はじまり( 文字列の仲間 引数[]
)
{
窓枠の仲間 窓際族 = 対象作成 例題10─6();
窓際族.題名を設定する( "πを2万桁求める" );
窓際族.大きさを設定する( 600, 400 );
窓際族.窓枠を表示する;
}
例題10─6(){
字体を設定する( 対象作成 字体の仲間( 字体名, 字体の種類, 字体の大きさ ) );
メニュー欄の仲間 欄丸 = 対象作成 メニュー欄の仲間();
メニュー中項目の仲間 中太 = 対象作成 メニュー中項目の仲間("ファイル");
メニュー小項目の仲間 小太 = 対象作成 メニュー小項目の仲間( "終 了" );
小太.動作ご用聞きの追加( ここ );
中太.項目を追加する( 小太 );
欄丸.項目を追加する(中太);
メニュー欄を作成する( 欄丸 );
文書小僧.字体を設定する( 対象作成 字体の仲間( 字体名, 字体の種類, 字体の大きさ ) );
窓枠に追加する( 文書小僧 );
窓枠ご用聞きの追加( 対象作成 派遣くん() );
整数型[] 作業用配列一 = 対象作成 整数型[配列の最大値+1];
整数型[] 作業用配列二 = 対象作成 整数型[配列の最大値+1];
整数型[] πの結果 = 対象作成 整数型[配列の最大値+1];
長いπを求める仲間 長いπ = 対象作成 長いπを求める仲間();
長いπ.マチンの逆正接演算( 作業用配列一, 16, 5 );
長いπ.マチンの逆正接演算( 作業用配列二, 4, 239 );
長いπ.長い配列の減算( πの結果, 作業用配列一, 作業用配列二 );
文字列の仲間 表示用文字 = 対象作成 文字列の仲間();
文書小僧.文字を追加する( 表示用文字.値を変換する(πの結果[0]) );
文書小僧.文字を追加する(".\n");
反復 ( 整数型 反復数 = 1; 反復数 <= 求める桁数; 反復数++ ) {
文書小僧.文字を追加する( 表示用文字.値を変換する(πの結果[反復数]) );
もし ( 反復数 剰余計算 10 == 0 ) 文書小僧.文字を追加する(" ");
もし ( 反復数 剰余計算 50 == 0 ) 文書小僧.文字を追加する("\n");
}
}
仲間の集まり 派遣くん 引き継ぎ 窓枠を適応させる仲間 {
全域で使用可 型なし 窓枠を閉じる { 終了する; }
}
全域で使用可 型なし 動作が実行されたとき( 動作に伴うでき事の仲間
起こった蔵 ){
もし ( 起こった蔵.実行された命令を取り出す() == "終 了" ) 終了する;
}
}
#日本語定義 長いπを求める仲間 "lng_pi"
#日本語定義 マチンの逆正接演算 "machins_arctan"
#日本語定義 長い配列の減算 "lng_dim_sub"
#日本語定義 配列の最大値 "20010"
#日本語定義 求める桁数 "20000"
#日本語定義 剰余計算 "%%"
#日本語定義 題名を設定する "setTitle"
#日本語定義 大きさを設定する "setSize"
#日本語定義 窓枠を表示する "setVisible(true)"
#日本語定義 窓枠に追加する "add"
#日本語定義 字体を設定する "setFont"
#日本語定義 項目を追加する "add"
#日本語定義 文字を追加する "append"
#日本語定義 値を変換する "valueOf"
#日本語定義 ここ "this"
#日本語定義 が等しい ".equals"
#日本語定義 ならば " "
#日本語定義 メニュー欄を作成する "setMenuBar"
#日本語定義 実行された命令を取り出す "getActionCommand"
#日本語定義 字体名 "\"serif\""
#日本語定義 字体の大きさ "14"
#日本語定義 字体の種類 "Font.PLAIN"
例10─6
これを展開すると、次のようなJava言語のコードになります。
// マチンの公式を使用して、任意の桁数πの値を計算するプログラム
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
public class ex6 extends Frame
implements ActionListener
{
TextArea 文書小僧 = new TextArea();
public static void main( String 引数[]
)
{
Frame 窓際族 = new ex6();
窓際族.setTitle( "πを2万桁求める" );
窓際族.setSize( 600, 400 );
窓際族.setVisible(true);
}
ex6(){
setFont( new Font( "serif", Font.PLAIN, 14 ) );
MenuBar 欄丸 = new MenuBar();
Menu 中太 = new Menu("ファイル");
MenuItem 小太 = new MenuItem( "終 了" );
小太.addActionListener( this );
中太.add( 小太 );
欄丸.add(中太);
setMenuBar( 欄丸 );
文書小僧.setFont( new Font( "serif", Font.PLAIN, 14 ) );
add( 文書小僧 );
addWindowListener( new 派遣くん() );
int[] 作業用配列一 = new int[20010+1];
int[] 作業用配列二 = new int[20010+1];
int[] πの結果 = new int[20010+1];
lng_pi 長いπ = new lng_pi();
長いπ.machins_arctan( 作業用配列一, 16, 5 );
長いπ.machins_arctan( 作業用配列二, 4, 239 );
長いπ.lng_dim_sub( πの結果, 作業用配列一, 作業用配列二 );
String 表示用文字 = new String();
文書小僧.append( 表示用文字.valueOf(πの結果[0]) );
文書小僧.append(".\n");
for ( int for数 = 1; for数 <= 20000; for数++ ) {
文書小僧.append( 表示用文字.valueOf(πの結果[for数]) );
if ( for数 % 10 == 0 ) 文書小僧.append(" ");
if ( for数 % 50 == 0 ) 文書小僧.append("\n");
}
}
class 派遣くん extends WindowAdapter {
public void windowClosing( WindowEvent win_evnt ) { System.exit(0); }
}
public void actionPerformed(
ActionEvent 起こった蔵 ){
if ( 起こった蔵.getActionCommand() == "終 了" ) System.exit(0);
}
}
例10─6を展開したもの
円周率を小数点以下2万桁として、例10─6のプログラムを実行させたときの最初の部分と最後の部分です。
今回のJava処理系(コンパイラ)のバージョンでは変数名、関数名、クラス名などにそのまま日本語を使うことができました。 これ以降、プログラム言語の開発環境で日本語の利用が拡大していけば幸いですが、万が一将来的にバージョンが変わったら日本語が全く使えないという状況になった場合には、いざというときのために日本語カスタマイザーの自動変数定義はあってしかるべきだと考えています。
Java言語に限ったことはないのですが、日本語プログラムの例題中、オブジェクトの名前に「○○ちゃん」、「○○君」などという擬人化した名前を付けていることに対して、不快感を持つ人もあるかとは思いますが、決してふざけているというわけではありません。オブジェクトの設計図ともいうべきクラスに対して、記憶領域としての実体を持っているオブジェクトにメッセージを送るという考え方が、今日ではプログラミング言語として広く認知されてきているのではないかと思います。一方、20年以上も前からオブェジェクトの次のパラダイムとして、エージェントという考え方がプログラミングの世界でも提唱されてきました。
つまり、現在のオブジェクトが「オブジェクト名.メソッド名」というような形式で、いわゆる以前の関数のような格好であらかじめ用意された機能を実行しているわけですが、将来的には「エージェント名.簡単な命令語」というように、より人間に近い働きをする「エージェント」というものに対して、簡単な命令語を与えてやるだけで、複雑なことをやってくれるようにという願いを込めて、擬人化した親しみやすい名前にしています。
将来的には、例えば「ネット検索君」というエージェントにサイトを検索させるときには「ネット検索君.サイト検索(検索語)」や「ネット検索君.画像検索(画像ファイル)」など、たとえ詳しい技術的なことは知らなくても、ワープロ感覚でプログラミングができるようになればいいなと考えています。
参考資料
James Gosling: on the Java Road ジェームズ・ゴースリン博士が公開しているブログページ
Java(TM) 2 SDK, Standard Edition Version 1.4.0 ドキュメント一式 サン・マイクロシステムズ社
Java2 中山茂著 技報堂出版 1999