戻る。

2個の正弦波の加算。

普通に描画
ダブルバッファで描画してちらつきを押さえる。
   

動画的に連続してグラフィックを書くと、左の様にチラチラちらくつくので、ダブルバッファ(オフラインスクリーン)を使用するのが定石。

普通、出力処理は

paint ( Graphics g)

の中で行うが、この g に直接かいちゃうとチラツクので、別にバッファを用意しておいて、バッファを書き終えてから一気に g に転送するという定石。

まず

public class applet の直ぐ下に、このクラスでのグローバル変数(みたいなもの)として、

Image off_img; //チラツキ防止の為のオフスクリーンバッファ
Graphics off_g;

を宣言しておく。

次に、

public void start() (自動生成されてなければ書く)

の中に、

// オフスクリーンバッファの定義。なぜかinit()の中に書くとエラーが出る?(JBuilder5)
int
w = this.getSize().width ;
int
h = this.getSize().height ;
off_img = createImage(w,h); //オフスクリーンバッファを現アプレットと同サイズで作成。
off_g = off_img.getGraphics(); //それのオフスクリーンバッファのグラフィックス

を書く。(ってその辺の検索サイトで[java ダブルバッファ]で検索書ければわかる用に、これらは普通は init()の中に書くと思うんですが、なぜかstartの中に書かないとうまくゆかない。確かJBuilder4ではinitで良かった筈なんだけどなぁ)

あと、repaint()っていうのは、paint()を呼び出すんだけど、updateというのを定義してやると、paintを呼び出すタイミングが画面の切り替えタイミングとシンクロして、ちらつきが防止されるらしいので、書いておく。

public void update(Graphics g){
paint(g); //これを記述すると、repaint()のタイミングが、画面書き換えタイミングとシンクロしてちらつきを防ぐ。

}

paintの中では、gではなくて、 off_g に線とか文字を書いておいて、

g.drawImage(off_img,0,0,this); //最後にオフスクリーンのイメージをオンスクリーンに転送する。

で表示すると、ちらつきが防止される。

 

 

ダブルバッファ使用のソース(赤部分がダブルバッファ関連)

applet_tips1.java
作成: JBuilder
package tips1;

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

import java.math.*;//sin


public class applet_tips1 extends Applet {
  boolean isStandalone = false;
  BorderLayout borderLayout2 = new BorderLayout();
  Panel panel1 = new Panel();
  Scrollbar scrollbar1 = new Scrollbar();
  BorderLayout borderLayout1 = new BorderLayout();
  Label label1 = new Label();
  Scrollbar scrollbar2 = new Scrollbar();

  Image off_img;   //チラツキ防止の為のオフスクリーンバッファ
  Graphics off_g;

  /**引数値の取得*/
  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) :
      (getParameter(key) != null ? getParameter(key) : def);
  }

  /**アプレットの構築*/
  public applet_tips1() {
  }
  /**アプレットの初期化*/
  public void init() {
    try {
      jbInit();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
  /**コンポーネントの初期化*/
  private void jbInit() throws Exception {
    this.setLayout(borderLayout2);
    scrollbar1.setForeground(Color.black);
    scrollbar1.setOrientation(0);
    scrollbar1.setValue(55);
    scrollbar1.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
      public void adjustmentValueChanged(AdjustmentEvent e) {
        scrollbar1_adjustmentValueChanged(e);
      }
    });
    panel1.setLayout(borderLayout1);
    label1.setText("周波数の合成。スクロールバーを動かしてください。↑");
    scrollbar2.setOrientation(0);
    scrollbar2.setValue(45);
    scrollbar2.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
      public void adjustmentValueChanged(AdjustmentEvent e) {
        scrollbar2_adjustmentValueChanged(e);
      }
    });
    this.setBackground(new Color(236, 243, 210));
    this.add(panel1, BorderLayout.SOUTH);
    panel1.add(scrollbar1, BorderLayout.NORTH);
    panel1.add(label1, BorderLayout.SOUTH);
    panel1.add(scrollbar2, BorderLayout.CENTER);
  }
  /**アプレットの情報取得*/
  public String getAppletInfo() {
    return "Applet Information";
  }
  /**引数情報の取得*/
  public String[][] getParameterInfo() {
    return null;
  }

  public void start(){
      // オフスクリーンバッファの定義。なぜかinit()の中に書くとエラーが出る?(JBuilder5)
     int w = this.getSize().width ;
     int h = this.getSize().height ;
    off_img = createImage(w,h);     //オフスクリーンバッファを現アプレットと同サイズで作成。
    off_g   = off_img.getGraphics();  //それのオフスクリーンバッファのグラフィックス


  }



 public void update(Graphics g){
  paint(g); //これを記述すると、repaint()のタイミングが、画面書き換えタイミングとシンクロしてちらつきを防ぐ。
  }


 public void paint(Graphics g){

    int nValue1,nValue2;
    int nx,ny,nx0,ny0;
    int nw,nh;
    String s;


    //以下、グラフィックへの描画はオフスクリーンoff_gへ書いて行く。
    nw = this.getSize().width ;
    nh = this.getSize().height ;
    off_g.clearRect(0,0,nw,nh);

    nValue1 = scrollbar1.getValue();
    s = Integer.toString(nValue1);
    off_g.setColor(new Color(128,0,0));
    off_g.drawString(s,0,nh/6*1);

    off_g.setColor(new Color(128,0,0));
    nx0=10 ; ny0=nh/6*1;
    for(nx = 10 ; nx <=nw  ; nx++){
      ny = (int)(nh/12*Math.sin((double)(nValue1*nx)/(double)nw*2*3.14/2.0)+nh/6*1);
      off_g.drawLine(nx0,ny0,nx,ny);
      nx0=nx; ny0=ny;
    }


    nValue2 = scrollbar2.getValue();
    s = Integer.toString(nValue2);
    off_g.setColor(new Color(0,128,0));
    off_g.drawString(s,0,nh/6*2);

    off_g.setColor(new Color(0,128,0));
    nx0=10 ; ny0=nh/6*2;
    for(nx = 10 ; nx <=nw  ; nx++){
      ny = (int)(nh/12*Math.sin((double)(nValue2*nx)/(double)nw*2*3.14/2.0)+nh/6*2);
      off_g.drawLine(nx0,ny0,nx,ny);
      nx0=nx; ny0=ny;
    }

    off_g.setColor(new Color(0,0,0));
    off_g.drawString("sum",0,nh/6*4);
    nx0=10 ; ny0=nh/6*3;
    for(nx = 10 ; nx <=nw  ; nx++){
      ny = (int)(nh/12*Math.sin((double)(nValue1*nx)/(double)nw*2*3.14/2.0)+nh/12*Math.sin((double)(nValue2*nx)/(double)nw*2*3.14/2.0)+nh/6*4);
      off_g.drawLine(nx0,ny0,nx,ny);
      nx0=nx; ny0=ny;
    }
    g.drawImage(off_img,0,0,this); //最後にオフスクリーンのイメージをオンスクリーンに転送する。


 }



  void scrollbar1_adjustmentValueChanged(AdjustmentEvent e) {
    repaint();

  }

  void scrollbar2_adjustmentValueChanged(AdjustmentEvent e) {
    repaint();
  }
}

applet_tips1.java
作成: JBuilder