でか文字表示ツールを作ってみよう3
いきなり汎用的な(抽象化した)コードを書こうとして行き詰まるよりは
まずは具体的なコードを書いてみるのが近道です。
毎度、管理人イガジーです。
ですから、堂々とハリボテ(見かけだけ)のプログラムを書いてみましょう。
その具体的なコードから、ひとつひとつ一般化してゆけばよいのです。
という訳で、実際に入力された文字やサイズに応じて、文字を描画する
一般化されたメソッドを作ります。
元にするのは、ハリボテの次のコードです。
// ハリボテ(決め打ち)のコード
cv.g.setColor(Color.WHITE);
cv.g.fillRect(0, 0, gbWIDTH, gbHEIGHT); // バッファ全体をクリア
cv.g.setFont(new Font(Font.SERIF,Font.PLAIN,300));
cv.g.setColor(Color.BLACK);
cv.g.drawString("漢", 0, 300);
この、表示している文字”漢”の部分を、TextField ch から得てくるようにします。
"漢" → ch.getText();
同様に、300 の部分をTextField sz から得るようにするのですが
TextFieldから得られるのは文字なので、数値に変換します。
あわせて、変な入力(数字以外の入力)や、最大最小の範囲チェックも
行う文字数値変換メソッドを作っておきましょう。
int getnum(TextField tf, int def,int min, int max) {
int r=def;
try {
r=Integer.parseInt(tf.getText());
}catch (Exception e) {
r=def;
}
if (r<min) {
r=min;
}else if (r>max) {
r=max;
}
tf.setText(Integer.toString(r));
return r;
}
引数の def は、異常値(数字以外等)の時にセットする値で
minは 最小値、max は最大値で、その範囲に丸め込むようにしています。
tf.setText(Integer.toString(r));
は、丸め込みなどの結果を表示にフィードバックするための処理です。
Choice fsel から、選ばれているものを得るには
fsel.getSelectedItem()
とします。
これらを使って、文字を描画するメソッドは次のような感じになります。
void drawChar() {
int fsize=getnum(sz,300,14,340);
cv.g.setColor(Color.WHITE); // 白で
cv.g.fillRect(0, 0, gbWIDTH, gbHEIGHT); // バッファをクリア
cv.g.setFont(new Font(fsel.getSelectedItem(),Font.PLAIN,fsize));
cv.g.setColor(Color.BLACK);
cv.g.drawString(ch.getText(), 0, fsize);
cv.repaint(); //再描画
}
最後のcv.repaint()は再描画のおまじないです。
さて、この文字描画メソッドは、いつ動作するようにしましょうか?
・TextFiled ch に文字が入力されたら
・Choice fsel でフォントが選ばれたら
・TextFiled ch にサイズが入力されたら
が自然ですね。
TextFiled に入力が行われた事を検出したいのですが、
入力の「完了」となるイベントは、[Enter]キーを押した時に発生します。
すなわち、300 を 200 に書き換えただけではそれを検出できず
[Enter]が押されてはじめて処理が行えるのです。
実際に、TextFieldにActionListenerを組み込んで試してみてください。
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
class BigFont2 extends Frame implements ActionListener {
private static final long serialVersionUID = 1L;
final int gbWIDTH=800,gbHEIGHT=400;
MyCanvas cv;
Choice fsel=new Choice();
TextField ch,sz;
BigFont2() { // constructor
String [] fontlist={
"Serif",
"SansSerif",
"Monospaced",
"Meiryo",
"MS Gothic",
"MS Mincho",
"Osaka",
"VLgothic",
"IPAGothic",
"IPAMincho"
};
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
this.setTitle("でか文字");
cv=new MyCanvas(gbWIDTH,gbHEIGHT);
this.add(cv,BorderLayout.CENTER);
for (int i=0;i<fontlist.length;++i){
fsel.add(fontlist[i]);
}
Panel p0=new Panel();
p0.add(new Label("文字"));
ch=new TextField("漢",4);
ch.addActionListener(this);
p0.add(ch);
p0.add(fsel);
p0.add(new Label("サイズ"));
sz=new TextField("300",4);
sz.addActionListener(this);
p0.add(sz);
this.add(p0,BorderLayout.NORTH);
drawChar(); //
this.setSize(400,440);
this.setVisible(true);
}
int getnum(TextField tf, int def,int min, int max) {
int r=def;
try {
r=Integer.parseInt(tf.getText());
}catch (Exception e) {
r=def;
}
if (r<min) {
r=min;
}else if (r>max) {
r=max;
}
tf.setText(Integer.toString(r));
return r;
}
void drawChar() {
int fsize=getnum(sz,300,14,340);
cv.g.setColor(Color.WHITE);
cv.g.fillRect(0, 0, gbWIDTH, gbHEIGHT);
cv.g.setFont(new Font(fsel.getSelectedItem(),Font.PLAIN,fsize));
cv.g.setColor(Color.BLACK);
cv.g.drawString(ch.getText(), 0, fsize);
cv.repaint(); //
}
public static void main(String[] args) {
new BigFont2();
}
@Override
public void actionPerformed(ActionEvent arg0) {
drawChar();
}
class MyCanvas extends Canvas {
private static final long serialVersionUID = 1L;
BufferedImage bi;
Graphics g=null;
MyCanvas(int ww,int hh) {
bi=new BufferedImage(ww,hh,BufferedImage.TYPE_INT_RGB);
g=bi.getGraphics();
}
@Override
public void paint(Graphics g0){
g0.drawImage(bi, 0, 0, null);
}
}
}
[Enter]キーを押すのはイマイチなので、次回はフォーカス移動でも描画する
ようにしてみましょう。フォーカス移動とは、TextFiled以外をクリックして
そのTextField からフォーカスが失われた(別のものにフォーカスが当たった)という
イベントを使います(FocusListenerを組み込みます)。
併せて、Choiceでフォントが選ばれた時も描画するようにしましょう。
Choiceでの選択は、ItemListener を組み込んで検出します。
次回のソースコード例の公開前に、ぜひご自身でコードを書いてみてください。
ご意見、ご質問、リクエストなどは、お気軽にメールフォームからどうぞ。
この記事へのコメントはこちら