- PR -

画像の点滅

1
投稿者投稿内容
yuki
会議室デビュー日: 2003/11/11
投稿数: 6
投稿日時: 2003-11-11 22:45
はじめまして!yukiと言います。
最近、アプレットを始めていろいろ作っているのですが、
今回、画像の上にアイコンをおいてボタンを押すとそのアイコンが
点滅するようなプログラムを作りました。
自分で色々調べながら作ったのですが、アイコンを点滅させると
画像の部分もちらついてしまいます。自分で作れるのはこれくらいが
限界です。そこでみなさまに見ていただいて色々とご意見いただけると
嬉しく思います。よろしくお願いします。

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

public class scroll_img extends Applet implements ActionListener, Runnable{

ImgCanvas image_canvas;
ScrollPane scrollPanel;
Image img1, img2, img3;
Panel pane = new Panel();
GridLayout gridLayout2 = new GridLayout(1,2);
Button btnNext = new Button("次へ");
Button btnPrv = new Button("戻る");
Panel btnPanel = new Panel();
Thread t1;
int imgFlg = 0;
int flg = 0;

public void init() {
setLayout(new BorderLayout());
img1 = getImage(getCodeBase(),"test\\gazo.gif");
img2 = getImage(getCodeBase(),"test\\icon.gif");
img3 = getImage(getCodeBase(),"test\\icon2.gif");
image_canvas = new ImgCanvas(img1, img2, img3);

image_canvas.setSize(500, 500);
scrollPanel = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);

scrollPanel.setSize(appWidth, appHeight);
scrollPanel.add(image_canvas);
add(scrollPanel, BorderLayout.CENTER);
Adjustable hor = scrollPanel.getHAdjustable();
hor.setUnitIncrement(20);
Adjustable ver = scrollPanel.getVAdjustable();
ver.setUnitIncrement(10);
btnPanel.setLayout(new GridLayout(1,2));
btnPanel.add(btnNext);
btnNext.addActionListener(this);
btnPanel.add(btnPrv);
btnPrv.addActionListener(this);
add(btnPanel,BorderLayout.NORTH);
}
}

public void actionPerformed(ActionEvent e){
if (e.getSource()==btnNext){
if (t1 == null){
t1 = new Thread(this);
t1.start();
imgFlg = 0;
}else{
t1.stop();
t1 = null;
t1 = new Thread(this);
t1.start();
imgFlg = 0;
}
}else if(e.getSource()==btnPrv){
if (t1 == null){
t1 = new Thread(this);
t1.start();
imgFlg = 1;
}else{
t1.stop();
t1 = null;
t1 = new Thread(this);
t1.start();
imgFlg = 1;
}
}
}
public void run(){
try {
while(true){
if(flg == 0) {
flg = 1;
}else{
flg = 0;
}
image_canvas.repaint();
t1.sleep(500);
}
} catch(Exception e){
System.out.println(e);
}
}

class ImgCanvas extends Canvas {
Image pic, pic1, pic2;
public ImgCanvas(Image img, Image img2, Image img3) {
pic = img;
pic1 = img2;
pic2 = img3;
}
public void paint(Graphics g) {
g.drawImage(pic, 30, 0, this);
g.drawImage(pic1, 40, 10, this);
g.drawImage(pic2, 90, 50, this);
if(flg == 1 && imgFlg == 0) {
g.drawImage(pic, 30, 0, this);
g.drawImage(pic2, 90, 50, this);
}else if(flg == 1 && imgFlg == 1) {
g.drawImage(pic, 30, 0, this);
g.drawImage(pic1, 40, 10, this);
}
}
}
}
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-11-12 09:13
ImgCanvas でオフスクリーン描画を行うように実装するか、またはSwing使用可能であれば、Swing-Componentを使用すれば、ちらつきを抑えることは可能でしょう(Swing-Componentは内部でオフスクリーン描画してくれてる)。

定期処理をしたければ、java.util.Timerか、またはSwing使用可能ならjavax.swing.Timerを使用した方が、プログラムがすっきりすると思います。
使用方法は....WEBで検索してみてください。

# 提示されたプログラム、Thread周りが怪しい気がするが、そっとしておいてあげよう。
begood
ベテラン
会議室デビュー日: 2003/09/12
投稿数: 97
お住まい・勤務地: とうきょー
投稿日時: 2003-11-12 12:54
このコードある程度は正常に動作してからここにのせたものですか?
シンタックスがずれているような気が・・・。ちがっていたら申し訳ないですけど・・・。それにうまくあわせても変数がおかしくなるような気が・・・。
yuki
会議室デビュー日: 2003/11/11
投稿数: 6
投稿日時: 2003-11-12 13:42
>かずくんさん

ありがとうございます。
Timerですか?調べてみます。
Thread周りがおかしいですか?そうですよね?
僕もそう思うのですが。。。具体的にどのようにすれば良いものでしょうか?

