トップページ > Java3D入門 > オイラーの公式アプレット(2)
//******************************************************************************
//exp(jθ)のグラフ “euler.java”
//
//複素関数グラフを描画
//
//※Canvas3D_ViewChangeクラスが必要
//※Axis_classクラスが必要
//※SlideBar2クラスが必要
//******************************************************************************
//Swing関係のインポート
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
//Java3D関係のインポート
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
public class euler implements MouseMotionListener
{
//=============================================================================
//フィールド
//=============================================================================
//曲線のパラメータ
double radius = 5.0d;
int z_range = 10;
int data_point=60;
//スライドバー
SlideBar2 bar;
int slidebar_value_max;
float bar_value;
//球の座標変換関係
Transform3D sphere_transform;
Vector3f sphere_vector;
TransformGroup sphere_tg;
//複素ベクトル(赤線)の座標変換関係
Transform3D line_transform1;
Transform3D line_transform2;
TransformGroup line_tg;
Vector3f line_vector;
//=============================================================================
//メインメソッド
//=============================================================================
public static void main(String args[])
{
euler frame = new euler();
}
//=============================================================================
//コンストラクタ
//=============================================================================
public euler()
{
//============================================================================
//まずは、基礎フレームの設定。
//============================================================================
//メイン・ウィンドウ作成
JFrame frame = new JFrame();
//ウィンドウのサイズ設定
frame.setSize(650+10,600+35);
//ウィンドウのタイトル設定
frame.setTitle("exp(jθ)");
//ウィンドウを閉じる動作の登録
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//コンテントペインを作成
JPanel cp = new JPanel();
//コンテントペイン上のレイアウトは全て手動で行う
cp.setLayout(null);
//フレームに、コンテントペインを登録
frame.add(cp);
//ウィンドウを可視化
frame.setVisible(true);
//============================================================================
//スライドバー
//============================================================================
//スライドバーを作成
bar = new SlideBar2();
//コンテントペイン
cp.add(bar);
//サイズ決定
bar.setBounds(600,0,50,600);
//Slidebarのinitial()はサイズ決定,ウィンドウ表示後に呼ぶ。
bar.initialize();
//バーの動きを,このクラスのマウス動作と結びつける
bar.addMouseMotionListener(this);
//バーの最大値
slidebar_value_max = bar.getSize().height - 16;
//============================================================================
//次にJava3D関係の設定。
//============================================================================
//現在使用している画面の、ハードウェア情報を取得する
GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
//Cnavas3D_ViewChangeクラスを用意する(距離は40, マウス感度は0.05)
Canvas3D_ViewChange canvas = new Canvas3D_ViewChange(40.0f, 0.02f, g_config);
//3D表示領域の大きさを設定。今回はウィンドウいっぱいに表示する
canvas.setBounds(0,0,600,600);
//コンテントペインにCanvas3Dを登録
cp.add(canvas);
//============================================================================
//3D空間を構築していきます
//============================================================================
//============================================================================
//全般
//Canvas3DクラスのSimpleUniverseを利用。
SimpleUniverse universe = canvas.universe;
//座標軸クラスをインスタンス化
complex_Axis_class axis = new complex_Axis_class(20.0f);
//universeへ登録
universe.addBranchGraph(axis.Axis_group);
//============================================================================
//らせん状の補助線を書く
//らせん状に頂点を打って,短い線分で曲線を表現
Point3d[] line_vertex = new Point3d[data_point*z_range];
for(int i=0;i < data_point*z_range;i++)
{
line_vertex[i] = new Point3d(radius*Math.cos(2*Math.PI*i/data_point), radius*Math.sin(2*Math.PI*i/data_point), radius*(i - z_range*data_point/2)/data_point);
}
//連続する点を指定(小区間に分割することも可能)
int[] strip = {data_point*z_range};
//折れ線のオブジェクトを作成
LineStripArray line = new LineStripArray(line_vertex.length, GeometryArray.COORDINATES, strip);
//折れ線オブジェクトに頂点座標を登録
line.setCoordinates(0, line_vertex);
//Shape3Dとして図形オブジェト化
Shape3D line_shape = new Shape3D(line);
//「枝」を作成
BranchGroup line_group = new BranchGroup();
//折れ線を「枝」に登録
line_group.addChild(line_shape);
//「枝」をuniverseに登録
universe.addBranchGraph(line_group);
//============================================================================
//球を書く
//質感,色などの設定
Appearance appearance = new Appearance();
Material material = new Material();
material.setDiffuseColor(0.0f,1.0f,1.0f);
appearance.setMaterial(material);
//球を生成
Sphere sphere = new Sphere(0.6f,appearance);
//「枝」を作成
BranchGroup sphere_group = new BranchGroup();
//座標変換グループ
sphere_tg = new TransformGroup();
//座標変換許可設定
sphere_tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//球を座標変換グループに登録
sphere_tg.addChild(sphere);
//座標変換グループを「枝」に登録
sphere_group.addChild(sphere_tg);
//「枝」をuniverseに登録
universe.addBranchGraph(sphere_group);
//初期位置へ座標変換する
sphere_transform = new Transform3D();
sphere_vector = new Vector3f((float)radius,0,0);
sphere_transform.setTranslation(sphere_vector);
sphere_tg.setTransform(sphere_transform);
//============================================================================
//複素ベクトルを書く
//線分の頂点を定義
Point3d[] line_vertex2 = new Point3d[2];
line_vertex2[0] = new Point3d(0, 0, 0);
line_vertex2[1] = new Point3d(radius, 0, 0);
//連続する点を指定(小区間に分割することも可能)
int[] strip2 = {2};
//折れ線オブジェクトに座標を登録。(色をつけるためのには引数にGeometryArray.COLOR_3が必要)
LineStripArray line2 = new LineStripArray(line_vertex2.length, GeometryArray.COORDINATES | GeometryArray.COLOR_3, strip2);
line2.setCoordinates(0, line_vertex2);
//色の設定
Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
line2.setColor(0, red);
line2.setColor(1, red);
//Shape3Dを作成
Shape3D line_shape2 = new Shape3D(line2);
//「枝」を作成
BranchGroup line_group2 = new BranchGroup();
//座標変換クラスを作成
line_tg = new TransformGroup();
line_tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//線分を座標変換クラスに登録
line_tg.addChild(line_shape2);
//座標変換クラスを「枝」に登録
line_group2.addChild(line_tg);
//「枝」をuniverseに登録
universe.addBranchGraph(line_group2);
//初期位置への座標変換準備
line_transform1 = new Transform3D();
line_transform2 = new Transform3D();
line_vector = new Vector3f();
//============================================================================
//ライトの設定(いつもと同じ平行光源を設定)
//============================================================================
//ライトの強さ及び色
Color3f light_color = new Color3f(3.4f,3.4f,3.4f);
//ライトの方向
Vector3f light_direction = new Vector3f(-0.8f,-1.2f,-1.0f);
//平行光源を用意
DirectionalLight light = new DirectionalLight(light_color,light_direction);
//ライトで照らす範囲(球範囲で指定,中心座標とその半径)
BoundingSphere bounds = new BoundingSphere(new Point3d( 0.0f , 0.0f , 0.0f ) , 1000);
//範囲を登録
light.setInfluencingBounds(bounds);
//ライト用の「枝」を作る
BranchGroup BranchGroup_Light = new BranchGroup();
//「枝」にライトを登録
BranchGroup_Light.addChild(light);
//仮想空間に「枝」を登録
universe.addBranchGraph(BranchGroup_Light);
}
//=============================================================================
//マウスが動いたときに呼ばれる
//=============================================================================
public void mouseMoved(MouseEvent event)
{
//何もしない
}
//=============================================================================
//マウスがドラッグされたときに呼ばれる
//=============================================================================
public void mouseDragged(MouseEvent event)
{
bar_value = bar.value * z_range * data_point / slidebar_value_max;
//===========================================================================
//球を動かす
//座標変換クラスのリセット
sphere_transform.setIdentity();
//球を移動させる先の位置ベクトル
sphere_vector.x = (float)radius*(float)Math.cos(2*Math.PI*bar_value/data_point);
sphere_vector.y = (float)radius*(float)Math.sin(2*Math.PI*bar_value/data_point);
sphere_vector.z = (float)radius*(bar_value - z_range*data_point/2)/data_point;
//平行移動の座標変換
sphere_transform.setTranslation(sphere_vector);
//座標変換実行
sphere_tg.setTransform(sphere_transform);
//===========================================================================
//複素ベクトルを動かす
//座標変換クラスのリセット
line_transform1.setIdentity();
line_transform2.setIdentity();
//線分を回転させる座標変換
line_transform1.rotZ(2*Math.PI*bar_value/data_point);
//線分を移動させる先の位置ベクトル
line_vector.x = 0.0f;
line_vector.y = 0.0f;
line_vector.z = (float)radius*(bar_value - z_range*data_point/2)/data_point;
//平行移動の座標変換
line_transform2.setTranslation(line_vector);
//座標変換を合成
line_transform2.mul(line_transform1);
//座標変換実行
line_tg.setTransform(line_transform2);
}
}
//******************************************************************************
//マウスのドラッグで視点移動を行うCanvas3D拡張クラス“Canvas3D_ViewChange”
//
//Canvas3Dを継承
//MouseMotionLisenerを実装
//
//コンストラクタの引数はカメラの距離とマウス感度
//さらに,コンストラクタの引数にはGraphicsConfigurationが必要(Canvas3Dと同じ仕様)
//
//フィールドとして,SimpleUniverse,ViewingPlatformを持つ
//
//球座標を使用
//動径の長さ一定,マウスのX移動はφ,マウスのY移動はθに対応
//動径の長さは“camera_distance”,初期角度は“theta”と“phi”で調節
//マウス感度は“sensitivity”で調節
//******************************************************************************
//全般のためのインポート
import java.awt.*;
import java.awt.event.*;
//Java3D関係のインポート
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
public class Canvas3D_ViewChange extends Canvas3D
{
//=============================================================================
//クラスのフィールド
//マウスの動きに対する感度
float sensitivity;
//動径の長さ(座標中心と視点との距離)
float camera_distance;
//新規取得するマウスのx,y座標
int new_x, new_y;
//前に取得したマウスのx,y座標
int pre_x, pre_y;
//SimpleUniverseをフィールドとしてもっておく。
SimpleUniverse universe;
//視点の座標変換のためのグループ
TransformGroup Camera;
//視点(カメラ)の座標
float camera_x, camera_y, camera_z, camera_xz, camera_xy, camera_yz = 0;
//極座標のパラメータ
//(初期位置の設定も行う)
float phi = (float)Math.PI/8;
float theta = (float)Math.PI/8;
//座標変換クラス
Transform3D Transform_camera_pos; //カメラの位置
Transform3D Transform_camera_phi; //phiに関する回転
Transform3D Transform_camera_theta; //thetaに関する回転
//3次元ベクトル(カメラの位置用)
Vector3f Vector_camera_pos;
//=============================================================================
//コンストラクタ
public Canvas3D_ViewChange(float Distance, float Sensitivity, GraphicsConfiguration config)
{
//親クラスのコンストラクタを呼ぶ. 引数はGraphicsConfiuration.
super(config);
//カメラの原点からの距離を設定
camera_distance = Distance;
//マウス感度を調節
sensitivity = Sensitivity;
//空のSimpleUniverseを生成
universe = new SimpleUniverse(this);
//============================================================================
//視点(カメラ)について設定
//============================================================================
//------------------------------------------------------------------
//カメラ全般の初期設定
//SimpleUniverseが生成したViewingPlatformを取得
ViewingPlatform vp = universe.getViewingPlatform();
//ViewingPlatformの座標変換グループとして,“Camera”を割り当てる
Camera = vp.getViewPlatformTransform();
//------------------------------------------------------------------
//カメラの位置に関する初期設定
//theta関係の計算(球座標→直交座標)
camera_y = camera_distance * (float)Math.sin(theta);
camera_xz = camera_distance * (float)Math.cos(theta);
//phi関係の計算(球座標→直交座標)
camera_x = camera_xz * (float)Math.sin(phi);
camera_z = camera_xz * (float)Math.cos(phi);
//カメラの位置ベクトルを用意
Vector_camera_pos = new Vector3f(camera_x, camera_y, camera_z);
//カメラ位置の座標変換クラスを用意
Transform_camera_pos = new Transform3D();
//初期位置設定ための座標変換を用意する。
Transform_camera_pos.setTranslation(Vector_camera_pos);
//------------------------------------------------------------------
//カメラの向きに関する初期設定
//カメラの向きの座標変換クラスを用意
Transform_camera_phi = new Transform3D();
Transform_camera_theta = new Transform3D();
//カメラの向きの初期設定
Transform_camera_theta.rotX(-theta);
Transform_camera_phi.rotY(phi);
//------------------------------------------------------------------
//以上の設定をカメラに反映
//合成する
Transform_camera_phi.mul(Transform_camera_theta);
Transform_camera_pos.mul(Transform_camera_phi);
//座標変換実行
Camera.setTransform(Transform_camera_pos);
//============================================================================
//マウスの設定
//============================================================================
//マウス入力用のクラス,mouse_classをインスタンス化
mouse_ViewChange mouse = new mouse_ViewChange();
//このフレームにマウス入力クラスを登録
addMouseMotionListener(mouse);
}
//*****************************************************************************
//mouse_ViewChange:マウス入力用のクラス
//*****************************************************************************
class mouse_ViewChange implements MouseMotionListener
{
//============================================================================
//マウスが動いた時に呼ばれるメソッド
//============================================================================
public void mouseMoved(MouseEvent event)
{
//常にマウス座標を更新しておく
pre_x = event.getX();
pre_y = event.getY();
}
//============================================================================
//マウスがドラッグされた時に呼ばれるメソッド
//============================================================================
public void mouseDragged(MouseEvent event)
{
//現在のx座標を取得
new_x = event.getX();
new_y = event.getY();
//thetaとphiの値を更新
//(マウスの動きと視点の動きの向きはここで調整する!)
theta -= sensitivity*(new_y - pre_y);
phi += sensitivity*(new_x - pre_x);
//===========================================================================
//極座標を直交座標へ直す
//theta関係の計算(球座標→直交座標)
camera_y = camera_distance * (float)Math.sin(theta);
camera_xz = camera_distance * (float)Math.cos(theta);
//phi関係の計算(球座標→直交座標)
camera_x = camera_xz * (float)Math.sin(phi);
camera_z = camera_xz * (float)Math.cos(phi);
//===========================================================================
//座標変換クラスを用意する
//カメラの位置ベクトルを作る
Vector_camera_pos.x = camera_x;
Vector_camera_pos.y = camera_y;
Vector_camera_pos.z = camera_z;
//座標変換クラスを初期化(重要!)
Transform_camera_pos.setIdentity();
//平行移動の座標変換を用意
Transform_camera_pos.setTranslation(Vector_camera_pos);
//回転の座標変換を用意
Transform_camera_theta.rotX(-theta);
Transform_camera_phi.rotY(phi);
//===========================================================================
//カメラの座標変換実行
//合成する
Transform_camera_phi.mul(Transform_camera_theta);
Transform_camera_pos.mul(Transform_camera_phi);
//座標変換実行
Camera.setTransform(Transform_camera_pos);
//===========================================================================
//マウス座標を更新しておく
pre_x = event.getX();
pre_y = event.getY();
}
}
//mouse_ViewChangeここまで
//*****************************************************************************
}
//******************************************************************************
//複素座標軸のクラス “complex_Axis_class.java”
//
//このクラスの“Axis_group”フィールドを,
//別プログラム内のSimpleUniverseのインスタンスへaddBranchGraph()して使用する
//******************************************************************************
//Java3D関係のインポート
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
//フォント関係のためのインポート
import java.awt.*;
public class complex_Axis_class
{
//=============================================================================
//クラスのフィールド
BranchGroup Axis_group;
//=============================================================================
//コンストラクタ (引数はサイズ)
public complex_Axis_class(float size)
{
//「枝」を作成
Axis_group = new BranchGroup();
//============================================================================
//X軸
//============================================================================
//材質
Appearance ap_x1 = new Appearance();
Material mat_x1 = new Material();
//表面効果
mat_x1.setDiffuseColor(1.0f,0.0f,0.0f);
//その他視覚効果
ap_x1.setMaterial(mat_x1);
//座標変換クラス
TransformGroup tg_x1 = new TransformGroup();
//座標変換の書き換えを許可
tg_x1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//座標変換内容
Transform3D transform_x1 = new Transform3D();
//円柱(引数は半径,長さ,材質)
Cylinder x1 = new Cylinder(size/100.0f, size, ap_x1);
//座標変換クラスへ軸を登録
tg_x1.addChild(x1);
transform_x1.rotZ(-Math.PI/2);
tg_x1.setTransform(transform_x1);
//全体の「枝」へ座標変換クラスを登録
Axis_group.addChild(tg_x1);
//材質
Appearance ap_x2 = new Appearance();
Material mat_x2 = new Material();
//表面効果
mat_x2.setDiffuseColor(1.0f,0.0f,0.0f);
//その他視覚効果
ap_x2.setMaterial(mat_x1);
//座標変換クラス
TransformGroup tg_x2 = new TransformGroup();
//座標変換の書き換えを許可
tg_x2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//座標変換内容
Transform3D transform_x2 = new Transform3D();
//円錐(引数は半径,長さ,材質)
Cone x2 = new Cone(size/100.0f*2.5f, size/10.0f, ap_x2);
//座標変換クラスへ軸を登録
tg_x2.addChild(x2);
//全体の「枝」へ座標変換クラスを登録
Axis_group.addChild(tg_x2);
Transform3D rot_x2 = new Transform3D();
rot_x2.rotZ(-Math.PI/2);
Vector3f x2_vec = new Vector3f(size/2.0f, 0.0f, 0.0f);
transform_x2.setTranslation(x2_vec);
transform_x2.mul(rot_x2);
tg_x2.setTransform(transform_x2);
//============================================================================
//Y軸
//============================================================================
//材質
Appearance ap_y1 = new Appearance();
Material mat_y1 = new Material();
//表面効果
mat_y1.setDiffuseColor(0.0f,1.0f,0.0f);
//その他視覚効果
ap_y1.setMaterial(mat_y1);
//座標変換クラス
TransformGroup tg_y1 = new TransformGroup();
//座標変換の書き換えを許可
tg_y1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//座標変換内容
Transform3D transform_y1 = new Transform3D();
//円柱(引数は半径,長さ,材質)
Cylinder y1 = new Cylinder(size/100.0f, size, ap_y1);
//座標変換クラスへ軸を登録
tg_y1.addChild(y1);
//全体の「枝」へ座標変換クラスを登録
Axis_group.addChild(tg_y1);
//材質
Appearance ap_y2 = new Appearance();
Material mat_y2 = new Material();
//表面効果
mat_y2.setDiffuseColor(0.0f,1.0f,0.0f);
//その他視覚効果
ap_y2.setMaterial(mat_y1);
//座標変換クラス
TransformGroup tg_y2 = new TransformGroup();
//座標変換の書き換えを許可
tg_y2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//座標変換内容
Transform3D transform_y2 = new Transform3D();
//円錐(引数は半径,長さ,材質)
Cone y2 = new Cone(size/100.0f*2.5f, size/10.0f, ap_y2);
//座標変換クラスへ軸を登録
tg_y2.addChild(y2);
//全体の「枝」へ座標変換クラスを登録
Axis_group.addChild(tg_y2);
Vector3f y2_vec = new Vector3f(0.0f, size/2.0f, 0.0f);
transform_y2.setTranslation(y2_vec);
tg_y2.setTransform(transform_y2);
//============================================================================
//Z軸
//============================================================================
//材質
Appearance ap_z1 = new Appearance();
Material mat_z1 = new Material();
//表面効果
mat_z1.setDiffuseColor(0.0f,0.0f,1.0f);
//その他視覚効果
ap_z1.setMaterial(mat_z1);
//座標変換クラス
TransformGroup tg_z1 = new TransformGroup();
//座標変換の書き換えを許可
tg_z1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//座標変換内容
Transform3D transform_z1 = new Transform3D();
//円柱(引数は半径,長さ,材質)
Cylinder z1 = new Cylinder(size/100.0f, size*2, ap_z1);
//座標変換クラスへ軸を登録
tg_z1.addChild(z1);
transform_z1.rotX(Math.PI/2);
tg_z1.setTransform(transform_z1);
//全体の「枝」へ座標変換クラスを登録
Axis_group.addChild(tg_z1);
//材質
Appearance ap_z2 = new Appearance();
Material mat_z2 = new Material();
//表面効果
mat_z2.setDiffuseColor(0.0f,0.0f,1.0f);
//その他視覚効果
ap_z2.setMaterial(mat_z2);
//座標変換クラス
TransformGroup tg_z2 = new TransformGroup();
//座標変換の書き換えを許可
tg_z2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//座標変換内容
Transform3D transform_z2 = new Transform3D();
//円錐(引数は半径,長さ,材質)
Cone z2 = new Cone(size/100.0f*2.5f, size/10.0f, ap_z2);
//座標変換クラスへ軸を登録
tg_z2.addChild(z2);
//全体の「枝」へ座標変換クラスを登録
Axis_group.addChild(tg_z2);
Transform3D rot_z2 = new Transform3D();
rot_z2.rotX(Math.PI/2);
Vector3f z2_vec = new Vector3f(0.0f, 0.0f, size/2.0f*2);
transform_z2.setTranslation(z2_vec);
transform_z2.mul(rot_z2);
tg_z2.setTransform(transform_z2);
//============================================================================
//3Dテキスト
//============================================================================
//文字は白色
Material mat_text = new Material();
mat_text.setDiffuseColor(1.0f, 1.0f, 1.0f);
Appearance ap_text = new Appearance();
ap_text.setMaterial(mat_text);
//フォントはArial,太字,大きさ
Font basic_font = new Font("Arial", java.awt.Font.BOLD, 2);
//3Dフォントを作成
Font3D font = new Font3D(basic_font, new FontExtrusion());
//実軸のテキスト(位置はX軸の先端)
Text3D x_text = new Text3D(font, "Re", new Point3f(size/2.0f + size/20.0f, 0.0f, 0.0f));
Shape3D x_label = new Shape3D();
x_label.setGeometry(x_text);
x_label.setAppearance(ap_text);
Axis_group.addChild(x_label);
//嘘軸のテキスト(位置はY軸の先端)
Text3D y_text = new Text3D(font, "Im", new Point3f(0.0f, size/2.0f + size/20.0f, 0.0f));
Shape3D y_label = new Shape3D();
y_label.setGeometry(y_text);
y_label.setAppearance(ap_text);
Axis_group.addChild(y_label);
//θ軸のテキスト(位置はZ軸の先端)
Text3D z_text = new Text3D(font, "θ", new Point3f(size/20.0f, 0.0f, size/1.0f - size/20.0f));
Shape3D z_label = new Shape3D();
z_label.setGeometry(z_text);
z_label.setAppearance(ap_text);
Axis_group.addChild(z_label);
}
}
//******************************************************************************
//スライドバー(縦方向) “SlideBar2.java”
//フィールド“volume”の値が、スライドバーの位置
//スライドバーの最大値は 寸法 - 16
//
//使用時の手順
//1.設置
//2.initial()クラスを呼ぶ(バーのサイズ決定,ウィンドウ表示後)
//3.設置先でもMouseMoitonListenerを実装し,
// 設置先でも bar.addMouseMotionListener(this) などのように登録
//******************************************************************************
//==============================================================================
//インポート
//==============================================================================
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.Graphics;
import java.awt.Image;
//==============================================================================
//SlideBarクラス
//==============================================================================
public class SlideBar2 extends Canvas implements MouseMotionListener
{
//=============================================================================
//フィールド
//=============================================================================
//スライドバーの値
int value=0;
//マウスの現在座標
int x=0;
int y=0;
//マウスの1つ前の座標
int pre_x=0;
int pre_y=0;
//バー自体の位置
int bar_pos=0;
//オフセット
int offset=0;
//ダブルバッファ用のImageクラス
Image iBuffer;
//ダブルバッファ用のGraphicsクラス
Graphics gBuffer;
//寸法
Dimension dimension;
//=============================================================================
//コンストラクタ
//=============================================================================
public SlideBar2()
{
//寸法を取得
dimension = getSize();
//MouseMotionListenerに登録
addMouseMotionListener(this);
}
//=============================================================================
//外から呼ぶメソッド。スライドバッファを設置し,サイズを決定後に呼ぶ。
//=============================================================================
public void initialize()
{
bar_pos = getSize().height-16;
getBuffer();
drawBar();
}
//=============================================================================
//ダブルバッファリング関係
//=============================================================================
public void getBuffer()
{
//一応,寸法取得
dimension = getSize();
//描画用メモリ領域確保
iBuffer = createImage(dimension.width,dimension.height);
//iBufferからGraphicsインスタンスを生成
gBuffer = iBuffer.getGraphics();
}
//=============================================================================
//描画
//=============================================================================
public void drawBar()
{
//寸法取得
dimension = getSize();
//gBufferの内容をクリア
gBuffer.clearRect(0,0,dimension.width,dimension.height);
//縦の線の色
gBuffer.setColor(Color.gray);
//縦の線を書く
gBuffer.drawLine(dimension.width/2,0,dimension.width/2,dimension.height);
//バーの色
gBuffer.setColor(Color.lightGray);
//バーを書く
gBuffer.fill3DRect(dimension.width/2-16,bar_pos,32,16,true);
//スライドバーの値を更新
value = dimension.height-bar_pos-16;
}
//=============================================================================
//paint()メソッド
//=============================================================================
public void paint(Graphics g)
{
//iBufferの内容を描画
g.drawImage(iBuffer,0,0,this);
}
//=============================================================================
//マウスが動いたときに呼ばれる
//=============================================================================
public void mouseMoved(MouseEvent event)
{
//マウス座標を更新
pre_x = event.getX();
pre_y = event.getY();
}
//=============================================================================
//マウスがドラッグされたときに呼ばれる
//=============================================================================
public void mouseDragged(MouseEvent event)
{
//一応,寸法取得
dimension = getSize();
//マウス座標を読み込み
x=event.getX();
y=event.getY();
//マウス位置がスライドバー範囲外の場合は何もしない
if(ybar_pos+40)
{
return;
}
//スライドバーの位置を更新
//(画面状では上の方がy座標が小さい)
bar_pos += (y-pre_y);
//もしバーの位置が負になっていたらゼロに戻す
if(bar_pos<0)
{
bar_pos=0;
}
//もしバーの位置が上限を超えていたら最大値に戻す
if((bar_pos+16)>dimension.height)
{
bar_pos = dimension.height-16;
}
//バーを書き直す
drawBar();
//スライドバーの値を更新
value = dimension.height-bar_pos-16;
//マウス座標を更新
pre_x = x;
pre_y = y;
//再描画
repaint();
}
}