概要

CardLayoutを設定したパネルの内部にそのカード切り替え用のJComboBoxOverlayLayoutで重ねて配置します。

サンプルコード

String[] model = {"red", "green", "blue"};

CardLayout cardLayout = new CardLayout();
JPanel cards = new JPanel(cardLayout);
cards.add(makePanel(Color.RED), model[0]);
cards.add(makePanel(Color.GREEN), model[1]);
cards.add(makePanel(Color.BLUE), model[2]);

JComboBox<String> combo = new JComboBox<>(model);
combo.addItemListener(e -> {
  if (e.getStateChange() == ItemEvent.SELECTED) {
    cardLayout.show(cards, Objects.toString(e.getItem()));
  }
});

JPanel pp = new JPanel(new BorderLayout());
pp.setOpaque(false);
pp.setBorder(BorderFactory.createEmptyBorder(8, 24, 0, 24));
pp.add(combo, BorderLayout.NORTH);

JPanel p = new JPanel() {
  @Override public boolean isOptimizedDrawingEnabled() {
    return false;
  }
};
p.setLayout(new OverlayLayout(p));
p.add(pp);
p.add(cards);
View in GitHub: Java, Kotlin

解説

  • CardLayoutを設定したパネルを作成
    • このパネルにはそれぞれ赤緑青の背景色を設定した3つのJPanelを追加
  • BorderLayoutを設定したパネルを作成
    • このパネルにはカード切り替えを実行するJComboBoxBorderLayout.NORTHで上部に追加
  • OverlayLayoutを設定したパネルを作成
    • このパネルにはOverlayLayoutを設定し、上記の2つのパネルを奥からCardLayoutBorderLayoutの順に同サイズで重なるよう配置
    • 2つのパネルがオーバーラップするのでマウスイベントなどでコンポーネントの奥手前の描画が入れ替わらないようにするためJComponent#isOptimizedDrawingEnabled()が常にfalseを返すようオーバーライド

参考リンク

コメント