
Swingアプリ開発ステップアップガイド
Swing初級から中級者向けに、4つの異なるアプリケーションを段階的に開発する方法を解説します。各アプリケーションは独立しており、難易度順に並んでいます。 ① […]
以下は、Swingを使用した基本的な画像ビューアアプリケーションの完全な実装例です。画像の表示、拡大/縮小、回転機能を備えています。
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class ImageViewerApp {
private static BufferedImage currentImage;
private static double scale = 1.0;
private static int rotation = 0;
private static JLabel imageLabel;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// メインウィンドウの作成
JFrame frame = new JFrame("画像ビューア");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
// 画像表示用ラベル
imageLabel = new JLabel("", SwingConstants.CENTER);
JScrollPane scrollPane = new JScrollPane(imageLabel);
frame.add(scrollPane, BorderLayout.CENTER);
// ツールバーの作成
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
// ツールバーボタン
JButton openButton = new JButton("開く");
JButton zoomInButton = new JButton("拡大");
JButton zoomOutButton = new JButton("縮小");
JButton rotateLeftButton = new JButton("左回転");
JButton rotateRightButton = new JButton("右回転");
JButton resetButton = new JButton("リセット");
// ボタンにアクションを追加
openButton.addActionListener(e -> openImage(frame));
zoomInButton.addActionListener(e -> zoom(1.25));
zoomOutButton.addActionListener(e -> zoom(0.8));
rotateLeftButton.addActionListener(e -> rotate(-90));
rotateRightButton.addActionListener(e -> rotate(90));
resetButton.addActionListener(e -> reset());
// ボタンをツールバーに追加
toolBar.add(openButton);
toolBar.addSeparator();
toolBar.add(zoomInButton);
toolBar.add(zoomOutButton);
toolBar.addSeparator();
toolBar.add(rotateLeftButton);
toolBar.add(rotateRightButton);
toolBar.addSeparator();
toolBar.add(resetButton);
frame.add(toolBar, BorderLayout.NORTH);
// ステータスバー
JLabel statusBar = new JLabel("準備完了");
frame.add(statusBar, BorderLayout.SOUTH);
frame.setVisible(true);
});
}
// 画像を開くメソッド
private static void openImage(JFrame parent) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter(
"画像ファイル", ImageIO.getReaderFileSuffixes()));
if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
try {
currentImage = ImageIO.read(selectedFile);
scale = 1.0;
rotation = 0;
updateImage();
} catch (Exception ex) {
JOptionPane.showMessageDialog(parent,
"画像を読み込めませんでした",
"エラー",
JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
}
// 画像をズームするメソッド
private static void zoom(double factor) {
scale *= factor;
updateImage();
}
// 画像を回転するメソッド
private static void rotate(int degrees) {
rotation += degrees;
rotation %= 360;
updateImage();
}
// 表示をリセットするメソッド
private static void reset() {
scale = 1.0;
rotation = 0;
updateImage();
}
// 画像表示を更新するメソッド
private static void updateImage() {
if (currentImage == null) return;
// 元の画像をコピー
BufferedImage image = new BufferedImage(
currentImage.getWidth(),
currentImage.getHeight(),
currentImage.getType());
Graphics2D g2d = image.createGraphics();
g2d.drawImage(currentImage, 0, 0, null);
g2d.dispose();
// 回転処理
if (rotation != 0) {
double radians = Math.toRadians(rotation);
double sin = Math.abs(Math.sin(radians));
double cos = Math.abs(Math.cos(radians));
int newWidth = (int) Math.floor(image.getWidth() * cos + image.getHeight() * sin);
int newHeight = (int) Math.floor(image.getHeight() * cos + image.getWidth() * sin);
BufferedImage rotated = new BufferedImage(newWidth, newHeight, image.getType());
Graphics2D g = rotated.createGraphics();
AffineTransform at = new AffineTransform();
at.translate(newWidth / 2, newHeight / 2);
at.rotate(radians);
at.translate(-image.getWidth() / 2, -image.getHeight() / 2);
g.setTransform(at);
g.drawImage(image, 0, 0, null);
g.dispose();
image = rotated;
}
// スケーリング処理
int scaledWidth = (int)(image.getWidth() * scale);
int scaledHeight = (int)(image.getHeight() * scale);
Image scaledImage = image.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);
// ラベルに画像を設定
imageLabel.setIcon(new ImageIcon(scaledImage));
}
}
ImageIO
を使用した画像読み込みAffineTransform
を使用した画像回転この基本実装をさらに発展させるためのアイデア:
例えば、画像保存機能を追加するには:
// ツールバーに保存ボタンを追加
JButton saveButton = new JButton("保存");
saveButton.addActionListener(e -> saveImage(frame));
toolBar.add(saveButton);
// 保存メソッドの実装
private static void saveImage(JFrame parent) {
if (currentImage == null) return;
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter(
"PNG画像", "png"));
if (fileChooser.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
if (!file.getName().toLowerCase().endsWith(".png")) {
file = new File(file.getAbsolutePath() + ".png");
}
try {
ImageIO.write(currentImage, "png", file);
} catch (IOException ex) {
JOptionPane.showMessageDialog(parent,
"画像を保存できませんでした",
"エラー",
JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
}
この画像ビューアアプリは、Swingでの画像処理の基本を理解するのに最適です。基本機能を実装した後、必要に応じて機能を追加していくことで、より実用的なアプリケーションに発展させることができます。