# Swing自定义组件

# 短暂消息提示

image-20250725141547852

# 封装

package demo;

import javax.swing.*;
import java.awt.*;

public class Toast extends JWindow {

    private static final int WIDTH = 300;
    private static final int HEIGHT = 50;
    private static final int DEFAULT_DURATION = 2000; // 2 秒

    private Toast(String message, Color bgColor, int durationMillis) {
        JPanel panel = new JPanel();
        panel.setBackground(bgColor);
        panel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
        panel.setLayout(new BorderLayout());

        JLabel label = new JLabel(message, SwingConstants.CENTER);
        label.setForeground(Color.WHITE);
        label.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        panel.add(label, BorderLayout.CENTER);

        setContentPane(panel);
        setSize(WIDTH, HEIGHT);

        // 设置在屏幕中央(可自定义位置)
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screen.width - WIDTH) / 2;
        int y = screen.height / 3; // 顶部偏下一点
        setLocation(x, y);

        // 淡入显示 & 自动关闭
        new Thread(() -> {
            setVisible(true);
            try {
                Thread.sleep(durationMillis);
            } catch (InterruptedException ignored) {
            }
            SwingUtilities.invokeLater(this::dispose);
        }).start();
    }

    public static void showToast(String message) {
        showToast(message, DEFAULT_DURATION);
    }

    public static void showToast(String message, int durationMillis) {
        showToast(message, new Color(0, 0, 0, 180), durationMillis);
    }

    public static void showToast(String message, Color bgColor, int durationMillis) {
        SwingUtilities.invokeLater(() -> new Toast(message, bgColor, durationMillis));
    }

    // 快捷方法:成功 / 错误 / 信息 / 警告
    public static void showSuccess(String msg) {
        showToast(msg, new Color(76, 175, 80), DEFAULT_DURATION);
    }

    public static void showError(String msg) {
        showToast(msg, new Color(244, 67, 54), DEFAULT_DURATION);
    }

    public static void showInfo(String msg) {
        showToast(msg, new Color(33, 150, 243), DEFAULT_DURATION);
    }

    public static void showWarning(String msg) {
        showToast(msg, new Color(255, 152, 0), DEFAULT_DURATION);
    }
}

# 使用

package demo;

import javax.swing.*;
import java.awt.*;

public class ToastTest {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Toast 消息测试");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(400, 300);
            frame.setLocationRelativeTo(null);

            JPanel panel = new JPanel(new GridLayout(4, 1, 10, 10));

            JButton successBtn = new JButton("显示成功提示");
            successBtn.addActionListener(e -> Toast.showSuccess("保存成功!"));

            JButton errorBtn = new JButton("显示错误提示");
            errorBtn.addActionListener(e -> Toast.showError("保存失败,请重试。"));

            JButton infoBtn = new JButton("显示信息提示");
            infoBtn.addActionListener(e -> Toast.showInfo("更新已完成。"));

            JButton warnBtn = new JButton("显示警告提示");
            warnBtn.addActionListener(e -> Toast.showWarning("数据不完整,请检查。"));

            panel.add(successBtn);
            panel.add(errorBtn);
            panel.add(infoBtn);
            panel.add(warnBtn);

            frame.setContentPane(panel);
            frame.setVisible(true);
        });
    }
}

# 定制按钮

