Heat1dyou.java は (実行は http://nalab.mind.meiji.ac.jp/~mk/labo/java/sample/Heat1dyou.html)、 大したことはしていない (イベント処理を JDK 1.1 以降のそれに置き換えた)。
1 /* 2 * Heat1dyou.java --- Heat1d_e_4.java を JDK 1.2 に合わせて変更したもの 3 * 2001年1月18日 4 * 5 * コンパイル: javac Heat1dyou.java 6 * 実行: appletviewer Heat1dyou.java 7 * 8 * <applet code ="Heat1dyou" width=500 height=500></applet> 9 */ 10 11 import java.applet.*; 12 import java.awt.*; 13 import java.awt.event.*; 14 15 public class Heat1dyou extends Applet implements ActionListener { 16 17 public int N = 20; 18 public double lambda = 0.5; 19 public double Tmax = 0.5; 20 // ユーザーとのインターフェイス 21 public Label labelLambda, labelN, labelTmax; 22 public TextField inputLambda, inputN, inputTmax; 23 public Button startB; 24 // 差分法による熱方程式シミュレーション 25 public HeatCanvas c1; 26 27 public void init() { 28 //画面のレイアウト、レイアウトマネージャーの設定 29 setLayout(new BorderLayout()); 30 31 //Northパネルの設定 32 Panel pn = new Panel(); 33 pn.setLayout(new GridLayout(3,2)); 34 35 //ボタン、テキストフィールドの準備 36 String s = "lambda (should be <= 1/2)"; 37 labelLambda = new Label(s, Label.LEFT); 38 pn.add(labelLambda); 39 40 inputLambda = new TextField("" + lambda,10); 41 pn.add(inputLambda); 42 43 labelN = new Label("N", Label.LEFT); 44 pn.add(labelN); 45 46 inputN = new TextField("" + N,10); 47 pn.add(inputN); 48 49 labelTmax = new Label("Tmax", Label.LEFT); 50 pn.add(labelTmax); 51 52 inputTmax = new TextField("" + Tmax,10); 53 pn.add(inputTmax); 54 55 inputLambda.addActionListener(this); 56 inputN.addActionListener(this); 57 inputTmax.addActionListener(this); 58 59 add(pn, "North"); 60 61 //Centerパネルの設定 62 Panel pc = new Panel(); 63 c1 = new HeatCanvas(); 64 c1.setSize(400,400); 65 c1.compute(lambda, N, Tmax); 66 pc.add(c1); 67 add(pc,"Center"); 68 69 //Eastパネルの設定 70 Panel pe = new Panel(); 71 startB = new Button("Restart"); 72 pe.add(startB); 73 add(pe,"East"); 74 startB.addActionListener(this); 75 } 76 77 //イベント処理(ボタン) 78 public void actionPerformed(ActionEvent e) { 79 if (e.getSource() == startB) { 80 String str1 = inputLambda.getText().trim(); 81 String str2 = inputN.getText().trim(); 82 String str3 = inputTmax.getText().trim(); 83 lambda = Double.valueOf(str1).doubleValue(); 84 N = Integer.parseInt(str2); 85 Tmax = Double.valueOf(str3).doubleValue(); 86 c1.compute(lambda, N, Tmax); 87 } 88 } 89 } 90 91 // HeatCanvas.java 92 93 class HeatCanvas extends Canvas { 94 95 static final boolean DEBUG = false; // true; 96 private static final String message = "1D Heat Equation"; 97 // 問題に取って基本的なパラメーター 98 // N: 区間の分割数 99 // Tmax: 最終時刻 100 // lambda: λ=τ/h^2 101 private int N; 102 private double Tmax, lambda; 103 // 座標系の変換のためのパラメーター 104 private int CanvasX = 400, CanvasY = 400; 105 private double ratiox, ratioy, X0, Y0; 106 // 107 private HeatCanvas c1; 108 109 // コンストラクター 110 public HeatCanvas() { 111 super(); 112 space(-0.1, -0.1, 1.1, 1.1); 113 } 114 public HeatCanvas(int cx, int cy) { 115 super(); 116 CanvasX = cx; CanvasY = cy; 117 space(-0.1, -0.1, 1.1, 1.1); 118 } 119 120 public void compute(double lambda, int N, double Tmax) { 121 this.lambda = lambda; 122 this.N = N; 123 this.Tmax = Tmax; 124 repaint(); 125 } 126 127 // 初期条件 128 private double f(double x) { 129 if (x <= 0.5) 130 return x; 131 else 132 return 1.0 - x; 133 } 134 // 座標変換の準備 135 private void space(double x0, double y0, double x1, double y1) { 136 X0 = x0; Y0 = y0; 137 ratiox = CanvasX / (x1 - x0); 138 ratioy = CanvasY / (y1 - y0); 139 } 140 // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系) 141 private int wx(double x) { 142 return (int)(ratiox * (x - X0)); 143 } 144 // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系) 145 private int wy(double y) { 146 return CanvasY - (int)(ratioy * (y - Y0)); 147 } 148 // x[], y[] の内容をグラフにする 149 private void drawGaph(Graphics g, double x[], double u[]) { 150 for (int i= 0; i < N; i++) 151 g.drawLine(wx(x[i]), wy(u[i]), wx(x[i + 1]), wy(u[i + 1])); 152 } 153 154 public void paint(Graphics g) { 155 156 double h = 1.0 / N; 157 double tau = lambda * h * h; 158 double dt = 0.01; 159 int Jmax = (int) (Tmax / tau); 160 int skip = (int) (dt / tau + 0.5); 161 double [] u, unext, x; 162 163 // ベクトルを確保する 164 x = new double[N+1]; 165 u = new double[N+1]; 166 unext = new double[N+1]; 167 for (int i = 0; i <= N; i++) 168 x[i] = i * h; 169 170 // これはあんまり意味がない。 171 g.setColor(Color.pink); 172 g.fillOval(10, 10, 330, 60); 173 g.setColor(Color.red); 174 for (int i=0; i<4;i++) 175 g.drawOval(10-i, 10-i, 330+2*i, 60+2*i); 176 177 // タイトルを表示する 178 g.setColor(Color.black); 179 g.setFont(new Font("Helvetica", Font.BOLD, 24)); 180 g.drawString(message, 40, 50); 181 182 // 初期値を計算する 183 for (int i = 0; i <= N; i++) 184 u[i] = f(i * h); 185 186 // 初期値のグラフを描く 187 drawGaph(g, x, u); 188 189 // 時間に関するループ 190 for (int j = 1; j <= Jmax; j++) { 191 int i; 192 for (i = 1; i < N; i++) 193 unext[i] = (1 - 2 * lambda) * u[i] 194 + lambda * (u[i-1] + u[i+1]); 195 for (i = 1; i < N; i++) 196 u[i] = unext[i]; 197 u[0] = 0; u[N] = 0; 198 199 if (DEBUG) 200 for (i = 0; i <= N; i++) 201 System.out.println("u[" + i + "]=" + u[i]); 202 // 適当な間隔 (dt=0.01) でグラフを描く 203 if (j % skip == 0) 204 drawGaph(g, x, u); 205 } 206 } 207 }