質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

Javaで波を発生させて様子を観察するシミュレーションを行いたい

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 923

実現したいこと

Javaのアプレット作成における質問です。
スクロールバーの操作により波を発生させ、それが壁にぶつかり反射する様子を観察する、視覚的な二次元の物理シミュレーションを作りたいです。
画面上部(BorderLayoutのNORTH)にシミュレーションを始めから行う(リセットする)ためのButtonと自由端・固定端を選択するためのChoice
画面左部(WEST)に波を発生させるためのScrollbar
画面中央部(CENTER)に波の描画などが基本的なコンポーネントです。
文字コードの関係上、コメントも全てガバガバ英語で記述しているため読みにくくて申し訳ありません。

発生している問題

まだ未完成ではありますが、動作確認のためappletviewerを起動させてもアプレットのウィンドウ下部に『開始:アプレットが初期化されていません。』と出るのみで先に進めることができません。
以下のコード及びアプレットは『理系のためのJava入門』という少し古い本を参考にしたものです。

該当コード

時間tに関するコード
PhysicsApplet.java

import java.applet.*;
import java.awt.*;

/* <applet code="PhysicsApplet.class" width="200" height="200"></applet>*/
abstract class PhysicsApplet extends Applet implements Runnable{
    Thread th;
    double t = 0;
    int dt = 100;

    /* @see java.applet.Applet#init()*/
    public void start(){
        if (th == null){
            th = new Thread(this);
            th.start();
        }
    }
    /* @see java.lang.Runnable#run()*/
    public void run(){
        while(th != null){
            /* calculation comes here*/
            routine();
            repaint();

            t = t + dt / 1000.0;
            try{
                Thread.sleep(dt);
            }
            catch(InterruptedException ex){
            }
        }
    }

    abstract public void routine();

    /* @see java.applet.Applet#stop()*/
    public void stop(){
        th = null;
    }
}


描画のためのアプレット
MouseWaveCanvas.java

import java.awt.*;

class MouseWaveCanvas extends Canvas{
    // each positions' list (x, y)
    private int[]  x;
    private int[]  y;

    // wall thickness [pix]
    private final int wallthickness = 4;

    /* paint fuction setting
       @param x
       @param y
    */
    public void setFunction(int[] x, int[] y){
        this.x = x;
        this.y = y;
    }

    /* paint the graph
       @see java.awt.Component#paint(java.awt.Graphics)
    */
    public void paint(Graphics g){
        int w = this.getWidth();
        int h = this.getHeight();
        int x0 = w - 10;
        int y0 = h/2;

        // axis setting
        g.setColor(Color.LIGHT_GRAY);
        g.drawLine(0, y0, x0, y0);

        // wall setting
        g.setColor(Color.DARK_GRAY);
        g.drawLine(x0 - wallthickness, 0, wallthickness, h);

        // return if no data
        if (this.x == null || this.y == null){
            return;
        }

        // move the starting point
        int[] xp = new int[x.length];
        int[] yp = new int[y.length];
        for (int i = 0; i < x.length; i++){
            xp[i] = x[i] + x0;
            yp[i] = - y[i] + y0;
        }

        // paint the function
        g.setColor(Color.BLACK);
        g.drawPolyline(xp, yp, x.length);
    }
}


実際に動かすためのコード
MouseWave.java

/*
Oscillatory wave(fixed & free) reflections' simulation, which can be controlled by the mouse's movement. 
*/

/* <applet code="MouseWave.class" width="800" height="400"></applet>*/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class MouseWave extends PhysicsApplet implements ActionListener, AdjustmentListener{

    // pattern FIXED
    public final String FIXED_STRING = "FIXED";
    public final int FIXED = -1;

    // pattern FREE
    public final String FREE_STRING = "FREE";
    public final int FREE = 1;

    // components
    MouseWaveCanvas canvas;
    Button button;
    Choice choice;
    Scrollbar scrollbar;

    // boundary condition (FREE on default)
    private int boundary = FREE;

    // setting wave(controlled by scrollbar)
    int scrl_default = this.canvas.getHeight()/2;
    int scrl_low     = this.canvas.getHeight();
    int scrl_y = scrl_default;

    // setting coord (X, Y)
    int n = this.canvas.getWidth() - 10;
    int[] x = new int[n];
    int[] y = new int[n];
    int[] y_reflect = new int[n];

    /* @see java.applet.Applet#init()*/
    public void init(){
        this.canvas    = new MouseWaveCanvas();
        this.button    = new Button("reset");
        this.choice    = new Choice();
        this.scrollbar = new Scrollbar(Scrollbar.VERTICAL, this.scrl_default, 10, this.scrl_low, 0 );
        choice.addItem(this.FIXED_STRING);
        choice.addItem(this.FREE_STRING);
        choice.select(this.FREE_STRING);

        // add components to panel
        Panel p = new Panel();
        p.add(button);
        p.add(choice);

        // set applets' layout
        this.setLayout(new BorderLayout());
        this.add(p, BorderLayout.NORTH);
        this.add(scrollbar, BorderLayout.WEST);
        this.add(this.canvas, BorderLayout.CENTER);

        // enable the components
        this.button.addActionListener(this);
        this.scrollbar.addAdjustmentListener(this);
    }

    /* @see PhysicsApplet#routine()*/
    public void routine(){
        for (int i=0; i<2*n; i++){
        x[i] = i;
        y[i] = 0;
        y_reflect[i] = 0;
        }

        // sync scrollbar to Y
        y[0] = scrl_y;

        // calculate the waves' form
        for (int i=n; i==0; i--){
        y[i] = y[i-1];
        }

        for (int i=0; i<n; i++){
            int reverse = -1 - i;
            y_reflect[0] = y[reverse];
        }

        for (int i=0; i<n; i++){
            y[i] += this.boundary * y_reflect[i];
        }

        this.canvas.setFunction(x, y);
        this.canvas.repaint();
    }

    /* @see java.awt.event.AdjustmentListener#adjustmentValueChanged(java.awt.event.AdjustmentEvent)*/
    // process when the scrollbar moved
    public void adjustmentValueChanged(AdjustmentEvent ev){
        if(ev.getSource() == this.scrollbar){
            this.scrl_y = ev.getValue() - this.scrl_default;
        }
        else if (ev.getValueIsAdjusting() != true){
            this.scrollbar.setValue(this.scrl_default);
        }
    }
    /* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)*/
    // process when the button has pushed(reset)
    public void actionPerformed(ActionEvent ev){
        if (ev.getSource() == this.button){
            if (this.choice.getSelectedItem().equals(this.FIXED_STRING)){
                this.boundary = this.FIXED;
            } else {
                this.boundary = this.FREE;
            }

            t = 0;
        }
    }
}

試したこと

アプレットタグなどを確認しても間違いがわからずコンパイルエラーも出ません。

/* @see java.applet.Applet#init()*/
public void init()
による初期化も行いましたが効果無しです。

補足情報(FW/ツールのバージョンなど)

実行環境はJava 1.8.0_221です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

init() は Applet を継承したクラスに必要なのではないでしょうか.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る