
Swingアプリ開発ステップアップガイド
Swing初級から中級者向けに、4つの異なるアプリケーションを段階的に開発する方法を解説します。各アプリケーションは独立しており、難易度順に並んでいます。 ① […]
Swingには基本的なコンポーネントに加え、より複雑なデータ表示や操作が可能な高度なコンポーネントが用意されています。これらのコンポーネントを活用することで、本格的なアプリケーションのインターフェースを構築できます。
JTableを使ったデータ表表示の例
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class SimpleTableExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("JTable基本例");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// テーブルデータの作成
Object[][] data = {
{"田中太郎", 25, "東京"},
{"山田花子", 30, "大阪"},
{"佐藤健二", 28, "福岡"}
};
// カラム名
String[] columns = {"名前", "年齢", "住所"};
// テーブルモデルの作成
DefaultTableModel model = new DefaultTableModel(data, columns) {
@Override
public boolean isCellEditable(int row, int column) {
return false; // セル編集不可
}
};
// JTableの作成
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane);
frame.setVisible(true);
});
}
}
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.util.List;
public class CustomTableModelExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("カスタムテーブルモデル例");
frame.setSize(600, 400);
// カスタムモデルの作成
ProductTableModel model = new ProductTableModel(List.of(
new Product("ノートPC", 120000, 10),
new Product("スマートフォン", 80000, 15),
new Product("タブレット", 50000, 8)
));
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane);
frame.setVisible(true);
});
}
}
class ProductTableModel extends AbstractTableModel {
private final List<Product> products;
private final String[] columns = {"商品名", "価格", "在庫数"};
public ProductTableModel(List<Product> products) {
this.products = products;
}
@Override
public int getRowCount() {
return products.size();
}
@Override
public int getColumnCount() {
return columns.length;
}
@Override
public String getColumnName(int column) {
return columns[column];
}
@Override
public Object getValueAt(int row, int column) {
Product product = products.get(row);
return switch (column) {
case 0 -> product.name();
case 1 -> product.price();
case 2 -> product.stock();
default -> null;
};
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return switch (columnIndex) {
case 0 -> String.class;
case 1 -> Integer.class;
case 2 -> Integer.class;
default -> Object.class;
};
}
}
record Product(String name, int price, int stock) {}
JListを使ったリスト表示の例
import javax.swing.*;
public class SimpleListExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("JList基本例");
frame.setSize(300, 400);
// リストデータ
String[] data = {
"Java", "Python", "C++", "JavaScript", "Ruby",
"Go", "Kotlin", "Swift", "Rust", "TypeScript"
};
// JListの作成
JList<String> list = new JList<>(data);
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// 選択イベントのリスナー
list.addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
System.out.println("選択された項目: " + list.getSelectedValue());
}
});
JScrollPane scrollPane = new JScrollPane(list);
frame.add(scrollPane);
frame.setVisible(true);
});
}
}
import javax.swing.*;
import java.awt.*;
public class CustomListRendererExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("カスタムレンダリングJList");
frame.setSize(350, 400);
// 複雑なデータのリスト
Language[] languages = {
new Language("Java", 1995, true),
new Language("Python", 1991, true),
new Language("C++", 1985, false),
new Language("Kotlin", 2011, true)
};
JList<Language> list = new JList<>(languages);
list.setCellRenderer(new LanguageCellRenderer());
frame.add(new JScrollPane(list));
frame.setVisible(true);
});
}
}
class Language {
String name;
int year;
boolean jvmBased;
public Language(String name, int year, boolean jvmBased) {
this.name = name;
this.year = year;
this.jvmBased = jvmBased;
}
}
class LanguageCellRenderer extends JPanel implements ListCellRenderer<Language> {
private JLabel nameLabel = new JLabel();
private JLabel detailLabel = new JLabel();
public LanguageCellRenderer() {
setLayout(new BorderLayout(5, 5));
add(nameLabel, BorderLayout.WEST);
add(detailLabel, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
@Override
public Component getListCellRendererComponent(
JList<? extends Language> list, Language value,
int index, boolean isSelected, boolean cellHasFocus) {
nameLabel.setText(value.name);
detailLabel.setText("リリース年: " + value.year +
(value.jvmBased ? " (JVM)" : ""));
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
}
}
JComboBoxを使ったドロップダウンリストの例
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
public class ComboBoxExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("JComboBox例");
frame.setSize(300, 200);
frame.setLayout(new FlowLayout());
String[] countries = {
"日本", "アメリカ", "イギリス",
"フランス", "ドイツ", "中国"
};
JComboBox<String> comboBox = new JComboBox<>(countries);
comboBox.setSelectedIndex(-1); // 初期選択なし
JLabel resultLabel = new JLabel("選択された国: ");
// 選択変更イベント
comboBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
resultLabel.setText("選択された国: " + comboBox.getSelectedItem());
}
});
frame.add(comboBox);
frame.add(resultLabel);
frame.setVisible(true);
});
}
}
import javax.swing.*;
import java.awt.*;
public class CustomObjectComboBox {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("カスタムオブジェクトComboBox");
frame.setSize(400, 200);
// カスタムオブジェクトの配列
Person[] people = {
new Person("田中太郎", 25),
new Person("山田花子", 30),
new Person("佐藤健二", 28)
};
// ComboBoxの作成
JComboBox<Person> comboBox = new JComboBox<>(people);
comboBox.setRenderer(new PersonCellRenderer());
JLabel infoLabel = new JLabel(" ");
comboBox.addActionListener(e -> {
Person selected = (Person)comboBox.getSelectedItem();
if (selected != null) {
infoLabel.setText(selected.name + " (" + selected.age + "歳)");
}
});
frame.setLayout(new FlowLayout());
frame.add(comboBox);
frame.add(infoLabel);
frame.setVisible(true);
});
}
}
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name;
}
}
class PersonCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(
JList<?> list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Person person) {
setText(person.name + " (" + person.age + "歳)");
}
return this;
}
}
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
public class TableComboIntegration {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("テーブルとコンボボックスの連携");
frame.setSize(600, 400);
// テーブルデータ
Object[][] data = {
{"プロジェクトA", "未着手"},
{"プロジェクトB", "進行中"},
{"プロジェクトC", "完了"}
};
// カラム名
String[] columns = {"プロジェクト名", "ステータス"};
// テーブルモデル
DefaultTableModel model = new DefaultTableModel(data, columns) {
@Override
public boolean isCellEditable(int row, int column) {
return column == 1; // ステータス列のみ編集可能
}
};
// JTableの作成
JTable table = new JTable(model);
// ステータス列にコンボボックスを設定
String[] statuses = {"未着手", "進行中", "保留", "完了"};
JComboBox<String> comboBox = new JComboBox<>(statuses);
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(comboBox));
// テーブルの選択変更イベント
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
int row = table.getSelectedRow();
if (row >= 0) {
System.out.println("選択行: " + row +
", プロジェクト: " + table.getValueAt(row, 0) +
", ステータス: " + table.getValueAt(row, 1));
}
}
});
frame.add(new JScrollPane(table));
frame.setVisible(true);
});
}
}
// モデルとビューの分離例(JTableの場合)
DefaultTableModel model = new DefaultTableModel(data, columns);
JTable table = new JTable(model);
// データ更新はモデルに対して行う
SwingUtilities.invokeLater(() -> {
model.addRow(new Object[]{"新しいデータ", 123});
model.fireTableDataChanged(); // 必要に応じて通知
});
これらの高度なコンポーネントを組み合わせることで、データ集約型の本格的なアプリケーションインターフェースを構築できます。次に学ぶ「Swingアプリケーションのアーキテクチャ」では、これらのコンポーネントを効果的に組み合わせる設計パターンを解説します。