
Swingアプリ開発ステップアップガイド
Swing初級から中級者向けに、4つの異なるアプリケーションを段階的に開発する方法を解説します。各アプリケーションは独立しており、難易度順に並んでいます。 ① […]
以下は、Swingを使用した学生情報管理システムの完全な実装例です。学生情報の追加、編集、削除、一覧表示機能を備えています。
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class StudentManagementSystem {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// メインウィンドウの作成
JFrame frame = new JFrame("学生情報管理システム");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(900, 600);
// 学生データを保持するリスト
List students = new ArrayList<>();
loadStudentData(students); // 起動時にデータを読み込む
// テーブルモデルの作成
StudentTableModel tableModel = new StudentTableModel(students);
JTable table = new JTable(tableModel);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(table);
// ボタンパネルの作成
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JButton addButton = new JButton("追加");
JButton editButton = new JButton("編集");
JButton deleteButton = new JButton("削除");
JButton saveButton = new JButton("保存");
// ボタンにアクションを追加
addButton.addActionListener(e -> {
StudentDialog dialog = new StudentDialog(frame, "学生情報の追加", null);
if (dialog.showDialog()) {
students.add(dialog.getStudent());
tableModel.fireTableDataChanged();
}
});
editButton.addActionListener(e -> {
int selectedRow = table.getSelectedRow();
if (selectedRow >= 0) {
Student selectedStudent = students.get(selectedRow);
StudentDialog dialog = new StudentDialog(frame, "学生情報の編集", selectedStudent);
if (dialog.showDialog()) {
students.set(selectedRow, dialog.getStudent());
tableModel.fireTableDataChanged();
}
} else {
JOptionPane.showMessageDialog(frame,
"編集する学生を選択してください",
"警告",
JOptionPane.WARNING_MESSAGE);
}
});
deleteButton.addActionListener(e -> {
int selectedRow = table.getSelectedRow();
if (selectedRow >= 0) {
int confirm = JOptionPane.showConfirmDialog(frame,
"選択した学生を削除しますか?",
"確認",
JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
students.remove(selectedRow);
tableModel.fireTableDataChanged();
}
} else {
JOptionPane.showMessageDialog(frame,
"削除する学生を選択してください",
"警告",
JOptionPane.WARNING_MESSAGE);
}
});
saveButton.addActionListener(e -> {
saveStudentData(students);
JOptionPane.showMessageDialog(frame,
"データを保存しました",
"情報",
JOptionPane.INFORMATION_MESSAGE);
});
// ボタンをパネルに追加
buttonPanel.add(addButton);
buttonPanel.add(editButton);
buttonPanel.add(deleteButton);
buttonPanel.add(saveButton);
// メインウィンドウにコンポーネントを追加
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.setVisible(true);
});
}
// 学生データをファイルから読み込む
private static void loadStudentData(List students) {
File file = new File("students.dat");
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
List loadedStudents = (List) ois.readObject();
students.clear();
students.addAll(loadedStudents);
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(null,
"データの読み込みに失敗しました",
"エラー",
JOptionPane.ERROR_MESSAGE);
}
}
}
// 学生データをファイルに保存
private static void saveStudentData(List students) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students.dat"))) {
oos.writeObject(students);
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(null,
"データの保存に失敗しました",
"エラー",
JOptionPane.ERROR_MESSAGE);
}
}
}
// 学生情報を表すクラス(シリアライズ可能)
class Student implements Serializable {
private String studentId;
private String name;
private String department;
private int grade;
private String email;
public Student(String studentId, String name, String department, int grade, String email) {
this.studentId = studentId;
this.name = name;
this.department = department;
this.grade = grade;
this.email = email;
}
// ゲッターとセッター
public String getStudentId() { return studentId; }
public String getName() { return name; }
public String getDepartment() { return department; }
public int getGrade() { return grade; }
public String getEmail() { return email; }
public void setStudentId(String studentId) { this.studentId = studentId; }
public void setName(String name) { this.name = name; }
public void setDepartment(String department) { this.department = department; }
public void setGrade(int grade) { this.grade = grade; }
public void setEmail(String email) { this.email = email; }
}
// テーブルモデルの実装
class StudentTableModel extends AbstractTableModel {
private final List students;
private final String[] columnNames = {"学籍番号", "氏名", "学部", "学年", "メールアドレス"};
public StudentTableModel(List students) {
this.students = students;
}
@Override
public int getRowCount() {
return students.size();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Student student = students.get(rowIndex);
switch (columnIndex) {
case 0: return student.getStudentId();
case 1: return student.getName();
case 2: return student.getDepartment();
case 3: return student.getGrade();
case 4: return student.getEmail();
default: return null;
}
}
public Student getStudentAt(int rowIndex) {
return students.get(rowIndex);
}
}
// 学生情報編集ダイアログ
class StudentDialog extends JDialog {
private boolean approved = false;
private Student student;
private JTextField idField;
private JTextField nameField;
private JComboBox departmentCombo;
private JSpinner gradeSpinner;
private JTextField emailField;
public StudentDialog(Frame owner, String title, Student student) {
super(owner, title, true);
setSize(400, 300);
setLocationRelativeTo(owner);
this.student = (student == null) ?
new Student("", "", "情報学部", 1, "") :
new Student(student.getStudentId(), student.getName(),
student.getDepartment(), student.getGrade(), student.getEmail());
// フォームコンポーネントの作成
idField = new JTextField(this.student.getStudentId(), 15);
nameField = new JTextField(this.student.getName(), 15);
String[] departments = {"情報学部", "経済学部", "文学部", "理学部", "工学部"};
departmentCombo = new JComboBox<>(departments);
departmentCombo.setSelectedItem(this.student.getDepartment());
gradeSpinner = new JSpinner(new SpinnerNumberModel(this.student.getGrade(), 1, 4, 1));
emailField = new JTextField(this.student.getEmail(), 15);
// レイアウト設定
JPanel formPanel = new JPanel(new GridLayout(5, 2, 10, 10));
formPanel.add(new JLabel("学籍番号:"));
formPanel.add(idField);
formPanel.add(new JLabel("氏名:"));
formPanel.add(nameField);
formPanel.add(new JLabel("学部:"));
formPanel.add(departmentCombo);
formPanel.add(new JLabel("学年:"));
formPanel.add(gradeSpinner);
formPanel.add(new JLabel("メールアドレス:"));
formPanel.add(emailField);
// ボタンパネル
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JButton okButton = new JButton("OK");
JButton cancelButton = new JButton("キャンセル");
okButton.addActionListener(e -> {
approved = true;
updateStudent();
dispose();
});
cancelButton.addActionListener(e -> dispose());
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
// ダイアログにコンポーネントを追加
setLayout(new BorderLayout(10, 10));
add(formPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
private void updateStudent() {
student.setStudentId(idField.getText());
student.setName(nameField.getText());
student.setDepartment((String)departmentCombo.getSelectedItem());
student.setGrade((Integer)gradeSpinner.getValue());
student.setEmail(emailField.getText());
}
public boolean showDialog() {
setVisible(true);
return approved;
}
public Student getStudent() {
return student;
}
}
AbstractTableModel
を継承したカスタムテーブルモデルこの基本実装をさらに発展させるためのアイデア:
例えば、検索機能を追加するには:
// 検索パネルを追加
JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JTextField searchField = new JTextField(20);
JButton searchButton = new JButton("検索");
searchPanel.add(new JLabel("検索:"));
searchPanel.add(searchField);
searchPanel.add(searchButton);
// メインウィンドウに検索パネルを追加(NORTH領域)
frame.add(searchPanel, BorderLayout.NORTH);
// 検索ボタンのアクション
searchButton.addActionListener(e -> {
String keyword = searchField.getText().toLowerCase();
if (keyword.isEmpty()) {
// キーワードが空の場合は全件表示
tableModel.fireTableDataChanged();
} else {
// 検索実行(学籍番号、氏名、メールアドレスで部分一致)
List filtered = new ArrayList<>();
for (Student s : students) {
if (s.getStudentId().toLowerCase().contains(keyword) ||
s.getName().toLowerCase().contains(keyword) ||
s.getEmail().toLowerCase().contains(keyword)) {
filtered.add(s);
}
}
// フィルタリングされたデータで新しいテーブルモデルを作成
StudentTableModel filteredModel = new StudentTableModel(filtered);
table.setModel(filteredModel);
}
});
この学生情報管理システムは、Swingを使った実践的なアプリケーション開発の良い例です。基本機能を理解した後、必要に応じて機能を拡張していくことで、より実用的なシステムに発展させることができます。