import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class SimplePendulumApplet extends Applet
implements Runnable,ActionListener,AdjustmentListener,ItemListener
//Appletクラスを継承して、時間的な処理、ボタンのイベント、スクロールバーのイベントを処理するインターフェイスを実装する。
{
Thread th;
//Threadクラスの変数thを設定
SimplePendulumCanvas
spc;
//SimplePendulumCanvasクラスの変数spcを設定
SimplePendulumCanvas2 spc2;
//コンポーネント
Button button;
Scrollbar
scrbar,scrbar1;
Label angleLabel,periodLabel;
Checkbox ch;
//プロパティ、メンバ
double t=0;
int dt=100;
double thetaMax=Math.PI/6;
//初期角度
double T=2.0;
//初期周期
final int thetaMax_min=5;
//最小角度
final int thetaMax_max=90;
//最大角度
final int deltaTheta=5;
//角度の刻み幅
final int periodmax_min=1;
//最小周期
final int
periodmax_max=6;
// 最大周期
final int deltaperiod=1; //周期の刻み幅
double omega = 2*Math.PI/T;
boolean threadFlg =
true;
//スレッドのループに利用するフラグ変数
boolean suspendFlg
= false;
//スレッドの一時停止と再開に利用するフラグ変数
//---------------------------------------------------------初期設定用メソッド--------------------------------------------
//メソッド1
public void init(){
this.spc=new SimplePendulumCanvas(this.thetaMax);
//キャンバスをオブジェクト化 theta=thetaMax
this.spc2=new SimplePendulumCanvas2(0);
//画面の設定を行っていく
//画面上部のパネルの作成
int theta_i=30;
int period_i=2;
this.button=new Button("reset");
this.ch=new Checkbox("stopped");
this.scrbar=new Scrollbar(Scrollbar.HORIZONTAL,
theta_i,
this.deltaTheta,
this.thetaMax_min,
this.thetaMax_max+this.deltaTheta); //
this.angleLabel=new Label(theta_i+"deg",Label.CENTER);
this.scrbar1=new
Scrollbar(Scrollbar.HORIZONTAL,period_i,this.deltaperiod,this.periodmax_min,this.periodmax_max+this.deltaperiod);
this.periodLabel=new Label("T="+period_i+"s",Label.CENTER);
Panel p=new Panel();
//パネルのオブジェクト化
p.setLayout(new
GridLayout(1,4));
//パネルのレイアウトのオブジェクト化と設定
p.add(ch);
p.add(button); //追加
p.add(scrbar);
p.add(angleLabel);
//画面下部のラベルの作成
Panel p2=new Panel();
p2.setLayout(new GridLayout(1,3));
p2.add(new Label("Period T",Label.CENTER));
p2.add(scrbar1);
p2.add(periodLabel);
//画面真中のパネル
Panel p3=new Panel();
p3.setLayout(new GridLayout(1,2));
p3.add(spc);
p3.add(spc2);
//アプレットのレイアウトを設定
this.setLayout(new BorderLayout());
this.add(p,BorderLayout.NORTH);
this.add(p3,BorderLayout.CENTER);
this.add(p2,BorderLayout.SOUTH);
//リスナーに登録
this.button.addActionListener(this);
this.scrbar.addAdjustmentListener(this);
this.ch.addItemListener(this);
this.scrbar1.addAdjustmentListener(this);
}
//-------------------------------------実行が始まると呼び出される処理----------------------//
//メソッド2
public void start(){
th=new Thread(this); //変数thをオブジェクト化
th.start(); //スレッドをスタートさせる
}
public void run(){
while(threadFlg){
double omega = 2*Math.PI/this.T;
//w=2π/Tの計算
double theta=this.thetaMax*Math.cos(omega*t); //θ=Acos(wt)の計算
this.spc.setAngle(theta); //CanvasのsetAngleメソッドに値を返す。
this.spc.repaint();
//Canvasの再描写
double
velocity=this.thetaMax*omega*Math.sin(omega*t);
//速度の計算
double acc=this.thetaMax*omega*omega*Math.cos(omega*t); //加速度の計算
this.spc2.setVelocity(velocity); //値を返す
this.spc2.setAcc(acc);
this.spc2.repaint(); //再描写
t=t+dt/1000.0; //時間を進める
try{
Thread.sleep(dt);
synchronized(this){
while(suspendFlg){ //suspendFlg=Trueの場合、スレッドを一時停止
wait();
}
}
}
catch(InterruptedException e){}
}
}
public void adjustmentValueChanged(AdjustmentEvent ev){
if(ev.getSource()==this.scrbar){ //スクロールバーを移動で、値を変える
this.angleLabel.setText(this.scrbar.getValue()+"deg");
}
if(ev.getSource()==this.scrbar1){
this.periodLabel.setText("T="+this.scrbar1.getValue()+"s");
}
}
public void actionPerformed(ActionEvent ev){
if(ev.getSource()==this.button){ //Resetボタンを押すと、t=0から
this.t=0;
this.thetaMax=this.scrbar.getValue()*Math.PI/180.0; //初期角度の値を変える
this.T=this.scrbar1.getValue(); //周期の値を変える
}
}
public synchronized void itemStateChanged(ItemEvent ev){
Checkbox ch = (Checkbox)ev.getItemSelectable(); //チェックボックスを押したとき
if(ch.getState()){
this.suspendFlg=true; //suspendFlgをTrueにする
}
else{
suspendFlg = false;
notify();}}
public void paint (Graphics g){
}
public void stop(){
}
}