按钮工厂(ButtonFactory 工具类,用于快速生成统一风格的按钮。

image-20250725135945004

# 封装

package demo;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;

public class ButtonFactory {

    /**
     * 通用按钮创建方法
     */
    public static JButton createButton(String text, Color fg, Color bg, Font font, Icon icon, Integer mnemonic) {
        JButton button = new JButton(text);
        button.setForeground(fg);
        button.setBackground(bg);
        button.setFocusPainted(false);
        button.setFont(font != null ? font : button.getFont());

        if (icon != null) {
            button.setIcon(icon);
        }

        if (mnemonic != null) {
            button.setMnemonic(mnemonic); // 支持快捷键
        }

        // 可选统一按钮样式,例如圆角、边框、hover 效果可以后续增强
        return button;
    }

    // 主按钮(蓝色)
    public static JButton createPrimaryButton(String text) {
        return createButton(
                text,
                Color.WHITE,
                new Color(33, 150, 243),
                new Font("微软雅黑", Font.PLAIN, 14),
                null,
                null
        );
    }

    // 次按钮(灰色)
    public static JButton createSecondaryButton(String text) {
        return createButton(
                text,
                Color.BLACK,
                new Color(224, 224, 224),
                new Font("微软雅黑", Font.PLAIN, 14),
                null,
                null
        );
    }

    // 成功按钮(绿色)
    public static JButton createSuccessButton(String text) {
        return createButton(
                text,
                Color.WHITE,
                new Color(76, 175, 80),
                new Font("微软雅黑", Font.PLAIN, 14),
                null,
                null
        );
    }

    // 危险按钮(红色)
    public static JButton createDangerButton(String text) {
        return createButton(
                text,
                Color.WHITE,
                new Color(244, 67, 54),
                new Font("微软雅黑", Font.PLAIN, 14),
                null,
                null
        );
    }

    // 自定义字体大小版本
    public static JButton createPrimaryButton(String text, int fontSize) {
        return createButton(
                text,
                Color.WHITE,
                new Color(33, 150, 243),
                new Font("微软雅黑", Font.PLAIN, fontSize),
                null,
                null
        );
    }

    // 添加快捷键按钮
    public static JButton createButtonWithShortcut(String text, char shortcutKey, Color bgColor) {
        return createButton(
                text,
                Color.WHITE,
                bgColor,
                new Font("微软雅黑", Font.PLAIN, 14),
                null,
                KeyEvent.getExtendedKeyCodeForChar(shortcutKey)
        );
    }
}

# 使用

package demo;

import javax.swing.*;
import java.awt.*;

public class ButtonFactoryTest {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("按钮工厂测试");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(400, 300);
            frame.setLocationRelativeTo(null);

            JPanel panel = new JPanel();
            panel.setLayout(new GridLayout(5, 1, 10, 10));
            panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

            panel.add(ButtonFactory.createPrimaryButton("主按钮"));
            panel.add(ButtonFactory.createSecondaryButton("次按钮"));
            panel.add(ButtonFactory.createSuccessButton("成功"));
            panel.add(ButtonFactory.createDangerButton("危险"));
            panel.add(ButtonFactory.createButtonWithShortcut("快捷键按钮 (Alt+S)", 'S', new Color(255, 152, 0)));

            frame.setContentPane(panel);
            frame.setVisible(true);
        });
    }
}

# 动态控制Tab

JTabbedPane 做核心,封装一个 DynamicTabPanel 类,然后在主 JFrame 初始化时动态传入 tab 的数量、标题和内容。

image-20250725134136418

# 封装

package com.bbs;

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class DynamicTabPanel extends JPanel {
    private JTabbedPane tabbedPane;

    public DynamicTabPanel() {
        setLayout(new BorderLayout());
        tabbedPane = new JTabbedPane();
        add(tabbedPane, BorderLayout.CENTER);
    }

    /**
     * 添加一个新 Tab
     * @param title 标签标题
     * @param content 标签内容(任何 JComponent)
     */
    public void addTab(String title, JComponent content) {
        tabbedPane.addTab(title, content);
    }

    /**
     * 批量添加多个 Tab
     * @param tabs List of TabItem(title + component)
     */
    public void setTabs(List<TabItem> tabs) {
        tabbedPane.removeAll();  // 清空旧的
        for (TabItem tab : tabs) {
            addTab(tab.getTitle(), tab.getContent());
        }
    }

    public JTabbedPane getTabbedPane() {
        return tabbedPane;
    }

    // 静态内部类表示单个 Tab
    public static class TabItem {
        private String title;
        private JComponent content;

        public TabItem(String title, JComponent content) {
            this.title = title;
            this.content = content;
        }

        public String getTitle() {
            return title;
        }

        public JComponent getContent() {
            return content;
        }
    }
}

# 使用

package com.bbs;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class DynamicTabTest {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("动态 Tab 面板示例");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800, 600);
            frame.setLocationRelativeTo(null);

            DynamicTabPanel tabPanel = new DynamicTabPanel();

            // 动态生成 tab 数据
            List<DynamicTabPanel.TabItem> tabs = new ArrayList<>();

            for (int i = 1; i <= 5; i++) {
                JPanel content = new JPanel();
                content.add(new JLabel("这是第 " + i + " 个标签页的内容"));
                tabs.add(new DynamicTabPanel.TabItem("标签页 " + i, content));
            }

            tabPanel.setTabs(tabs);

            frame.add(tabPanel, BorderLayout.CENTER);
            frame.setVisible(true);
        });
    }
}

# 面板图片操作

# 图片上传

