JavaScript:カレンダーの作成

JavaScript で作成した超簡易カレンダーです。

“<”、“>”をクリックすると、月が変わります。

 

 

プログラムは以下のようになります。

calendar.htm

<html>
<body>
<div id="calendar"></div>
<script src="./calendar.js"></script>
<script>calendar("calendar")</script>
</body>
</html>
 

 

calendar.js

var $date = new Date();
var $year = $date.getFullYear();
var $month = $date.getMonth();

function calendar(id) {
  $id = id;
  var first = new Date($year, $month, 1);
  var last = new Date($year, $month + 1, 0);
  var first_day = first.getDay();
  var last_date = last.getDate();
  var flag = true;
  var counter = 1;
  var calendar = "<table border='1'>";
  calendar += "<caption>"
  calendar += "<strong onclick='decrease()'>&lt; </strong>"
  calendar += $year + "/" + ("00" + ($month + 1)).slice(-2)
  calendar += "<strong onclick='increase()'> &gt;</strong>"
  calendar += "</caption>";
  var week = ["日", "月", "火", "水", "木", "金", "土"];
  for (var j = 0; j < 7; j++) {
    calendar += "<th>" + week[j] + "</th>";
  }
  for (var i = 0; i < 6; i++) {
    calendar += "<tr align='center'>";
    for (var j = 0; j < 7; j++) {
      if (i == 0 && first_day == j) flag = false;
      if (counter > last_date) flag = true;
      calendar += "<td>";
      calendar += flag ? "&nbsp;" : counter++;
      calendar += "</td>";
    }
    calendar += "</tr>";
    if (counter > last_date) break;
  }
  calendar += "</table>";
  document.getElementById(id).innerHTML = calendar;
}

function decrease() {
  if ($month-- == 0) {
    $year--;
    $month = 11;
  }
  calendar($id);
}

function increase() {
  if ($month++ == 11) {
    $year++;
    $month = 0;
  }
  calendar($id);
}
 

 


参考サイト

 

JavaScript:オブジェクトのメソッドを onclick で呼び出す方法

オブジェクトのメソッドを onclick で呼び出す方法を紹介します。

“++”をクリックすると、数値が増加します。

 

プログラムは以下のようになります。

method_call_by_onclick.htm

<html>
<body>

<div id="index"></div>

<script>
var index1 = new Index(0);
var index2 = new Index(0);
var index3 = new Index(0);

function Index(index) {
  this.index = index;
  this.span2;
  this.increase = function () {
    this.span2.innerHTML = ++this.index;
  };

  var that = this;
  var create = function () {
    var div = document.createElement("div");
    document.getElementById("index").appendChild(div);

    var span1 = document.createElement("span");
    span1.onclick = function () {that.increase();};
    span1.innerHTML = "++";
    div.appendChild(span1);

    that.span2 = document.createElement("span");
    that.span2.innerHTML = that.index;
    div.appendChild(that.span2);
  };

  create();
}
</script>

</body>
</html>
 

 

ここからは、テスト用コードです。無視してください^^

 

function_call_by_onclick.htm(idの指定なし)

<html>
<body>

<script>
var $index = 0;
var $div = document.createElement("div");
document.body.appendChild($div);

function create() {
  var index = "";
  index += "<span onclick='increase()'>++</span>";
  index += "<span>" + $index + "</span>";
  $div.innerHTML = index;
}

function increase() {
  $index++;
  create();
}

create();
</script>

</body>
</html>
 

 

function_call_by_onclick.htm(idの指定あり)

<html>
<body>

<div id="index"></div>

<script>
var $index = 0;

function create(id) {
  $id = id;
  var index = "";
  index += "<span onclick='increase()'>++</span>";
  index += "<span>" + $index + "</span>";
  document.getElementById(id).innerHTML = index;
}

function increase() {
  $index++;
  create($id);
}
</script>

<script>
create("index");
</script>

</body>
</html>
 

 

test.htm

<html>
<body>
<script>
var index = new Index();
index.show();
function Index() {
  this.index;
  this.show = function () {
    document.write(this.index);
  };
  var that = this;
  var set = function () {
    that.index = 0;
  };
  set();
}
</script>
</body>
</html>
 

 


参考サイト

 

Java:フレームワークの自作

ここでは、抽象クラスとリフレクションの二通りの方法で超簡易フレームワークを作成する方法を紹介します。
家で例えるなら、フレームワークは骨組みの部分です。言い換えると、共通部分です。同じ骨組みでも内装や外装の異なる家を複数建てたい場合がありますよね。 そういう場合は、あらかじめ共通の骨組みを作っておいて、内装や外装を後からカスタマイズできるようにしておくと便利です。 フレームワークには、更に、発生したイベントに応じて、ユーザが登録した関数(コールバック関数)を呼び出すイベント駆動の機構が備わっています。
下記の例では、Frameworkクラスが骨組みで、Modelクラスが内装や外装に相当します。MVCモデルで言えば、Frameworkクラスがコントローラで、Modelクラスがモデル、標準入出力がビューに相当します。


