イベント処理の基本概念
GUIプログラミングにおけるイベント処理は、ユーザー操作に対する応答を実現する重要な仕組みです。Javaでは主に3つの要素で構成されます。
イベントソース
イベントを発生させるオブジェクト(ボタン、テキストフィールドなど)で、リスナーの登録とイベントオブジェクトの送信を行います。
イベントリスナー
特定のリスナーインターフェースを実装したクラスのインスタンスで、イベント発生時に自動実行されるメソッドを定義します。
イベントオブジェクト
java.util.EventObjectクラスから派生したオブジェクトで、イベント関連情報をカプセル化します。
アクションイベントの実装
以下のコードはボタンクリックでパネルの背景色を変更する実装例です。ラムダ式を使用して簡潔に記述しています。
import javax.swing.*;
import java.awt.*;
public class ColorButtonFrame extends JFrame {
private JPanel mainPanel;
public ColorButtonFrame() {
mainPanel = new JPanel();
add(mainPanel);
createColorButton("黄色", Color.YELLOW);
createColorButton("青色", Color.BLUE);
createColorButton("赤色", Color.RED);
}
private void createColorButton(String label, Color color) {
JButton btn = new JButton(label);
btn.addActionListener(e -> mainPanel.setBackground(color));
mainPanel.add(btn);
}
public static void main(String[] args) {
JFrame frame = new ColorButtonFrame();
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
ルックアンドフィールの設定
GUIコンポーネントの外観を動的に変更する例を示します。
import javax.swing.*;
public class ThemeChanger {
public static void setupThemes(JFrame frame, JPanel panel) {
for (UIManager.LookAndFeelInfo info :
UIManager.getInstalledLookAndFeels()) {
JButton themeBtn = new JButton(info.getName());
themeBtn.addActionListener(e -> {
try {
UIManager.setLookAndFeel(info.getClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception ex) {
ex.printStackTrace();
}
});
panel.add(themeBtn);
}
}
}
マウスイベント処理
マウスクリックで図形を操作するコンポーネントの実装例です。
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
public class ShapeCanvas extends JComponent {
private ArrayList<Rectangle2D> shapes = new ArrayList<>();
private Rectangle2D selectedShape;
private final int SHAPE_SIZE = 15;
public ShapeCanvas() {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
selectedShape = findShapeAt(e.getPoint());
if (selectedShape == null) {
addNewShape(e.getPoint());
}
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 2) {
removeShapeAt(e.getPoint());
}
}
});
}
private Rectangle2D findShapeAt(Point2D point) {
return shapes.stream()
.filter(shape -> shape.contains(point))
.findFirst()
.orElse(null);
}
private void addNewShape(Point2D point) {
double x = point.getX() - SHAPE_SIZE / 2.0;
double y = point.getY() - SHAPE_SIZE / 2.0;
Rectangle2D newShape = new Rectangle2D.Double(
x, y, SHAPE_SIZE, SHAPE_SIZE);
shapes.add(newShape);
repaint();
}
private void removeShapeAt(Point2D point) {
Rectangle2D shape = findShapeAt(point);
if (shape != null) {
shapes.remove(shape);
repaint();
}
}
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
shapes.forEach(g2::draw);
}
}
名前抽選アプリケーション
ボタン操作でランダムに名前を表示する実用的なアプリケーション例です。
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
public class RandomNameSelector extends JFrame {
private JLabel nameLabel = new JLabel("", SwingConstants.CENTER);
private java.util.Timer timer;
private List<String> names;
public RandomNameSelector(List<String> nameList) {
names = nameList;
setupUI();
}
private void setupUI() {
setLayout(new BorderLayout());
nameLabel.setFont(new Font("Serif", Font.BOLD, 24));
nameLabel.setOpaque(true);
nameLabel.setBackground(Color.WHITE);
JButton toggleBtn = new JButton("開始");
toggleBtn.addActionListener(e -> {
if (toggleBtn.getText().equals("開始")) {
toggleBtn.setText("停止");
startRandomSelection();
} else {
toggleBtn.setText("開始");
stopRandomSelection();
}
});
add(nameLabel, BorderLayout.CENTER);
add(toggleBtn, BorderLayout.SOUTH);
setSize(300, 150);
}
private void startRandomSelection() {
timer = new java.util.Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
SwingUtilities.invokeLater(() -> {
String randomName = names.get(
(int) (Math.random() * names.size()));
nameLabel.setText(randomName);
});
}
}, 0, 100);
}
private void stopRandomSelection() {
if (timer != null) {
timer.cancel();
}
}
}