功能 实现情况
支持本地文件选择
自动复制到 /upload
自动创建 upload 目录
命名统一、避免重复 ✅(时间戳命名)
显示上传后图片
输出最终图片路径(可存库)

image-20250723141502570

package com.bbs.view;

import com.bbs.dao.BookDao;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.nio.file.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ImageUpload extends JFrame {
    private JLabel imageLabel;
    private JButton selectButton, uploadButton, resetButton,backButton;
    private File selectedImageFile;
    private String uploadedImagePath;


    public ImageUpload(Integer id) throws Exception {
        super("图片上传");
        this.bookId = id;

        selectButton = new JButton("选择图片");
        uploadButton = new JButton("上传图片");
        resetButton = new JButton("重置图片");
        JButton backButton = new JButton("返回"); // ✅ 新增返回按钮

        imageLabel = new JLabel("暂无图片", SwingConstants.CENTER);
        imageLabel.setPreferredSize(new Dimension(200, 200));
        imageLabel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        imageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        imageLabel.setForeground(Color.GRAY);

        // 整体使用 BorderLayout
        setLayout(new BorderLayout());

        // 中部内容:按钮 + 图片
        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));

        // 原按钮行
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 10));
        buttonPanel.add(selectButton);
        buttonPanel.add(uploadButton);
        buttonPanel.add(resetButton);

        // 图片显示区域
        JPanel imagePanel = new JPanel();
        imagePanel.add(imageLabel);

        centerPanel.add(buttonPanel);
        centerPanel.add(imagePanel);

        add(centerPanel, BorderLayout.CENTER);

        // 底部返回按钮单独一行
        JPanel bottomPanel = new JPanel();
        bottomPanel.add(backButton);
        add(bottomPanel, BorderLayout.SOUTH);

        // 事件绑定
        selectButton.addActionListener(e -> chooseImageFile());
        uploadButton.addActionListener(e -> confirmUpload());
        resetButton.addActionListener(e -> resetImage());
        backButton.addActionListener(e -> dispose());  // 关闭窗口

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(450, 360);
        setLocationRelativeTo(null);
        setVisible(true);
    }



    private void chooseImageFile() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
            final String[] extensions = { "jpg", "jpeg", "png", "gif", "bmp" };
            @Override
            public boolean accept(File f) {
                if (f.isDirectory()) return true;
                String name = f.getName().toLowerCase();
                for (String ext : extensions) {
                    if (name.endsWith(ext)) return true;
                }
                return false;
            }
            @Override
            public String getDescription() {
                return "图片文件 (*.jpg, *.png, *.gif, *.bmp)";
            }
        });

        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            selectedImageFile = fileChooser.getSelectedFile();
            previewImage(selectedImageFile);
        }
    }

    private void resetImage() {
        selectedImageFile = null;
        uploadedImagePath = null;
        imageLabel.setIcon(null);
        imageLabel.setText("暂无图片");
        imageLabel.setForeground(Color.GRAY);
    }

    private void previewImage(File file) {
        if (file == null || !file.exists()) return;
        ImageIcon icon = new ImageIcon(file.getAbsolutePath());
        Image img = icon.getImage().getScaledInstance(
                imageLabel.getWidth(), imageLabel.getHeight(), Image.SCALE_SMOOTH);
        imageLabel.setIcon(new ImageIcon(img));
        imageLabel.setText(null);
    }

    private void confirmUpload() {
        if (selectedImageFile == null) {
            JOptionPane.showMessageDialog(this, "请先选择图片!");
            return;
        }

        String path = saveToUploadDirectory(selectedImageFile);
        if (path != null) {
            uploadedImagePath = path;
            JOptionPane.showMessageDialog(this, "图片上传成功!\n路径:" + uploadedImagePath);
            System.out.println("图片已上传至:" + uploadedImagePath);
            // TODO: 保存路径
            dispose();
        } else {
            JOptionPane.showMessageDialog(this, "图片上传失败!");
        }
    }

    private String saveToUploadDirectory(File sourceFile) {
        try {
            File uploadDir = new File("upload");
            if (!uploadDir.exists()) uploadDir.mkdirs();

            String originalName = sourceFile.getName();
            String ext = originalName.substring(originalName.lastIndexOf("."));
            String timeStr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            String newFileName = "dish_" + timeStr + ext;

            File destFile = new File(uploadDir, newFileName);
            Files.copy(sourceFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            return destFile.getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}


# 表格图片展示

# 封装

  • 图片自适应
  • 表格可指定显示图片的列,可设置表格字体、表头字体大小
  • 表格可指定隐藏某些行
  • 方便复用

image-20250723131118279

package com.bbs.util;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.io.File;
import java.net.URL;
import java.util.Set;

public class PlusTable extends JTable {

    public PlusTable(Object[][] data, String[] columnNames, Set<Integer> imageColumns, Set<Integer> hiddenColumns) {
        super(new DefaultTableModel(data, columnNames) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }

            @Override
            public Class<?> getColumnClass(int columnIndex) {
                return String.class;
            }
        });

        //        getTableHeader().setFont(new Font("宋体", Font.BOLD, 18)); // 设置表头字体

//        setFont(new Font("宋体", Font.PLAIN, 18));  // 设置表格字体

        setRowHeight(100); // 设置行高

        // 图片列渲染器
        for (int col : imageColumns) {
            getColumnModel().getColumn(col).setCellRenderer(new ProportionalImageRenderer());
        }

        // 非图片列居中
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
        for (int i = 0; i < getColumnCount(); i++) {
            if (!imageColumns.contains(i)) {
                getColumnModel().getColumn(i).setCellRenderer(centerRenderer);
            }
        }

        // 隐藏指定列
        if (hiddenColumns != null) {
            for (int i = getColumnCount() - 1; i >= 0; i--) { // 从后向前删,避免越界
                if (hiddenColumns.contains(i)) {
                    getColumnModel().removeColumn(getColumnModel().getColumn(i));
                }
            }
        }
    }

    // 图片渲染器内部类
    static class ProportionalImageRenderer extends JLabel implements TableCellRenderer {
        private static final int VERTICAL_PADDING = 5;

        public ProportionalImageRenderer() {
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
            setOpaque(true);
            setBorder(BorderFactory.createEmptyBorder(VERTICAL_PADDING, 0, VERTICAL_PADDING, 0));
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                                                       boolean isSelected, boolean hasFocus,
                                                       int row, int column) {
            setText(null);
            setIcon(null);

            if (value instanceof String) {
                String path = (String) value;
                try {
                    ImageIcon icon;
                    if (path.startsWith("http://") || path.startsWith("https://")) {
                        icon = new ImageIcon(new URL(path));
                    } else {
                        File imgFile = new File(path);
                        if (!imgFile.exists()) {
                            setText("图片不存在");
                            return this;
                        }
                        icon = new ImageIcon(path);
                    }

                    int cellWidth = table.getColumnModel().getColumn(column).getWidth();
                    int cellHeight = table.getRowHeight(row) - 2 * VERTICAL_PADDING;

                    int imgWidth = icon.getIconWidth();
                    int imgHeight = icon.getIconHeight();

                    if (imgWidth > 0 && imgHeight > 0) {
                        double widthRatio = (double) cellWidth / imgWidth;
                        double heightRatio = (double) cellHeight / imgHeight;
                        double scale = Math.min(widthRatio, heightRatio);

                        int newWidth = (int) (imgWidth * scale);
                        int newHeight = (int) (imgHeight * scale);

                        Image scaledImg = icon.getImage().getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
                        setIcon(new ImageIcon(scaledImg));
                    }
                } catch (Exception ex) {
                    setText("加载失败");
                }
            }

            return this;
        }
    }
}

