From 98b1561ef266a54c598d51d57e1809e34567b294 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 1 Jun 2026 15:27:15 +0200 Subject: [PATCH] feat(io): SwingIO.choose renders the menu as buttons --- .../thb/jeanluc/adventure/io/SwingIO.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/SwingIO.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/SwingIO.java index fb4e4be..e40210f 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/SwingIO.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/io/SwingIO.java @@ -10,7 +10,11 @@ import thb.jeanluc.adventure.io.text.StyledText; import javax.swing.AbstractAction; import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; import javax.swing.JComponent; +import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; @@ -342,6 +346,51 @@ public class SwingIO implements GameIO { // The GUI map panel is always visible; nothing extra to do on the 'map' command. } + @Override + public int choose(String title, List options) { + // Same EDT↔worker handoff as readLine: the worker blocks on take(), + // the EDT (button click / window close) offers the chosen index. + LinkedBlockingQueue picked = new LinkedBlockingQueue<>(); + SwingUtilities.invokeLater(() -> { + JDialog dialog = new JDialog(frame, title, true); + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); + panel.add(new JLabel(title)); + panel.add(Box.createVerticalStrut(8)); + for (int i = 0; i < options.size(); i++) { + int idx = i; + JButton b = new JButton(options.get(i)); + b.setAlignmentX(0f); + b.addActionListener(e -> { + dialog.dispose(); + picked.offer(idx); + }); + panel.add(b); + panel.add(Box.createVerticalStrut(4)); + } + // Closing the dialog counts as the last (safe/cancel) option. + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + dialog.dispose(); + picked.offer(options.size() - 1); + } + }); + dialog.setContentPane(panel); + dialog.pack(); + dialog.setLocationRelativeTo(frame); + dialog.setVisible(true); + }); + try { + return picked.take(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return options.size() - 1; + } + } + private void addList(List spans, List xs, Style st) { for (int i = 0; i < xs.size(); i++) { if (i > 0) {