とりあえずウィンドウを表示して何かしたいとき使う基底クラスAbstractFrame
AbstractFrame
Java2Dを使って画面に何か出したいと思ったとき、適当なサイズのJFrameを作ってJPanel突っ込んでpaint(Graphics g)を実装して…という一連の流れが面倒なので、下記のようなabstract classを作っておいて、実際の場面ではこれをextendsして使ってます。
import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import javax.swing.JComponent; import javax.swing.JFrame; /** 単なるウィンドウ */ public abstract class AbstractFrame extends JFrame { private static final long serialVersionUID = 1L; private JComponent component; /** 初期化処理 */ public void initialize(int width, int height) { // パネルの初期化 component = new MainComponent(); getContentPane().add(component); // メインウィンドウの初期化 setDefaultCloseOperation(DISPOSE_ON_CLOSE); setResizable(false); setVisible(true); final Insets insets = getInsets(); setSize(width+insets.left+insets.right, height+insets.top+insets.bottom); } /** 終了処理 */ public void dispose() { System.exit(0); } /** 描画処理 */ public abstract void paint2D(Graphics2D g); /** 再描画の要請 */ public void requestRepaint() { if (component != null) component.repaint(); } /** 描画領域 */ class MainComponent extends JComponent { private static final long serialVersionUID = 1L; public void paint(Graphics g) { paint2D((Graphics2D) g); } public void update(Graphics g) { paint(g); } } }
この抽象クラスを継承したクラスでpaint2D(Graphics2D g)を実装して使います。画面の表示を更新したいときはrequestRepaint()を呼びます。
Javaでデジタル時計
使用例; 文字だけの時計。
import java.awt.Color; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Calendar; import javax.swing.SwingUtilities; import javax.swing.Timer; public class SamplePaint extends AbstractFrame implements ActionListener { public static void main(String[] args) { // Swingがらみの処理はEvent Dispatch Thread上でやる SwingUtilities.invokeLater(new Runnable() { public void run() { new SamplePaint(); } } } public SamplePaint() { initialize(320, 240); new Timer(1000, this).start(); } @Override public void paint2D(Graphics2D g) { g.setColor(Color.white); g.fillRect(0, 0, getWidth()-1, getHeight()-1); g.setColor(Color.black); final Calendar now = Calendar.getInstance(); final int h = now.get(Calendar.HOUR_OF_DAY), m = now.get(Calendar.MINUTE), s = now.get(Calendar.SECOND); g.drawString(""+h+":"+m+":"+s, 30, 30); } @Override public void actionPerformed(ActionEvent actionevent) { requestRepaint(); } }
initialize(int width, int height)に渡すのは描画領域の幅と高さです。ウィンドウ自体は、枠がある分、それより大きくなります。ウィンドウを閉じるボタンが押されるとプログラムが終了します。
SwingのTimerが発火するたびrequestRepaint()を呼んでいます。その中でpaint2D(Graphics2D g)が呼ばれ、時計の表示が更新されます。
…まぁ、これだけならProcessing使えばいいんですけどね。あ、最近ではJavaFXもあるか。