1.抽象クラスを使ったフレームワーク

抽象クラスを使ったフレームワークはオーソドックスな方法ですが、弱点は、メソッド名やメソッド数がフレームワーク側で決まり、ユーザ側ではそれらを決定できないことです。 HttpServlet は抽象クラスを使って作られています。

 

D:\pkg\framework\Framework.java

package framework;

import java.util.Scanner;

public abstract class Framework {
  protected Framework() {
    Scanner scanner = new Scanner(System.in);
    while (true) {
      String event = scanner.nextLine();
      switch (event) {
        case "event1":
        handle1();
        break;

        case "event2":
        handle2();
        break;

        case "event3":
        handle3();
        break;

        default:
        System.err.println("exception");
      }
    }
  }

  protected abstract void handle1();
  protected abstract void handle2();
  protected abstract void handle3();
}
 

 

Frameworkクラスのコンパイル

D:\pkg\javac0.bat(ファイル名をjavac.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
javac D:/pkg/framework/*.java
 

 

次にユーザ側のプログラムです。Frameworkクラスを継承し、コールバック関数 handle1、handle2、handle3 を実装(登録)して Modelクラスを完成させます。

 

D:\src\model.java

import framework.Framework;

class Model extends Framework {
  protected void handle1() {
    System.out.println("action1");
  }

  protected void handle2() {
    System.out.println("action2");
  }

  protected void handle3() {
    System.out.println("action3");
  }
}
 

 

D:\src\main.java

class Main {
  public static void main(String... args) {
    new Model();
  }
}
 

 

ModelクラスとMainクラスのコンパイル

D:\src\javac0.bat(ファイル名をjavac.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
javac -cp D:/pkg *.java
 

 

Mainクラスの起動

D:\src\java0.bat(ファイル名をjava.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
java -cp .;D:/pkg Main
 



〈実行〉

event1[Enter]
action1
event2[Enter]
action2
event3[Enter]
action3


2.リフレクションを使ったフレームワーク

Javaのリフレクションは、実行時に、文字列(変数名や関数名)を通して、変数の読み書きや関数の呼び出しを行うための機能です。 この機能を使うと、switch文を使わずに、登録したメソッドをメソッド名(文字列)で呼び出すことができます。 リフレクションでフレームワークを作成すると、ユーザ側でメソッド名やメソッド数を自由に決めることができます。 Apache Struts はリフレクションを使って作られています。

 

D:\pkg\framework\Framework.java

package framework;

import java.lang.reflect.Method;
import java.util.Scanner;

public class Framework {
  public Framework() {
    Scanner scanner = new Scanner(System.in);
    while (true) {
      try {
        String event = scanner.nextLine();
        String stringClass = event.split(":", 0)[0];
        String stringMethod = event.split(":", 0)[1];
        Class<?> clazz = Class.forName(stringClass);
        Method method = clazz.getMethod(stringMethod);
        method.invoke(clazz.newInstance());
      }
      catch (ReflectiveOperationException e) {
        e.printStackTrace();
      }
      catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}
 


注)catch (Exception e) {} を外すと、捕捉できない例外が発生したときにループを抜けてしまいます。

次にユーザ側のプログラムです。メソッド名はユーザ側で自由に決めることができます。

 

D:\src\Model.java

public class Model {
  public void handle1() {
    System.out.println("action1");
  }

  public void handle2() {
    System.out.println("action2");
  }

  public void handle3() {
    System.out.println("action3");
  }
}
 

 

D:\src\main.java

import framework.Framework;

class Main {
  public static void main(String... args) {
    new Framework();
  }
}
 



コンパイルや実行は、抽象クラスの場合と同じです。


〈実行〉

Model:handle1[Enter]
action1
Model:handle2[Enter]
action2
Model:handle3[Enter]
action3


参考サイト

 

Java:リフレクションの使い方

Javaのリフレクションは、実行時に、文字列(変数名や関数名)を通して、変数の読み書きや関数の呼び出しを行うための機能です。

 

arithmetics.java

class Arithmetics {
  public String attribute;
  public double add(double x, double y) {
    return x + y;
  }
}
 

 

main.java

import java.lang.reflect.Field;
import java.lang.reflect.Method;

class Main {
  public static void main(String... args) {
    try {
      String stringClass = "Arithmetics";
      String stringField = "attribute";
      String stringMethod = "add";

      Class<?> clazz = Class.forName(stringClass);
      Object object = clazz.newInstance();

      Field field = clazz.getField(stringField);
      field.set(object, "Hello!");
      System.out.println(field.get(object));

      Method method = clazz.getMethod(stringMethod, double.class, double.class);
      System.out.println(method.invoke(object, 1, 1));
    }
    catch (ReflectiveOperationException e) {
      e.printStackTrace();
    }
  }
}
 



〈実行結果〉

Hello!
2.0


Javaのリフレクションを使うとアノテーション情報を取得することもできます。

 

InfoAnnotation.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
public @interface InfoAnnotation {
  String info() default "";
}
 

 

arithmetics.java

class Arithmetics {
  @InfoAnnotation(info = "field")
  public String attribute;

  @InfoAnnotation(info = "method")
  public double add(double x, double y) {
    return x + y;
  }
}
 

 

main.java

import java.lang.reflect.Field;
import java.lang.reflect.Method;

class Main {
  public static void main(String... args) {
    try {
      Field field = Arithmetics.class.getField("attribute");
      InfoAnnotation fieldAnnotation = field.getAnnotation(InfoAnnotation.class);
      System.out.println(fieldAnnotation.info());

      Method method = Arithmetics.class.getMethod("add", double.class, double.class);
      InfoAnnotation methodAnnotation = method.getAnnotation(InfoAnnotation.class);
      System.out.println(methodAnnotation.info());
    }
    catch (ReflectiveOperationException e) {
      e.printStackTrace();
    }
  }
}
 



〈実行結果〉

field
method


参考サイト

 

Java:JARライブラリの作成と使用

1.JARライブラリの作成

 

D:\jar\pkg1\pkg2\pkg3\Arithmetics.java

package pkg1.pkg2.pkg3;

public class Arithmetics {
  public static double add(double x, double y) {
    return x + y;
  }
}
 

 

〈フォルダpkg1の中にあるファイルを全てアーカイブする場合〉

D:\jar\jar0.bat(ファイル名をjar.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
javac pkg1/pkg2/pkg3/*.java
jar cfv hoge.jar pkg1

 

〈フォルダpkg1/pkg2/pkg3の中にあるclassファイルを全てアーカイブする場合〉

D:\jar\jar1.bat(ファイル名をjar.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
javac pkg1/pkg2/pkg3/*.java
jar cfv hoge.jar pkg1/pkg2/pkg3/*.class


2.JARライブラリの使用

 

D:\src\main.java

import pkg1.pkg2.pkg3.Arithmetics;

class Main {
  public static void main(String... args) {
    System.out.println(Arithmetics.add(1, 1));
  }
}
 

 

Mainクラスのコンパイル

D:\src\javac0.bat(ファイル名をjavac.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
javac -cp .;D:\jar\hoge.jar main.java

 

Mainクラスの実行

D:\src\java0.bat(ファイル名をjava.batにすると暴走します)

set JAVA_HOME=D:\sdk\jdk
set path=%path%;%JAVA_HOME%\bin
java -cp .;D:\jar\hoge.jar Main
pause


参考サイト

 

C++:vectorを使った多次元配列の動的確保

下記の vector.cpp は、std::vector を使って多次元配列を動的に確保するためのプログラムです。

 

vector.cpp

#include <iostream>
#include <vector>
using namespace std;

void showVectorSize(vector<double>& v1) {
  cout << v1.size() << endl;
}

void showVectorSize(vector<vector<double>>& v2) {
  cout << v2.size() << "," << v2.front().size() << endl;
}

void showVectorSize(vector<vector<vector<double>>>& v3) {
  cout << v3.size() << "," << v3.front().size() << "," << v3.front().front().size() << endl;
}

int main() {
  int n1 = 10;
  int n2 = 20;
  int n3 = 30;

  vector<double> v1;
  v1 = vector<double>(n1, 0);
  cout << v1[1] << endl;
  showVectorSize(v1);

  vector<vector<double>> v2;
  v2 = vector<vector<double>>(n1, vector<double>(n2, 0));
  cout << v2[1][2] << endl;
  showVectorSize(v2);

  vector<vector<vector<double>>> v3;
  v3 = vector<vector<vector<double>>>(n1, vector<vector<double>>(n2, vector<double>(n3, 0)));
  cout << v3[1][2][3] << endl;
  showVectorSize(v3);
}
 

 

注)コンパイルする時は、オプション -std=c++11 を付けて下さい。付けない場合は、入れ子になったテンプレート引数において、
  vector<vector<double> >
のように、>> の間に空白を入れる必要があります。


g++ -std=c++11 -O2 vector.cpp -o vector.exe


参考サイト