Java GUIにおけるイベント処理の基礎と実装

イベント処理の基本概念

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();
        }
    }
}

タグ: Java Swing AWT イベント処理 マウスイベント

7月17日 21:34 投稿