Java Appletの解説

<21.お絵かきソフト(その7)>

詳細な描画をするためには、拡大の機能が必要です。

1.拡大

20.「お絵かきソフト例題1」を改良したものです。ボタン(bmt8に拡大)が増えています。
1.<Javaファイル>
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.lang.Math;
public class tpaint11 extends Applet{
Graphics g;
//**bt1,bt2,bt3:色ボタン、bdisp選択された色を表示するボタン
Button bt1,bt2,bt3,bdisp;
//**bmt1,bmt2,bmt3 方法ボタン
Button bmt1,bmt2,bmt3,bmt4,bmt5,bmt6,bmt7,bmt8;
//**方法の変数chi(初期値chi=4は細線)
//**詳細処理の変数tadi、多角形(tadi=2)コピー(tadi=3)詳細処理なしは0
int chi=4,tadi=0;
//**入力表示ラベルpmeth(方法)pstr(入力文字)pkaku(拡大倍率)
Label pmeth,pstr,pkaku;
//**px1,py1マウスボタンが押された座標(px1,py1)
//**px2,py2マウスボタンがドラッグされた座標(px2,py2)
//**四角形表示の基準座標(xx1,yy1)
//**四角形表示の幅、高さ(w1,h1) int px1,py1,px2,py2,xx1,yy1,w1,h1;
//**多角形の点の配列
int xpl[]=new int[10],ypl[]=new int[10];
//**多角形の角カウント
int taka=0;
//**コピーのための座標
int xcc1,ycc1,wcc1,hcc1;
//**コピーのイメージ
ImageFilter cutfil;
Image cutimg;
//**重なりで色の変化しないためのオフスクリーン
Graphics offg;
Dimension offd,clo;
Image offImage;
//**gの色
int gclr=3;
//**文字入力のためのフィールドtf1、文字列sp
TextField tf1;
String sp;
//**スクロールバー、バーの座標scrx1,scry1
Scrollbar vbar,hbar;
int scrx1,scry1;
//**拡大判定フラッグchscr=1拡大;拡大時の座標(zoox,zooy)
byte chscr=0;
int zoox,zooy;
//**拡大時、切り取りの移動のため座標(cutxx,cutyy),cutw,cuth幅,高さ
//**zoom拡大chscr=0の時1、chscr=1の時0.5
int cutxx,cutyy,cutw,cuth;
float zoom=(float)1.0;
//**拡大時の表示場所(bxx1,byy1)始点、(bxx2,byy2)終点bw1,bh1幅,高さ
int bxx1,byy1,bxx2,byy2,bw1,bh1;
//**bpx,bpy多角形表示のためのマウスボタンが放されて時の座標
//**xw1,yh1コピー画像のX軸移動、Y軸移動距離
int bpx,bpy,xw1,yh1;
//**拡大用のイメージ
Graphics offgtmp;
Image offImagetmp;
public void init(){
setBackground(Color.white);
g=getGraphics();
offg=getGraphics();
setLayout(new BorderLayout());
Dimension clo=getSize();
offd=clo;
offImage=createImage(clo.width,clo.height);
offg=offImage.getGraphics();
//**拡大用のイメージ
offImagetmp=createImage(clo.width,clo.height);
offgtmp=offImagetmp.getGraphics();
//**<パネルの配置>
//**方法ボタンの配置
Panel p1=new Panel();
p1.setBackground(Color.green);
p1.setLayout(new GridLayout(7,2,0,0));
p1.add(new Label("方法;"));
p1.add(pmeth=new Label("細線"));
p1.add(new Label("拡大;"));
p1.add(pkaku=new Label("1倍"));
p1.add(bmt1=new Button("全消去"));
p1.add(bmt2=new Button("部分消去"));
p1.add(bmt3=new Button("中塗四角"));
p1.add(bmt4=new Button("細線"));
p1.add(bmt5=new Button("中塗多角"));
p1.add(bmt6=new Button("コピー"));
p1.add((bmt7=new Button("文字入力")));
p1.add((bmt8=new Button("拡大")));
p1.add(tf1=new TextField("",6));
p1.add(pstr=new Label("   "));
//**色ボタンの配置
add("West",p1);
Panel p2=new Panel();
p2.setBackground(Color.yellow);
p2.setFont(new Font("TimesRoman",Font.BOLD,20));
p2.add(bdisp=new Button(" "));
bdisp.setBackground(Color.black);
p2.add(new Label("選択"));
p2.add(bt1=new Button("blue"));
bt1.setBackground(Color.blue);
p2.add(bt2=new Button("red"));
bt2.setBackground(Color.red);
p2.add(bt3=new Button("black"));
bt3.setBackground(Color.black);
bt3.setForeground(Color.white);
add("South",p2);
//**拡大用のY軸スクロールバー
Panel p3=new Panel();
add("East",vbar=new Scrollbar(Scrollbar.VERTICAL,0,0,20,360));
//**拡大用のX軸スクロールバー
Panel p4=new Panel();
add("North",hbar=new Scrollbar(Scrollbar.HORIZONTAL,0,0,120,600));
//**ボタンのリスナー宣言
bmt1.addActionListener(new MyListener());
bmt2.addActionListener(new MyListener());
bmt3.addActionListener(new MyListener());
bmt4.addActionListener(new MyListener());
bmt5.addActionListener(new MyListener());
bmt6.addActionListener(new MyListener());
bmt7.addActionListener(new MyListener());
bmt8.addActionListener(new MyListener());
bt1.addActionListener(new MyListener());
bt2.addActionListener(new MyListener());
bt3.addActionListener(new MyListener());
//**スクロールバーのリスナー宣言
vbar.addAdjustmentListener(new BarListener());
hbar.addAdjustmentListener(new BarListener());
//**テクストフィールドのリスナー宣言
tf1.addActionListener(new StListener());
//**<<<マウスの処理>>>
addMouseListener(
new MouseAdapter(){
//**<<マウスボタンが押された時の処理>>
public void mousePressed(MouseEvent e){
//**初期化:xyzoo座標変換(拡大倍率により変わる)
//**マウスボタンが押された座標(px1,py1)
//**マウスボタンがドラッグされた座標(px2,py2)
xyzoo(e.getX(),e.getY());px1=zoox;py1=zooy;px2=zoox;py2=zooy;
w1=0;h1=0;xx1=0;yy1=0;xw1=0;yh1=0;
//**<多角形処理>
//**(bpx,bpy)マウスが放された時の座標、前の直線の終点を今回の始点にする
if (chi==5){if (taka==0) {xpl[0]=px1;ypl[0]=py1;}
else {px1=bpx;py1=bpy;}}
//**<文字入力:文字を表示>
if (chi==7){offg.drawString(sp,px1,py1);repaint();}}
//**<<マウスが放された時の処理>>
public void mouseReleased(MouseEvent e){
//**<中塗四角>
//**四角形の始点(xx1,yy1)、幅、高さ(w1,h1) if(chi==3){offg.fillRect(xx1,yy1,w1,h1);repaint();}
//**<中塗多角>
//**if (taka<9):9角形まで
//**(px1,py1)は前の直線の終点、(px2,py2)マウスが放された点
//**多角形の点の配列(xpl,ypl)
else if(chi==5){
if (taka<9){offg.drawLine(px1,py1,px2,py2);bpx=px2;bpy=py2;
taka=taka+1;xpl[taka]=px2;ypl[taka]=py2;}
else{chi=4;pmeth.setText("細線");}
repaint(); }
//**<コピー>
//**xcc1,ycc1は切り取りx,y座標,wcc1,hcc1は切り取りの幅,高さ
else if(chi==6){if (tadi==0){
tadi=3;xcc1=xx1;ycc1=yy1;wcc1=w1;hcc1=h1;w1=0;h1=0;
cutfil=new CropImageFilter(xcc1,ycc1,wcc1,hcc1);
cutimg=createImage(new FilteredImageSource(offImage.getSource(),cutfil)); }
//**redra(tadi);コピーしたイメージcutimgを最後にoffgに表示する>
else if(tadi==3) {tadi=0;redra(tadi);}
}}});
//**<<マウスドラッグ中の処理>>
addMouseMotionListener(
new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
//**マウスボタンがドラッグされた座標(px2,py2)
xyzoo(e.getX(),e.getY());px2=zoox;py2=zooy;
if(chi==2){offg.clearRect(px2,py2,20,20);repaint();}
//**中塗四角:revwh負方向の方向でも,四角が表示されるよう座標変換
else if(chi==3){revwh(px2,py2);repaint();}
else if(chi==4){offg.drawLine(px1,py1,px2,py2);px1=zoox;py1=zooy;repaint();}
else if(chi==5){repaint();}
else if(chi==6){if (tadi==3){xw1=(px2-px1);yh1=(py2-py1);w1=xw1;h1=yh1;repaint();}
else{revwh(px2,py2);repaint();}
}}});
}
//**<<ボタン処理>>
class MyListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//**方法ボタン処理
if(e.getSource()==bmt1){offg.clearRect(0,0,getSize().width-1,getSize().height-1);
repaint();tadi=0;taka=0;chi=1;pmeth.setText("全消去");}
else if(e.getSource()==bmt2){plydisp(tadi);tadi=0;taka=0;chi=2;pmeth.setText("部分消去");}
else if(e.getSource()==bmt3){plydisp(tadi);tadi=0;taka=0;chi=3;pmeth.setText("中塗四角");}
else if(e.getSource()==bmt4){plydisp(tadi);tadi=0;taka=0;chi=4;pmeth.setText("細線");}
else if(e.getSource()==bmt5){plydisp(tadi);tadi=2;taka=0;chi=5;pmeth.setText("中塗多角");}
else if(e.getSource()==bmt6){plydisp(tadi);tadi=0;taka=0;chi=6;pmeth.setText("コピー");}
else if(e.getSource()==bmt7){plydisp(tadi);tadi=0;taka=0;chi=7;pmeth.setText("文字入力");
sp="";pstr.setText(sp);tf1.setText("");tf1.requestFocus();}
else if(e.getSource()==bmt8){plydisp(tadi);chi=8;pmeth.setText("拡大");taka=0;
scrx1=120;scry1=20;vbar.setValue(0);hbar.setValue(0);
chscr=(byte)(chscr^1);zoom=(float)(1.0-chscr/2.0);
if (chscr==0){pkaku.setText("1倍");}
else {pkaku.setText("2倍");}
repaint();}
//**色ボタン処理
if(e.getSource()==bt1){offg.setColor(Color.blue);bdisp.setBackground(Color.blue);gclr=1;}
else if(e.getSource()==bt2){offg.setColor(Color.red);bdisp.setBackground(Color.red);gclr=2;}
else if(e.getSource()==bt3){offg.setColor(Color.black);bdisp.setBackground(Color.black);gclr=3;}
}}
//**<負方向の方向でも,四角が表示されるよう座標変換>
void revwh(int px2, int py2){
if (px1<=px2){xx1=px1;}
else {xx1=px2;}
if (py1<=py2){yy1=py1;}
else {yy1=py2;}
w1=Math.abs(px2-px1);
h1=Math.abs(py2-py1);
}
//**<多角形の表示をする。>
void plydisp(int tadi){
if (tadi==2){offg.fillPolygon(xpl,ypl,taka+1);}
repaint();
}
//**
public void paint(Graphics g){
update(g);
}
//**<<<描画>>>
public void update(Graphics g){
//**g上での色指定
if (gclr==1){g.setColor(Color.blue);}
else if(gclr==2){g.setColor(Color.red);}
else if(gclr==3){g.setColor(Color.black);}
//**<<拡大2倍時処理(chscr==1)>>
//**1.コピー時処理(tadi==3)
if (chscr==1){if (tadi==3){
offgtmp.drawImage(offImage,0,0,600,400,this);
g.drawImage(offImagetmp,-scrx1,-scry1,1200,800,this);
cutxx=(xcc1+xw1)*2-scrx1;
cutyy=(ycc1+yh1)*2-scry1;
cutw=wcc1*2;cuth=hcc1*2;
g.drawImage(cutimg,cutxx,cutyy,cutw,cuth,this);
}
//**2.コピー時以外の処理
else {bxx1=(xx1)*2-scrx1;byy1=(yy1)*2-scry1;
bw1=w1*2;bh1=h1*2;
offgtmp.drawImage(offImage,0,0,600,400,this);
g.drawImage(offImagetmp,-scrx1,-scry1,1200,800,this);
if (chi==3){g.fillRect(bxx1,byy1,bw1,bh1);}
else if (chi==5){gsxy(px1,py1,px2,py2);g.drawLine(bxx1,byy1,bxx2,byy2);}
else if (chi==6){g.drawRect(bxx1,byy1,bw1,bh1);}
} }
//**<<拡大1倍の時の処理>>
else {g.drawImage(offImage,0,0,this);
//**1.コピー時の処理(tadi==3)
if (tadi==3){g.drawImage(cutimg,xcc1+xw1,ycc1+yh1,this);}
//**2.コピー時以外の処理
else {
if (chi==3){g.fillRect(xx1,yy1,w1,h1);}
else if (chi==5){g.drawLine(px1,py1,px2,py2);}
else if (chi==6){g.drawRect(xx1,yy1,w1,h1);}
}}}
//**<コピーしたイメージcutimgの最後にoffgに表示する>
void redra(int tadi){
offg.drawImage(cutimg,xcc1+w1,ycc1+h1,this);
}
//**<テキストフィールド入力>
class StListener implements ActionListener{
public void actionPerformed(ActionEvent e){
TextField t=(TextField)e.getSource();
sp=t.getText();
pstr.setText(sp);
repaint();}}
//**<スクロールバー>
class BarListener implements AdjustmentListener{
public void adjustmentValueChanged(AdjustmentEvent e){
Scrollbar L=(Scrollbar)e.getSource();
if (L==hbar){scrx1=L.getValue();}
else {scry1=L.getValue();}
repaint();}}
//**<拡大した時の座標計算>
void xyzoo(int xxx,int yyy){
zoox=(int)Math.round(xxx*zoom+zoom*scrx1*chscr);
zooy=(int)Math.round(yyy*zoom+zoom*scry1*chscr);
}
//**<拡大時の描画座標計算>
void gsxy(int px1,int py1,int px2,int py2){
bxx1=(px1)*2-scrx1;byy1=(py1)*2-scry1;
bxx2=(px2)*2-scrx1;byy2=(py2)*2-scry1;
}

}
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
例1.ここをクリックして下さい。



トップページ

趣味のトップページ

娯楽室の各部屋
Aplletの解説へ戻る

Scriptの解説 Scriptのゲーム Appletのゲーム Linuxの部屋 物置部屋