# 如何使用

private JTable table;

table = new PlusTable(new Object[][]{}, columnNames, Set.of(5),Set.of());
table.setRowHeight(100);
scrollPane.setViewportView(table);
initTable();

    private void fillTable(List<Book> bookList) {
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        model.setRowCount(0); // 清除旧数据
        for (Book book : bookList) {
            model.addRow(new Object[]{
                    book.getId(),
                    book.getTitle(),
                    book.getAuthor(),
                    book.getIsbn(),
                    book.getCount(),
                    book.getCover()
            });
        }
    }

# Label展示图片

# 封装

  • 图片自适应完整呈现

image-20250725131929459

package com.bbs;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import javax.imageio.ImageIO;

public class AutoResizeImageLabel extends JLabel {
    private Image originalImage;

    public AutoResizeImageLabel() {
        this.setHorizontalAlignment(CENTER);
        this.setVerticalAlignment(CENTER);
    }

    /**
     * 直接从 Image 对象设置图像
     */
    public void setImage(Image image) {
        this.originalImage = image;
        repaint();
    }

    /**
     * 从文件路径加载图像并设置
     */
    public boolean setImageFromFile(String path) {
        try {
            File file = new File(path);
            if (!file.exists()) {
                System.err.println("文件不存在: " + path);
                return false;
            }

            Image img = ImageIO.read(file);
            if (img != null) {
                setImage(img);
                return true;
            } else {
                System.err.println("无法读取图片文件: " + path);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        if (originalImage != null) {
            int labelWidth = getWidth();
            int labelHeight = getHeight();

            int imgWidth = originalImage.getWidth(null);
            int imgHeight = originalImage.getHeight(null);

            if (imgWidth > 0 && imgHeight > 0) {
                double scale = Math.min((double) labelWidth / imgWidth, (double) labelHeight / imgHeight);

                int drawWidth = (int) (imgWidth * scale);
                int drawHeight = (int) (imgHeight * scale);

                int x = (labelWidth - drawWidth) / 2;
                int y = (labelHeight - drawHeight) / 2;

                g.drawImage(originalImage, x, y, drawWidth, drawHeight, this);
            }
        }
    }
}

# 如何使用

package com.bbs;

import javax.swing.*;

public class TestAutoResizeLabel {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("自动适应图片展示");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(600, 400);
            frame.setLocationRelativeTo(null);
            frame.getContentPane().setLayout(null);

            AutoResizeImageLabel imageLabel = new AutoResizeImageLabel();
            imageLabel.setBounds(60, 32, 436, 213);
            frame.getContentPane().add(imageLabel);

            // 使用封装的方法加载图片
            String path = "upload/pngsucai_1359311_90049c.png";
            boolean loaded = imageLabel.setImageFromFile(path);
            
            JLabel lblNewLabel = new JLabel("内容测试");
            lblNewLabel.setBounds(257, 294, 54, 15);
            frame.getContentPane().add(lblNewLabel);

            if (!loaded) {
                JOptionPane.showMessageDialog(frame, "图片加载失败: " + path, "错误", JOptionPane.ERROR_MESSAGE);
            }

            frame.setVisible(true);
        });
    }
}

