ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

java.awt.Frameの仕様を調べる方法

前回のブログでjava.awt.Frameクラスを題材にして、クラスやパッケージの概念について議路しました。
今回は、java.awt.Frameクラスの仕様をoracle社のサイト内から見つけ出す方法について書きます。
「このクラスの使い方知らないなあ」というときに、調べる癖をつけると良いと思います。

(1)Orcale社のトップページにいく
http://www.oracle.com/technetwork/java/index.html

(2)左下のEssential Links内の Java API'sをクリック
http://www.oracle.com/technetwork/java/api-141528.html
(3)自分の使用しているJavaのバージョンを選択。今回は、Java Standard Editionの中の
Java SE 7(http://docs.oracle.com/javase/7/docs/api/)を選択する。

(4)Packages内のjava.awtをクリック


(5)Class Summaryの中のFrameをクリック


やっとたどり着いた、Frameクラスの仕様を眺めてみると、クラス間の関係だったり、メソッドだったりと様々な情報を入手することができます。特に、冒頭の部分が役に立ちます。
Frameクラスは4つものスパークラスを持っていることがわかります。このため、Frameクラスがスーパークラスから継承したメソッドについては、スーパークラスのメソッドのページへのリンクを参照するような記載となっています。
また、以前議論したように、JFrameクラス(Swingパッケージに含まれる)は、Frameクラスを継承したサブクラスであることが一目瞭然でわかります。


AWTを題材にして、パッケージの概念について考える

AWTを題材にして、パッケージの概念について考えてみたいと思います。
何気なく、Javaの入門書に付属しているAWTの項目のソースコードを見ていると、

import java.awt.*;    //AWTの主要パッケージの取り込み

のような記述が目立ちます。今回はこの意味について考えてみたいと思います。
まずは、AWTプログラミングの原型を提示します。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

import java.awt.*; //AWTの主要なパッケージを読み込む

public class FrameTest
{
public static void main(String[] args) //main()メソッドからプログラムは開始される。
{
Frame f = new Frame("Hello"); //フレームを作成
f.setVisible(true); //フレームを可視化
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

このソースコードは、
import java.awt.*;

import java.awt.Frame;
のように書き換えても正常に動作します。


///////////////////////////////////////////////////////////////////////////////////////////////////////////////


import java.awt.Frame; //AWTの主要なパッケージを読み込む

public class FrameTest
{
public static void main(String[] args) //main()メソッドからプログラムは開始される。
{
Frame f = new Frame("Hello"); //フレームを作成
f.setVisible(true); //フレームを可視化
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////


この説明には以下の図が助けになります。



import java.awt.*;    //AWTの主要パッケージの取り込み
というのは実は、java.awtパッケージに含まれているクラスの階層を丸ごと取り込んでいたいただけにすぎないのです。このことが理解できれば、

import java.awt.Frame;
のように、Frameクラスだけに狙いを定めてインポートすることが可能になります。



さらに興味深いこととして、プログラムの冒頭でインポートしなくても、Frameクラスのインスタントを生成するときだけ、Frameクラスを読み込むことが可能です。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////


public class FrameTest
{
public static void main(String[] args)
{
java.awt.Frame f = new java.awt.Frame("Hello");   //Frameクラスを読み込んでフレームを生成
f.setVisible(true);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


ひとたびFrameクラスのインスタンスを生成してしまえば、その後は再度Frameクラスを読み込む必要はありません。下の例では、f.setSize()やf.setVisible()が、Frameクラスを呼び出さずにFrameクラスに定義されているメソッドを使用している例です。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

public class FrameTest
{
public static void main(String[] args)
{
java.awt.Frame f = new java.awt.Frame("Hello");
f.setSize(600,300);
f.setVisible(true);
}
}



///////////////////////////////////////////////////////////////////////////////////////////////////////////////

ちなみに、このプログラムの実行結果は以下のようになります。
$ javac FrameTest.java
$ java FrameTest



【参考文献】
アスキー書籍編集部『Java6 プログラミング講座』2007 ASCII 181 pp


AWTからSwingが開発されるに至った経緯

一般に、JavaでGUIを持つアプリケーションやアプレットを作成する、AWTとSwingを使用します。この二つの違いを理解するには、歴史的な流れを知る必要があるようです。

Javaができた当初から存在したのはAWTの方だったそうです。
AWTは、稼働するプラットフォームに処理をゆだねるという仕組みを採用していたために、次のような問題が生じました。

  1. パフォーマンスが悪い
  2. すべてのプラットフォームで一貫したGUIを提供するのが難しい
  3. プラットフォームの短所も引き継ぐ
そこでAWTの短所を克服する形で、Swingが開発されました。Swingは、AWTとな異なる仕組みを作用しており、Java対応のどのプラットフォームでプログラムを動かしてもまったく同じ外観と動作が得られます。Swingの利点を上げると、以下のようになります。
  1. ユーザーインターフェース要素の数が多く、各要素の機能も豊富である。
  2. プラットフォームへの依存度が少ないため、プラットフォームの機能に制限されることも少ない。また、各プラットフォームに固有のバグが少ない。
  3. すべてのプラットフォームで一貫したユーザーインターフェースを提供する。

このようにSwingはAWTを発展させる形で作られたため、現在ではGUIプログラミングを行う時は、Swingを用いるのが主流です。しかし、Swingは完全にSwingを置き換えているわけではなく、AWTの基本構造をベースにしているため、使用する上ではAWTの知識が必要となってきます。
【参考文献】
アスキー書籍編集部『Java6 プログラミング講座』2007 ASCII 178 - 180 pp

JFrameコンポーネントを利用したコンポーネントの追加


Javaが好まれる理由の一つにGUIアプリケーションの開発が容易であることが挙げられる。これは、Swingというパッケイージを用いて達成されます。今回は、Swingを用いたアプリケーション、すなわちSwingアプリケーションに関する基本事項について書きます。

キーワード)
コンテナ、コンポーネント、Swingパッケージ、JFrameクラス

############################################################
//Components.java

//javax.swingのパッケージをまるごとimport
import javax.swing.*;
//javax.awtのパッケージをまるごとimport
import java.awt.*;

public class Components{
public static void main(String[] args){

//JFクラスのコンストラクトを用いてコンテナを作成
JFrame frame = new JFrame("コンポーネントのレイアウト");

//レイアウトマネージャを生成
FlowLayout f_layout = new FlowLayout();
//レイアウトマネージャを適用
frame.setLayout(f_layout);

//コンポーネントの作成
JButton button = new JButton("ボタンです");
JLabel label = new JLabel("ラベルです");
JTextField text = new JTextField("テキストフィールドです", 15);

//コンポオー年との追加
frame.add(button);
frame.add(label);
frame.add(text);

//終了時の動作指定
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//フレームサイズを設定
frame.setSize(350, 110);
//フレームを可視化
frame.setVisible(true);
}
}
############################################################


############################################################
プログラムのテスト
$ java Components


############################################################








############################################################
#javax.swingパッケージに含まれるクラスを調べるには以下のリンクへ
http://docs.oracle.com/javase/jp/6/api/javax/swing/package-summary.html


javax.swingパッケージの中にJFrameというクラスが含まれていることがわかりました。
############################################################

############################################################
#JFrameクラスの仕様は以下のリンクで書くにすることができます。




############################################################

レイアウトマネージャについて一言。Swingアプリケーションでコンポーネントのレイアウトを行う時は、レイアウトマネージャと呼ばれるオブジェクトを使用します。全部で11種類のレイアウトマネージャが存在し、それらを組み合わせてレイアウトをデザインすることができるようになっています。



【参考文献】
丸の内とら『Java入門教室』SE SHOEISHA 2012 346 - 355pp

Javaにおけるエラー処理(例外処理)


Javaにはtry ~ catch文を用いて例外処理(エラー処理)を行うことが可能です。
基本フォーマットは以下のようです。

try{
実行する文1;
実行する文2;
実行する文3;
} catch (例外クラス 変数名)
{
例外が発生した時に実行する文;
}

try{}内でエラーが発生したらcatch内の変数に向けて例外オブジェクトがthrowされます。
下のプログラムはシンプルな実装例で



######################################################

// Exception.java

//Consoleクラスを呼び込む
import java.io.Console;

public class Exception {
    public static void main(String[] args) {
// int型の変数を宣言
        int input;
//Consoleクラスを使用する準備
        Console console = System.console();
        System.out.println("数字を入力してください。");
//例外処理。try内でエラーが出たら、例外オブジェクトをthrowする
            try {
                input = Integer.parseInt(console.readLine());
//例外オブジェクトをキャッチ
            } catch(NumberFormatException e) {
                System.out.println("エラー");
System.out.println("例外オブジェクトの中身は:" + e);
            }
}
}
######################################################

########テスト##########
$ java Exception 

数字を入力してください。
2


$ java Exception
数字を入力してください。
hoge
エラー
例外オブジェクトの中身は:java.lang.NumberFormatException: For input string: "hoge"

###########################



IntegerクラスのメッソドであるparseIntの仕様については以下のサイトで検索することができます。





【参考文献】
丸の内とら『Java入門教室』SE SHOEISHA 2012 126-134pp

Consoleクラスを使ったデータの受け取り(クラスの読み込みの実例)


Consoleクラスを用いて、ユーザー側から文字入力を受け取るプログラムです。
Consoleクラスのメソッド及びそれぞれの例外処理に関しての情報は下記のサイトにのっています。

Consoleクラスはフルネームは"java.io.Console"と言います。"java.io"部分はパッケージ名です。このページには、ConsoleクラスのMethodについて記述がされています。クラスによっては、このページにメソッドだけでなくフィールドについても記載されています。

Consoleクラスに実装されているreadLineメソッドの仕様を眺めてみます。

java.ioパッケージに含まれるようなので、java.ioパッケージに含まれるClassのSummaryを眺めてみます。



SystemクラスやStringクラスの代表されるJava Core APIライブラリの代表的クラスの場合は、デフォルトでimportされるので、明示的にimportする必要はありません。一方、Consoleクラスなどのその他一般のクラスを利用しようと考えた場合は、その都度クラスをimportする必要があります。

#ソースコードの編集
$ vim aisatsu.java

// aisatsu.java
//Consoleクラスのimport
//Consoleクラスを利用すると、CUIでの有用なインターフェースが提供される
import java.io.Console;
public class aisatsu{
 public static void main(String[] args){
  //変数の宣言
  String name;
  //Consoleクラスを使用するための準備
  Console console = System.console();
  System.out.println("Input your name, please.");
  //ユーザーの入力を取得して、変数に代入する。
  //Consoleクラスのメソッド(readLine)を呼び出す
  name = console.readLine();
  System.out.println("Hello, " + name);
 }
}

#コンパイルしてテスト
$ java aisatsu
Input your name, please.
Kappa
Hello, Kappa



上のソースコードでは、文頭に"import java.io.Console"と宣言することで、Consoleクラスをimportしていました。import文を書かなくても、"java.io.Console"のようにパッケージ名とクラス名を合わせて指定することで、ソースコード内でクラスを参照することもできます。


// aisatsu.java
public class aisatsu{
 public static void main(String[] args){
  //変数の宣言
  String name;
  //Consoleクラスを使用するための準備。
  //パッケージ名とクラス名を書く。
  java.io.Console console = System.console();
  System.out.println("Input your name, please.");
  //ユーザーの入力を取得して、変数に代入する。
  //Consoleクラスのメソッド(readLine)を呼び出す
  name = console.readLine();
  System.out.println("Hello, " + name);
 }
}


【参考文献】
丸の内とら『Java入門教室』SE SHOEISHA 2012 75-83pp

オブジェクト指向プログラミングの基本用語


オブジェクト指向型プログラミングに関する各種用語の整理を行いました。大部分は、文末に挙げた参考文献に依拠しています。

#手続き型言語
  • C, Pascal, BASICなど
  • 編成単位が原始的
  • データの扱いが大雑把(local, globalの2種類よりも細かく柔軟性のある指定ができない)
  • アクセスしてはいけない関数からの不注意なアクセスというプログラミングエラーが頻繁に起きる
  • そのデータにアクセする必要な視覚のある関数だけがアクセスできて、ほかからはデータが見えないようにするにはオブジェクト指向型言語が必要
#オブジェクト指向型言語
  • OPP :  object oriented programming
  • 関数と変数の両方をおさめたプログラミング単位:オブジェクト を規定
  • C言語の構造体をヒントに拡張した
#オブジェクト
  • フィールド:オブジェクトの中の変数
  • メソッド:オブジェクトの中の関数
  • 無関係なメソッドや行儀の悪いメソッドがあるオブジェクトのフィールドにアクセスができないようになっている。
#クラス
  • 形はまったく同じでもメソッドの処理内容やフィールドの内容が少しずつ違うオブジェクトをいくつも作成するのは手間がかかる。
  • クラスという概念は、一定の形をしたオブジェクトの仕様書みたいなもの。
#オブジェクトの作成
  • クラスの定義を書いただけでは、そのクラスのオブジェクトは作られない
  • C言語の構造体でもやはり、構造体の定義をかいただけでは何も変数は作られない
  • newというキーワードを使ってオブジェクトを生成
  • オブジェクトの生成と同時に、そのオブジェクトの参照を、そのオブジェクトのクラス型指定としてついている変数に収める必要がある
  • 実際にクラスからオブジェトを作成することをインスタンス作成(instantiation)という
  • オブジェクトのことを「クラスのインスタンス」ということがある。
#オブジェクトのメッソドへのアクセス
  • "."を用いてオブジェクトとそのメソッドやフィールを結びつける
               例  object.field    object.method
#コンストラクタ
  • コンストラクタはnewを用いてオブジェクトを作るときに、自動的に呼び出さる。
  • コンストラクタの名前は常にクラスの名前と同じ
  • コンストラクタの中には、オブジェクトが最初に作られた時の状態や、その時に行われるべき操作などが書かれる。
  • コンストラクタがないと、不必要に多いメソッドを作ってしまうことになる
#publicとprivate
  • publicとprivateはアクセス指定(access modifier)と呼ばれる
  • クラスのメソッドやフィールドに外からアクセスできるか・できないかを指定する
  • privateが付いているフィールやメソッドは、そのクラスの中のメソッドからしかアクセスできない
  • publicが付いているフィールドやメソッドは、その他のクラスから呼び出すことができる
#クラスのフィールド(つまりデータ)は、通常はprivateにして、メソッドの方をpublicにする
  • このようにすることで、他のクラスのメソッドが断り無く勝手にデータを書き換えたりできないので、データが保護される。
  • 外部からのクラスのデータにアクセスする必要があったら、必ずそのクラスのメソッドを使うようにすることができる
  • 『データは女王蜂のみたいなものです。巣の奥深くに隠しておいて、働き蜂のメソッドたちに世話をさせるのです。』
#継承(inheritance)
  • 既存のクラスから派生させたクラスとして、既存のクラスの拡張版のような新しいクラスを作ること
  • 元のクラスをスーパークラス(super class)と呼ぶ
  • 新たに定義されるクラスをサブクラス(subclass)と呼ぶ
  • スーパークラスからサブクラスを作ることは拡張(extend)していることに等しい。そのため、キーワードはextendを使用
  • 既存のクラスに新たな特徴を加えることが容易にできるし、元となる1つのクラスを軸として関連クラスの集まりを定義できるので、設計の点で有利である
#多形性(polymorphism)
  • 多形性とは、クラスがそれぞれ異なる複数のオブジェクトに対して、同じ取り扱いができる状態のこと
  • それらの異なるクラスは、同一のクラスからのサブクラスでなけれbならない
  • クラスが異なる複数のオブジェクトに対して、同じ名前のメソッドを呼び呼び出せるが、そのメソッドの処理内容が少しずつ違う状態のことをpolymorphismと呼ぶ
  • 柔軟で臨機応変な取り扱いを自動的に行うこと
  • 多形性はプログラムの設計とコーディングを単純化し、わかりやすくする
#ソフトウェア工学
  • ソフトウェアの全生涯には、仕様決定、設計、審査、コーディング(狭義のプログラミング)、試験、生産、メンテナンスが含まれる
  • ソフトウェア工学そのものは抽象的な学問なので、大規模なプロジェクトを実際に体験した人でないと具体的な理解が難しい
【参考文献】

Robert Lafore 著 岩谷 宏訳 『Javaで学ぶアルゴリズムとデータ構造』ソフトバンク 1999 8 - 16 pp

Javaアプレットのビュア

作成したJava appletの出来映えを確認したい場合は、appletviewerというコマンドを使用します。
例として、Javaでアプレットを使用しながらアルゴリズムを学べる『Javaで学ぶアルゴリズムとデータ構造』という本 (http://www.sbcr.jp/products/4797306947.html) に付属するサンプルを閲覧してみます。


$ appletviewer ~/Javaで学ぶアルゴリズムとデータ構造/DSA/JAVAAPPS/JAVA-1.1/Chap02/Array


一昔前のJavaだと、Chromeなどのブラウザでは付属のアプレットが動かないことがしばしば見られます。Webブラウザが対応していないためです。そのためApplet Viewerは重宝されます。


【参考文献】
Robert Lafore 著 岩谷 宏訳 『Javaで学ぶアルゴリズムとデータ構造』ソフトバンク 1999

Swingアプリケーションの導入


Swingを用いてWindowを表示させるだけのアプリケーションの作成をしてみます。
AWT(Abstract Window Toolkit)とはJavaが初めてリリースされたときから存在しているJava Core APIのGUIコンポーネントです。
Java Core APIとはJavaの開発環境であるJDKに含まれる、プログラム作成に必要となる基本的なクラスを集めた道具箱のようなものです。
SwingはAWTを進化させる形で、1998年にリリースされました。ちなみにJava自体は、1995年にSun Microsystem社よりリリースされています。
それでは、Swingを用いたアプリケーションを行いたいと思います。

$ vim Hello.java



//Hello.java
//パッケージのインポート
import javax.swing.*;

public class Hello{
 public static void main(String[] args){
  //JFrameクラスのオブジェクトを作成する
  JFrame frame = new JFrame("こんにちは");
  //ウィンドウが閉じるときの動作を設定
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //ウィンドウのサイズを指定
  frame.setSize(500,300);
  //ウィンドウを可視化
  frame.setVisible(true);
 }
}



#コンパイルして実行してみます。
$ javac Hello.java
$ java Hello




【参考文献】
丸の内とら『Java入門教室』SE SHOEISHA 2012 318-325pp

Javaのswingアプリケーションの文字化けの解決方法

Javaの日本語を含むSwingアプリケーションを作るときにハマってしまいました。
解決策も合わせて書きたいと思います。

まず、私のMac OS XのJavaの環境は以下の通りです。

$ java -version
java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-10M3909)
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01-434, mixed mode)

とりあえず、Java以下のソースをコンパイルして実行すると文字化けはおこりません。

$ vim Hello.java

public class Hello{
        public static void main(String[] args){
                System.out.println("Hello in English\n");
                System.out.println("こんにちは in English\n");
        }
}

$ javac Hello.java
$ java Hello


Hello in English

こんにちは in English


コンソールではうまくいくようです。
しかしSwingではうまくいきません。


$ vim Hello.java


import javax.swing.*;

public class Hello{
        public static void main(String[] args){
                JFrame frame = new JFrame("こんにちは");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.setSize(500,300);
                frame.setVisible(true);
        }
}

$ javac Hello.java
$ java Hello

題名が見事な文字化けをしています。
すこし調べた結果、以下のようにするとうまくいくことがわかりました。
文字コードをUTF8 と明示することがミソのようです。

$ javac -J-Dfile.encoding=UTF-8 Hello.java
$ java -Dfile.encoding=UTF-8 Hello

無事解決しました。
エイリアスを設定しておくと便利です。

$ vim ~/.bashrc

#この一行を追記する
alias javac='javac -J-Dfile.encoding=UTF-8'
alias java='java -Dfile.encoding=UTF-8'

【参考文献】
jitsu102の日記