>begoodさん

ありがとうございます。確かにおかしいです。
余分な部分を載せないほうが良いと思ったので削除したのですが、
削除されていない部分がありました。申し訳ありませんでした。
多分、これで良いと思います。よろしくお願いします。

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

public class scroll_img extends Applet implements ActionListener, Runnable{

ImgCanvas image_canvas;
ScrollPane scrollPanel;
Image img1, img2, img3;
Panel pane = new Panel();
GridLayout gridLayout2 = new GridLayout(1,2);
Button btnNext = new Button("次へ");
Button btnPrv = new Button("戻る");
Panel btnPanel = new Panel();
Thread t1;
int imgFlg = 0;
int flg = 0;

public void init() {
setLayout(new BorderLayout());
img1 = getImage(getCodeBase(),"test\\gazo.gif");
img2 = getImage(getCodeBase(),"test\\icon.gif");
img3 = getImage(getCodeBase(),"test\\icon2.gif");
image_canvas = new ImgCanvas(img1, img2, img3);

image_canvas.setSize(500, 500);
scrollPanel = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);

scrollPanel.setSize(appWidth, appHeight);
scrollPanel.add(image_canvas);
add(scrollPanel, BorderLayout.CENTER);
Adjustable hor = scrollPanel.getHAdjustable();
hor.setUnitIncrement(20);
Adjustable ver = scrollPanel.getVAdjustable();
ver.setUnitIncrement(10);
btnPanel.setLayout(new GridLayout(1,2));
btnPanel.add(btnNext);
btnNext.addActionListener(this);
btnPanel.add(btnPrv);
btnPrv.addActionListener(this);
add(btnPanel,BorderLayout.NORTH);
}

public void actionPerformed(ActionEvent e){
if (e.getSource()==btnNext){
if (t1 == null){
t1 = new Thread(this);
t1.start();
imgFlg = 0;
}else{
t1.stop();
t1 = null;
t1 = new Thread(this);
t1.start();
imgFlg = 0;
}
}else if(e.getSource()==btnPrv){
if (t1 == null){
t1 = new Thread(this);
t1.start();
imgFlg = 1;
}else{
t1.stop();
t1 = null;
t1 = new Thread(this);
t1.start();
imgFlg = 1;
}
}
}
public void run(){
try {
while(true){
if(flg == 0) {
flg = 1;
}else{
flg = 0;
}
image_canvas.repaint();
t1.sleep(500);
}
} catch(Exception e){
System.out.println(e);
}
}

class ImgCanvas extends Canvas {
Image pic, pic1, pic2;
public ImgCanvas(Image img, Image img2, Image img3) {
pic = img;
pic1 = img2;
pic2 = img3;
}

public void paint(Graphics g) {
g.drawImage(pic, 30, 0, this);
g.drawImage(pic1, 40, 10, this);
g.drawImage(pic2, 90, 50, this);
if(flg == 1 && imgFlg == 0) {
g.drawImage(pic, 30, 0, this);
g.drawImage(pic2, 90, 50, this);
}else if(flg == 1 && imgFlg == 1) {
g.drawImage(pic, 30, 0, this);
g.drawImage(pic1, 40, 10, this);
}
}
}
begood
ベテラン
会議室デビュー日: 2003/09/12
投稿数: 97
お住まい・勤務地: とうきょー
投稿日時: 2003-11-12 17:21
コードを乗せるときにはそのまま乗せるようにしましょう。仕事をしていて、不具合かなんかでコードを誰かに送るときがあります。そのときに、途中を削ったりして送れば、とんでもないことになります。今回の場合、クラスファイルの途中で何かを削っているように見えます。たとえば、flgとimgFlgとか。

通常ちらつきがおきないようにするには、JAVAやSWにかかわらず、一度メモリに書いた画像をそのまま何か違うものに書き換えるにはメモリから画面に出力するまでに、画像の変換をさまざまな形で行うゆえ、バス幅の違い、処理速度の違いから、不具合があるようであれば初期化、メモリのクリアといったことを行います。よく、PCを立ち上げる際にすべての電子部品とか、初期化されてますよね。さまざまな切り替えの部分で初期化とは言わないまでも、同じようなことを行います。今回の場合、色々な言い方がありますが、オフスクリーンとか、ダミーとか、いったん画面を整える表示(実際に表示はさせなくてもよいですし、初期化なんてこともしなくてよいです。)をさせて、次の画面が表示される前に、画面上(メモリ上でもよいです)きれいにして、表示をさせます。そうすれば見た目きれいに見えます。他にもいろいろなやり方がありますが、この方法が一番オーソドックスかと思います。

最近フレームワークとか色々と生産性のことがあがっていて、このように考えることが世の中から消えつつあるので、自分にも言い聞かせたいのですが、やっていったほうが良いと思われます。
1

スキルアップ/キャリアアップ(JOB@IT)