# 下拉框组件

# 目标

封装一个可复用的下拉框组件 CustomComboBox<T>,支持以下功能:

  • 快速初始化数据源
  • 设置默认选项
  • 获取当前选中项
  • 支持泛型(如:StringInteger、自定义对象)
  • 提供常用方法如刷新数据、设置提示文本等

# 组件代码:CustomComboBox.java

import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Vector;

public class CustomComboBox<T> extends JPanel {
    private JComboBox<T> comboBox;
    private DefaultComboBoxModel<T> model;

    public CustomComboBox(List<T> items) {
        this(items, null);
    }

    public CustomComboBox(List<T> items, T selectedItem) {
        setLayout(new BorderLayout());
        model = new DefaultComboBoxModel<>(new Vector<>(items));
        comboBox = new JComboBox<>(model);

        if (selectedItem != null) {
            comboBox.setSelectedItem(selectedItem);
        }

        add(comboBox, BorderLayout.CENTER);
    }

    public void setSelectedItem(T item) {
        comboBox.setSelectedItem(item);
    }

    public T getSelectedItem() {
        return (T) comboBox.getSelectedItem();
    }

    public void refreshItems(List<T> newItems) {
        model.removeAllElements();
        for (T item : newItems) {
            model.addElement(item);
        }
    }

    public JComboBox<T> getComboBox() {
        return comboBox;
    }

    public void setPrompt(String prompt) {
        comboBox.setRenderer(new DefaultListCellRenderer() {
            @Override
            public Component getListCellRendererComponent(JList<?> list, Object value, int index,
                                                          boolean isSelected, boolean cellHasFocus) {
                super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                if (value == null && index == -1) {
                    setText(prompt);
                }
                return this;
            }
        });
    }
}

# 示例用法

import javax.swing.*;
import java.util.Arrays;

public class TestComboBox {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("下拉框组件示例");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(400, 150);

            CustomComboBox<String> comboBox = new CustomComboBox<>(
                Arrays.asList("苹果", "香蕉", "橘子", "西瓜"), "香蕉"
            );
            comboBox.setPrompt("请选择水果");

            frame.getContentPane().add(comboBox, "North");

            JButton btn = new JButton("获取选中值");
            btn.addActionListener(e -> {
                String selected = comboBox.getSelectedItem();
                JOptionPane.showMessageDialog(frame, "你选择的是: " + selected);
            });

            frame.getContentPane().add(btn, "South");

            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

image-20250803115309862

Last Updated: 8/13/2025, 9:30:19 AM