
Swingアプリ開発ステップアップガイド
Swing初級から中級者向けに、4つの異なるアプリケーションを段階的に開発する方法を解説します。各アプリケーションは独立しており、難易度順に並んでいます。 ① […]
JDialog dialog = new JDialog(frame, "Hello Dialog", true);
dialog.setSize(300, 200);
dialog.setVisible(true);
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
System.out.println("Clicked at: " + e.getX() + "," + e.getY());
}
});
class MyPanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(50, 50, 100, 80);
}
}
CardLayout cardLayout = new CardLayout();
JPanel cardPanel = new JPanel(cardLayout);
cardPanel.add(new JPanel(), "Panel1");
cardPanel.add(new JPanel(), "Panel2");
component.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse entered");
}
public void mouseExited(MouseEvent e) {
System.out.println("Mouse exited");
}
});
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(50, 50, 100, 100);
}
JButton okButton = new JButton("OK");
okButton.addActionListener(e -> dialog.dispose());
dialog.add(okButton);
Point startPoint;
component.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
}
public void mouseReleased(MouseEvent e) {
Point endPoint = e.getPoint();
System.out.println("Dragged from " + startPoint + " to " + endPoint);
}
});
JButton nextButton = new JButton("Next");
nextButton.addActionListener(e -> cardLayout.next(cardPanel));
JDialog dialog = new JDialog(frame, "Modal Dialog", true);
// ダイアログ設定...
class DrawingPanel extends JPanel {
private List points = new ArrayList<>();
public DrawingPanel() {
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
points.add(e.getPoint());
repaint();
}
});
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for (int i = 1; i < points.size(); i++) {
g2.drawLine(points.get(i-1).x, points.get(i-1).y,
points.get(i).x, points.get(i).y);
}
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
GradientPaint gp = new GradientPaint(0, 0, Color.BLUE,
getWidth(), getHeight(), Color.CYAN);
g2d.setPaint(gp);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
JButton prevButton = new JButton("Previous");
prevButton.addActionListener(e -> cardLayout.previous(cardPanel));
JButton nextButton = new JButton("Next");
nextButton.addActionListener(e -> cardLayout.next(cardPanel));
addMouseWheelListener(e -> {
int rotation = e.getWheelRotation();
// 拡大縮小処理...
});
JTextField field1 = new JTextField(20);
JTextField field2 = new JTextField(20);
JButton okButton = new JButton("OK");
okButton.addActionListener(e -> {
String value1 = field1.getText();
String value2 = field2.getText();
// 値を使用...
dialog.dispose();
});
JPopupMenu popupMenu = new JPopupMenu();
// メニュー項目追加...
component.setComponentPopupMenu(popupMenu);
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(3)); // 太い線
g2d.drawLine(10, 10, 100, 10);
float[] dash = {5f, 3f};
g2d.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 1f, dash, 0f)); // 点線
g2d.drawLine(10, 20, 100, 20);
JLabel titleLabel = new JLabel("", JLabel.CENTER);
// カード切り替え時にタイトル更新
cardLayout.addLayoutComponent(cardPanel, "Title");
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
System.out.println("Double clicked");
}
}
});
if (dialog.showDialog() == DialogResult.OK) {
// ダイアログの結果に基づいて表示更新
}
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
setLocation(e.getXOnScreen() - getWidth()/2,
e.getYOnScreen() - getHeight()/2);
}
});
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawOval(50, 50, 100, 100);
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WizardExample {
private JFrame frame;
private JPanel cardPanel;
private CardLayout cardLayout;
private JButton prevButton, nextButton;
private int currentStep = 0;
private final int TOTAL_STEPS = 3;
public WizardExample() {
frame = new JFrame("ウィザード形式アプリケーション");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
// CardLayoutの設定
cardLayout = new CardLayout();
cardPanel = new JPanel(cardLayout);
// 各ステップのパネルを作成
for (int i = 0; i < TOTAL_STEPS; i++) {
JPanel stepPanel = new JPanel(new BorderLayout());
stepPanel.add(new JLabel("ステップ " + (i + 1) + "/" + TOTAL_STEPS, JLabel.CENTER), BorderLayout.CENTER);
// ステップごとに異なるコンポーネントを追加
switch (i) {
case 0:
stepPanel.add(new JLabel("基本情報を入力してください", JLabel.CENTER), BorderLayout.NORTH);
break;
case 1:
stepPanel.add(new JLabel("詳細情報を入力してください", JLabel.CENTER), BorderLayout.NORTH);
break;
case 2:
stepPanel.add(new JLabel("確認してください", JLabel.CENTER), BorderLayout.NORTH);
break;
}
cardPanel.add(stepPanel, "step" + i);
}
// ボタンパネル
JPanel buttonPanel = new JPanel();
prevButton = new JButton("前へ");
nextButton = new JButton("次へ");
JButton finishButton = new JButton("完了");
prevButton.setEnabled(false);
finishButton.setVisible(false);
// ボタンアクション
prevButton.addActionListener(e -> {
if (currentStep > 0) {
currentStep--;
cardLayout.previous(cardPanel);
updateButtons();
}
});
nextButton.addActionListener(e -> {
if (currentStep < TOTAL_STEPS - 1) {
currentStep++;
cardLayout.next(cardPanel);
updateButtons();
}
});
finishButton.addActionListener(e -> {
JOptionPane.showMessageDialog(frame, "処理が完了しました!");
frame.dispose();
});
buttonPanel.add(prevButton);
buttonPanel.add(nextButton);
buttonPanel.add(finishButton);
// フレームに追加
frame.add(cardPanel, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
private void updateButtons() {
prevButton.setEnabled(currentStep > 0);
nextButton.setEnabled(currentStep < TOTAL_STEPS - 1);
if (currentStep == TOTAL_STEPS - 1) {
nextButton.setVisible(false);
((JButton)((JPanel)nextButton.getParent()).getComponent(2)).setVisible(true);
} else {
nextButton.setVisible(true);
((JButton)((JPanel)nextButton.getParent()).getComponent(2)).setVisible(false);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(WizardExample::new);
}
}
List shapes = new ArrayList<>();
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
shapes.add(new Ellipse2D.Double(e.getX()-10, e.getY()-10, 20, 20));
repaint();
}
});
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
for (Shape shape : shapes) {
g2d.draw(shape);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
public class ShapeEditor {
private JFrame frame;
private DrawingPanel drawingPanel;
private ArrayList shapes = new ArrayList<>();
private Shape selectedShape = null;
private Point dragOffset;
public ShapeEditor() {
frame = new JFrame("図形エディタ");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
drawingPanel = new DrawingPanel();
drawingPanel.setBackground(Color.WHITE);
// 図形追加ボタン
JButton addRectButton = new JButton("四角形追加");
addRectButton.addActionListener(e -> {
shapes.add(new Rectangle2D.Double(50, 50, 100, 80));
drawingPanel.repaint();
});
JButton addCircleButton = new JButton("円追加");
addCircleButton.addActionListener(e -> {
shapes.add(new Ellipse2D.Double(50, 50, 100, 100));
drawingPanel.repaint();
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(addRectButton);
buttonPanel.add(addCircleButton);
frame.add(drawingPanel, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
class DrawingPanel extends JPanel {
public DrawingPanel() {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
// 図形選択
selectedShape = null;
for (Shape shape : shapes) {
if (shape.contains(e.getPoint())) {
selectedShape = shape;
dragOffset = new Point(
e.getX() - (int)((RectangularShape)shape).getX(),
e.getY() - (int)((RectangularShape)shape).getY()
);
break;
}
}
repaint();
}
public void mouseReleased(MouseEvent e) {
// 右クリックで図形削除
if (SwingUtilities.isRightMouseButton(e) && selectedShape != null) {
shapes.remove(selectedShape);
selectedShape = null;
repaint();
}
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if (selectedShape != null) {
// 図形移動
RectangularShape rectShape = (RectangularShape)selectedShape;
rectShape.setFrame(
e.getX() - dragOffset.x,
e.getY() - dragOffset.y,
rectShape.getWidth(),
rectShape.getHeight()
);
repaint();
}
}
});
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// すべての図形を描画
for (Shape shape : shapes) {
if (shape == selectedShape) {
g2d.setColor(Color.BLUE);
g2d.setStroke(new BasicStroke(2));
} else {
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(1));
}
g2d.draw(shape);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(ShapeEditor::new);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.*;
public class ComplexDialogExample {
public static void main(String[] args) {
JFrame frame = new JFrame("メインウィンドウ");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
JButton showDialogButton = new JButton("ダイアログを表示");
showDialogButton.addActionListener(e -> showCustomDialog(frame));
frame.add(showDialogButton);
frame.setVisible(true);
}
private static void showCustomDialog(JFrame parent) {
// カスタムダイアログの作成
JDialog dialog = new JDialog(parent, "高度な検索", true);
dialog.setSize(500, 400);
dialog.setLayout(new BorderLayout());
// タブ付きペイン
JTabbedPane tabbedPane = new JTabbedPane();
// 1つ目のタブ - 検索条件
JPanel searchPanel = new JPanel(new BorderLayout());
// 検索フィールド
JPanel searchFieldPanel = new JPanel();
JTextField searchField = new JTextField(20);
JButton searchButton = new JButton("検索");
searchFieldPanel.add(new JLabel("検索語:"));
searchFieldPanel.add(searchField);
searchFieldPanel.add(searchButton);
// フィルターオプション
JPanel filterPanel = new JPanel(new GridLayout(0, 2, 5, 5));
filterPanel.setBorder(BorderFactory.createTitledBorder("フィルターオプション"));
JCheckBox caseSensitiveCheck = new JCheckBox("大文字小文字を区別");
JCheckBox wholeWordCheck = new JCheckBox("単語単位で検索");
JComboBox fileTypeCombo = new JComboBox<>(new String[]{"すべてのファイル", "テキストファイル", "画像ファイル", "PDF"});
filterPanel.add(caseSensitiveCheck);
filterPanel.add(wholeWordCheck);
filterPanel.add(new JLabel("ファイルタイプ:"));
filterPanel.add(fileTypeCombo);
searchPanel.add(searchFieldPanel, BorderLayout.NORTH);
searchPanel.add(filterPanel, BorderLayout.CENTER);
// 2つ目のタブ - 検索結果
JPanel resultsPanel = new JPanel(new BorderLayout());
DefaultListModel resultsModel = new DefaultListModel<>();
JList resultsList = new JList<>(resultsModel);
JScrollPane scrollPane = new JScrollPane(resultsList);
// ダミーデータを追加
for (int i = 1; i <= 20; i++) {
resultsModel.addElement("検索結果 " + i);
}
resultsPanel.add(scrollPane, BorderLayout.CENTER);
// タブを追加
tabbedPane.addTab("検索条件", searchPanel);
tabbedPane.addTab("検索結果", resultsPanel);
// 下部ボタンパネル
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JButton okButton = new JButton("OK");
JButton cancelButton = new JButton("キャンセル");
JButton applyButton = new JButton("適用");
buttonPanel.add(applyButton);
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
// ダイアログにコンポーネントを追加
dialog.add(tabbedPane, BorderLayout.CENTER);
dialog.add(buttonPanel, BorderLayout.SOUTH);
// ボタンアクション
okButton.addActionListener(e -> {
System.out.println("OKがクリックされました");
dialog.dispose();
});
cancelButton.addActionListener(e -> dialog.dispose());
// 検索ボタンのアクション
searchButton.addActionListener(e -> {
String searchText = searchField.getText();
if (!searchText.isEmpty()) {
tabbedPane.setSelectedIndex(1); // 結果タブに切り替え
// ここで実際の検索処理を行う
}
});
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
public class MouseGestureRecognizer {
private JFrame frame;
private DrawingPanel drawingPanel;
private List mousePath = new ArrayList<>();
private Timer gestureTimer;
// ジェスチャーコマンド
private enum GestureCommand { OPEN, SAVE, DELETE, COPY, PASTE, UNKNOWN }
public MouseGestureRecognizer() {
frame = new JFrame("マウスジェスチャー認識");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
drawingPanel = new DrawingPanel();
frame.add(drawingPanel, BorderLayout.CENTER);
JLabel statusLabel = new JLabel(" 右ボタンを押しながらマウスを動かしてジェスチャーを描いてください ");
frame.add(statusLabel, BorderLayout.SOUTH);
// ジェスチャー認識用タイマー
gestureTimer = new Timer(1000, e -> {
if (!mousePath.isEmpty()) {
GestureCommand command = recognizeGesture(mousePath);
statusLabel.setText("認識されたコマンド: " + command);
mousePath.clear();
drawingPanel.repaint();
}
});
gestureTimer.setRepeats(false);
frame.setVisible(true);
}
class DrawingPanel extends JPanel {
public DrawingPanel() {
setBackground(Color.WHITE);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
mousePath.clear();
mousePath.add(e.getPoint());
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e) && mousePath.size() > 1) {
gestureTimer.restart();
}
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
mousePath.add(e.getPoint());
repaint();
}
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// マウスパスを描画
if (mousePath.size() > 1) {
g2d.setColor(Color.BLUE);
g2d.setStroke(new BasicStroke(2));
for (int i = 1; i < mousePath.size(); i++) {
Point p1 = mousePath.get(i-1);
Point p2 = mousePath.get(i);
g2d.drawLine(p1.x, p1.y, p2.x, p2.y);
}
}
}
}
private GestureCommand recognizeGesture(List path) {
if (path.size() < 3) return GestureCommand.UNKNOWN;
// 単純な方向ベースのジェスチャー認識
Point first = path.get(0);
Point last = path.get(path.size()-1);
// 水平方向の動き
if (Math.abs(last.y - first.y) < 50) {
if (last.x > first.x + 100) return GestureCommand.OPEN;
if (last.x < first.x - 100) return GestureCommand.SAVE;
}
// 垂直方向の動き
if (Math.abs(last.x - first.x) < 50) {
if (last.y > first.y + 100) return GestureCommand.DELETE;
if (last.y < first.y - 100) return GestureCommand.COPY;
}
// 円形の動き
double radius = calculateAverageRadius(path);
if (radius > 30 && radius < 150) {
return GestureCommand.PASTE;
}
return GestureCommand.UNKNOWN;
}
private double calculateAverageRadius(List path) {
if (path.size() < 3) return 0;
// 中心点を計算
int sumX = 0, sumY = 0;
for (Point p : path) {
sumX += p.x;
sumY += p.y;
}
Point center = new Point(sumX / path.size(), sumY / path.size());
// 平均半径を計算
double totalRadius = 0;
for (Point p : path) {
totalRadius += center.distance(p);
}
return totalRadius / path.size();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(MouseGestureRecognizer::new);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.awt.TexturePaint;
public class AdvancedGraphicsExample extends JFrame {
private DrawingPanel drawingPanel;
public AdvancedGraphicsExample() {
setTitle("高度なグラフィックス描画");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawingPanel = new DrawingPanel();
add(drawingPanel, BorderLayout.CENTER);
setVisible(true);
}
class DrawingPanel extends JPanel {
private BufferedImage texture;
public DrawingPanel() {
// テクスチャ画像を作成
texture = new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = texture.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, 20, 20);
g2d.setColor(Color.BLUE);
g2d.drawLine(0, 0, 20, 20);
g2d.drawLine(20, 0, 0, 20);
g2d.dispose();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// 背景のグラデーション
GradientPaint gradient = new GradientPaint(0, 0, new Color(240, 240, 240),
getWidth(), getHeight(), Color.WHITE);
g2d.setPaint(gradient);
g2d.fillRect(0, 0, getWidth(), getHeight());
// 影付きの四角形
drawShapeWithShadow(g2d, new Rectangle2D.Double(50, 50, 200, 150),
new Color(70, 130, 180), 5);
// テクスチャ付きの円
TexturePaint texturePaint = new TexturePaint(texture,
new Rectangle2D.Double(0, 0, texture.getWidth(), texture.getHeight()));
g2d.setPaint(texturePaint);
Ellipse2D circle = new Ellipse2D.Double(300, 100, 200, 200);
g2d.fill(circle);
// 透明な図形
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f));
g2d.setColor(new Color(220, 20, 60));
g2d.fill(new RoundRectangle2D.Double(400, 350, 250, 150, 30, 30));
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
// 複雑なパス(星形)
GeneralPath star = new GeneralPath();
star.moveTo(150, 350);
star.lineTo(180, 450);
star.lineTo(100, 390);
star.lineTo(200, 390);
star.lineTo(120, 450);
star.closePath();
// グラデーションで塗りつぶし
GradientPaint starGradient = new GradientPaint(150, 350, Color.YELLOW,
200, 450, Color.ORANGE);
g2d.setPaint(starGradient);
g2d.fill(star);
// 太い境界線
g2d.setStroke(new BasicStroke(5));
g2d.setColor(Color.BLACK);
g2d.draw(star);
// テキストの描画(影付き)
Font font = new Font("Serif", Font.BOLD | Font.ITALIC, 48);
g2d.setFont(font);
String text = "Swing Graphics";
// 影
g2d.setColor(new Color(0, 0, 0, 100));
g2d.drawString(text, 253, 303);
// メインテキスト
g2d.setColor(new Color(30, 144, 255));
g2d.drawString(text, 250, 300);
}
private void drawShapeWithShadow(Graphics2D g2d, Shape shape, Color color, int shadowSize) {
// 影を描画
g2d.setColor(new Color(0, 0, 0, 50));
for (int i = 1; i <= shadowSize; i++) {
AffineTransform shadowTransform = AffineTransform.getTranslateInstance(i, i);
g2d.fill(shadowTransform.createTransformedShape(shape));
}
// 図形を描画
GradientPaint shapeGradient = new GradientPaint(
(float)shape.getBounds().getMinX(),
(float)shape.getBounds().getMinY(),
color.brighter(),
(float)shape.getBounds().getMaxX(),
(float)shape.getBounds().getMaxY(),
color.darker());
g2d.setPaint(shapeGradient);
g2d.fill(shape);
g2d.setColor(color.darker().darker());
g2d.setStroke(new BasicStroke(2));
g2d.draw(shape);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(AdvancedGraphicsExample::new);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Stack;
public class NavigationSystem {
private JFrame frame;
private JPanel cardPanel;
private CardLayout cardLayout;
private Stack history = new Stack<>();
private JButton backButton, forwardButton;
private String currentCard;
public NavigationSystem() {
frame = new JFrame("履歴管理システム");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 400);
// CardLayoutの設定
cardLayout = new CardLayout();
cardPanel = new JPanel(cardLayout);
// カード(画面)を追加
String[] cards = {"ホーム", "製品", "サービス", "お問い合わせ", "設定"};
for (String card : cards) {
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel(card + "画面", JLabel.CENTER), BorderLayout.CENTER);
// 各カードに移動用ボタンを追加
JPanel navPanel = new JPanel();
for (String navCard : cards) {
if (!navCard.equals(card)) {
JButton navButton = new JButton(navCard + "へ");
navButton.addActionListener(e -> navigateTo(navCard));
navPanel.add(navButton);
}
}
panel.add(navPanel, BorderLayout.SOUTH);
cardPanel.add(panel, card);
}
// ナビゲーションボタン
backButton = new JButton("← 戻る");
forwardButton = new JButton("進む →");
JButton homeButton = new JButton("ホーム");
backButton.setEnabled(false);
forwardButton.setEnabled(false);
// ボタンアクション
backButton.addActionListener(e -> goBack());
forwardButton.addActionListener(e -> goForward());
homeButton.addActionListener(e -> navigateTo("ホーム"));
JPanel controlPanel = new JPanel();
controlPanel.add(backButton);
controlPanel.add(forwardButton);
controlPanel.add(homeButton);
// 初期画面表示
navigateTo("ホーム");
frame.add(cardPanel, BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
private void navigateTo(String cardName) {
if (currentCard != null && !currentCard.equals(cardName)) {
history.push(currentCard);
backButton.setEnabled(true);
forwardButton.setEnabled(false);
}
currentCard = cardName;
cardLayout.show(cardPanel, cardName);
}
private void goBack() {
if (!history.isEmpty()) {
String previousCard = history.pop();
forwardButton.setEnabled(true);
if (history.isEmpty()) {
backButton.setEnabled(false);
}
cardLayout.show(cardPanel, previousCard);
currentCard = previousCard;
}
}
private void goForward() {
// 簡易実装(実際には進む履歴も管理する必要あり)
forwardButton.setEnabled(false);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(NavigationSystem::new);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
public class InteractiveShapeEditor extends JFrame {
private DrawingPanel drawingPanel;
private List shapes = new ArrayList<>();
private Shape selectedShape = null;
private Point dragStartPoint;
private int resizeHandle = -1; // リサイズハンドルのインデックス (-1 = 選択なし)
private final int HANDLE_SIZE = 8;
// 図形の種類
private enum ShapeType { RECTANGLE, ELLIPSE, LINE }
private ShapeType currentShapeType = ShapeType.RECTANGLE;
public InteractiveShapeEditor() {
setTitle("インタラクティブ図形編集ツール");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawingPanel = new DrawingPanel();
add(drawingPanel, BorderLayout.CENTER);
// ツールバーの作成
JToolBar toolBar = new JToolBar();
// 図形選択ボタン
ButtonGroup shapeGroup = new ButtonGroup();
JToggleButton rectButton = new JToggleButton("四角形", true);
JToggleButton ellipseButton = new JToggleButton("円");
JToggleButton lineButton = new JToggleButton("直線");
rectButton.addActionListener(e -> currentShapeType = ShapeType.RECTANGLE);
ellipseButton.addActionListener(e -> currentShapeType = ShapeType.ELLIPSE);
lineButton.addActionListener(e -> currentShapeType = ShapeType.LINE);
shapeGroup.add(rectButton);
shapeGroup.add(ellipseButton);
shapeGroup.add(lineButton);
toolBar.add(rectButton);
toolBar.add(ellipseButton);
toolBar.add(lineButton);
// 色選択ボタン
JButton colorButton = new JButton("色選択");
colorButton.addActionListener(e -> {
Color newColor = JColorChooser.showDialog(this, "色を選択", Color.RED);
if (newColor != null && selectedShape != null) {
drawingPanel.setShapeColor(selectedShape, newColor);
}
});
toolBar.add(colorButton);
// 削除ボタン
JButton deleteButton = new JButton("削除");
deleteButton.addActionListener(e -> {
if (selectedShape != null) {
shapes.remove(selectedShape);
selectedShape = null;
drawingPanel.repaint();
}
});
toolBar.add(deleteButton);
add(toolBar, BorderLayout.NORTH);
setVisible(true);
}
class DrawingPanel extends JPanel {
private HashMap shapeColors = new HashMap<>();
private HashMap shapeStrokes = new HashMap<>();
public DrawingPanel() {
setBackground(Color.WHITE);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
dragStartPoint = e.getPoint();
selectedShape = null;
resizeHandle = -1;
// 既存の図形を選択
for (Shape shape : shapes) {
if (shape.contains(e.getPoint())) {
selectedShape = shape;
break;
}
}
// リサイズハンドルをチェック
if (selectedShape != null) {
resizeHandle = getResizeHandleAt(e.getPoint(), selectedShape);
}
// 新しい図形を作成
if (selectedShape == null && !SwingUtilities.isRightMouseButton(e)) {
createNewShape(e.getPoint());
}
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
if (selectedShape != null && e.getPoint().equals(dragStartPoint)) {
// クリックのみ(ドラッグなし)の場合は選択状態のみ変更
}
repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if (selectedShape != null) {
if (resizeHandle >= 0) {
// リサイズ処理
resizeShape(e.getPoint());
} else {
// 移動処理
moveShape(e.getPoint());
}
repaint();
}
}
});
}
private void createNewShape(Point p) {
Shape newShape = null;
Color color = new Color(
(int)(Math.random() * 256),
(int)(Math.random() * 256),
(int)(Math.random() * 256)
);
switch (currentShapeType) {
case RECTANGLE:
newShape = new Rectangle2D.Double(p.x, p.y, 1, 1);
break;
case ELLIPSE:
newShape = new Ellipse2D.Double(p.x, p.y, 1, 1);
break;
case LINE:
newShape = new Line2D.Double(p.x, p.y, p.x, p.y);
break;
}
shapes.add(newShape);
selectedShape = newShape;
shapeColors.put(newShape, color);
shapeStrokes.put(newShape, new BasicStroke(2));
}
private void moveShape(Point p) {
double dx = p.x - dragStartPoint.x;
double dy = p.y - dragStartPoint.y;
dragStartPoint = p;
if (selectedShape instanceof Rectangle2D) {
Rectangle2D rect = (Rectangle2D)selectedShape;
rect.setRect(
rect.getX() + dx,
rect.getY() + dy,
rect.getWidth(),
rect.getHeight()
);
} else if (selectedShape instanceof Ellipse2D) {
Ellipse2D ellipse = (Ellipse2D)selectedShape;
ellipse.setFrame(
ellipse.getX() + dx,
ellipse.getY() + dy,
ellipse.getWidth(),
ellipse.getHeight()
);
} else if (selectedShape instanceof Line2D) {
Line2D line = (Line2D)selectedShape;
line.setLine(
line.getX1() + dx,
line.getY1() + dy,
line.getX2() + dx,
line.getY2() + dy
);
}
}
private void resizeShape(Point p) {
if (selectedShape instanceof Rectangle2D) {
Rectangle2D rect = (Rectangle2D)selectedShape;
double newWidth = p.x - rect.getX();
double newHeight = p.y - rect.getY();
if (newWidth > 10 && newHeight > 10) {
rect.setRect(
rect.getX(),
rect.getY(),
newWidth,
newHeight
);
}
} else if (selectedShape instanceof Ellipse2D) {
Ellipse2D ellipse = (Ellipse2D)selectedShape;
double newWidth = p.x - ellipse.getX();
double newHeight = p.y - ellipse.getY();
if (newWidth > 10 && newHeight > 10) {
ellipse.setFrame(
ellipse.getX(),
ellipse.getY(),
newWidth,
newHeight
);
}
} else if (selectedShape instanceof Line2D) {
Line2D line = (Line2D)selectedShape;
line.setLine(
line.getX1(),
line.getY1(),
p.x,
p.y
);
}
}
private int getResizeHandleAt(Point p, Shape shape) {
if (shape instanceof Rectangle2D || shape instanceof Ellipse2D) {
Rectangle2D bounds = shape.getBounds2D();
Point2D[] handles = {
new Point2D.Double(bounds.getMaxX(), bounds.getMaxY()), // 右下
new Point2D.Double(bounds.getMinX(), bounds.getMaxY()), // 左下
new Point2D.Double(bounds.getMaxX(), bounds.getMinY()), // 右上
new Point2D.Double(bounds.getMinX(), bounds.getMinY()) // 左上
};
for (int i = 0; i < handles.length; i++) {
if (p.distance(handles[i]) < HANDLE_SIZE) {
return i;
}
}
}
return -1;
}
public void setShapeColor(Shape shape, Color color) {
shapeColors.put(shape, color);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// すべての図形を描画
for (Shape shape : shapes) {
if (shape == selectedShape) {
g2d.setColor(shapeColors.get(shape).darker());
g2d.setStroke(new BasicStroke(3));
} else {
g2d.setColor(shapeColors.get(shape));
g2d.setStroke(shapeStrokes.get(shape));
}
g2d.draw(shape);
// 選択された図形のリサイズハンドルを描画
if (shape == selectedShape &&
(shape instanceof Rectangle2D || shape instanceof Ellipse2D)) {
Rectangle2D bounds = shape.getBounds2D();
g2d.setColor(Color.BLUE);
g2d.fillRect(
(int)bounds.getMaxX() - HANDLE_SIZE/2,
(int)bounds.getMaxY() - HANDLE_SIZE/2,
HANDLE_SIZE, HANDLE_SIZE
);
}
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new InteractiveShapeEditor());
}
}