Java Swing:如何结合ActionListener与JComboBox实现点击绘制指定形状?
问题分析与解决方案
我看了你的代码,问题其实出在几个关键细节上,导致点击按钮后完全没有图形绘制出来:
核心问题点
- 没有将下拉框选择值赋值给类变量:你在
actionPerformed里调用了color.getSelectedIndex()、shape.getSelectedIndex(),但没把返回的结果存到myColor、myShape、mySize里,这些变量一直是默认的0,后续的绘制判断自然不会执行。 - 下拉框索引判断错误:
JComboBox的索引是从0开始的,但你在绘制逻辑里判断的是myColor == 1、myShape == 1这类,和下拉框的选项顺序完全不匹配。 - 错误重写绘制方法:对于
JComponent子类,标准做法是重写paintComponent方法而非paint,而且必须调用super.paintComponent(g)来清空画布,避免图形重叠或残留。 - 尺寸逻辑混乱:你用
sizes数组存储的坐标和尺寸,在绘制矩形、椭圆时的索引使用不符合预期,导致图形位置或大小异常。
修正后的完整代码
package com.java24hours; import java.awt.*; import java.awt.event.*; import java.awt.geom.Ellipse2D; import javax.swing.*; public class Shape1Student implements ActionListener { int choice; int myColor; int myShape; int mySize; JButton drawShape = new JButton("DrawShape"); JComboBox<String> shape = new JComboBox<>(); JComboBox<String> color = new JComboBox<>(); JComboBox<String> size = new JComboBox<>(); Drawing draw = new Drawing(); Color gold = new Color(159, 121, 44); public Shape1Student() { JFrame frame = new JFrame("DS Draw Shapes"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); panel.add(drawShape); panel.add(shape); drawShape.setFont(new Font("Book Antiqua", Font.BOLD | Font.ITALIC, 16)); shape.addItem("Square"); shape.addItem("Rectangle"); shape.addItem("Circle"); shape.addItem("Ellipse"); panel.add(color); color.addItem("Red"); color.addItem("Blue"); color.addItem("Custom"); panel.add(size); size.addItem("Small"); size.addItem("Medium"); size.addItem("Large"); drawShape.addActionListener(this); frame.add(panel, BorderLayout.NORTH); frame.add(draw, BorderLayout.CENTER); frame.setSize(500, 500); frame.setVisible(true); } public void actionPerformed(ActionEvent e) { if (e.getSource() == drawShape) { choice = 1; // 关键:把下拉框的选择结果赋值给类变量 myColor = color.getSelectedIndex(); myShape = shape.getSelectedIndex(); mySize = size.getSelectedIndex(); draw.repaint(); } } class Drawing extends JComponent { @Override protected void paintComponent(Graphics g2) { super.paintComponent(g2); // 必须调用,清空之前的绘制内容 Graphics2D g = (Graphics2D) g2; // 基础坐标与尺寸,后续根据选择缩放 int baseX = 50; int baseY = 50; int baseWidth = 100; int baseHeight = 100; if (choice == 1) { // 根据选择设置颜色 switch (myColor) { case 0: // 对应下拉框第一个选项Red g.setColor(Color.RED); break; case 1: // 对应Blue g.setColor(Color.BLUE); break; case 2: // 对应Custom(Gold) g.setColor(gold); break; default: g.setColor(Color.BLACK); } // 根据选择设置缩放比例 double scale = 1.0; switch (mySize) { case 0: // Small scale = 0.5; break; case 1: // Medium scale = 1.0; break; case 2: // Large scale = 2.0; break; } g.scale(scale, scale); // 根据选择绘制对应形状 switch (myShape) { case 0: // Square g.fillRect(baseX, baseY, baseWidth, baseHeight); break; case 1: // Rectangle:调整宽高为矩形比例 g.fillRect(baseX, baseY, baseWidth + 50, baseHeight); break; case 2: // Circle Ellipse2D.Float circle = new Ellipse2D.Float(baseX, baseY, baseWidth, baseHeight); g.fill(circle); break; case 3: // Ellipse:调整宽高为椭圆比例 Ellipse2D.Float ellipse = new Ellipse2D.Float(baseX, baseY, baseWidth + 50, baseHeight); g.fill(ellipse); break; } } } } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Shape1Student()); // 确保Swing组件在EDT线程初始化 } }
关键修改说明
- 赋值下拉框选择值:在按钮点击事件里,把
getSelectedIndex()的结果存到对应的类变量中,确保绘制逻辑能拿到用户的选择。 - 修正索引对应关系:下拉框第一个选项索引为0,所以判断时用
case 0、case 1等,和你添加的选项顺序一一对应。 - 改用标准绘制方法:重写
paintComponent并调用父类方法,这是Swing组件绘制的规范方式,能正确处理组件更新和重绘。 - 优化代码结构:用
switch替代大量if-else,代码更易读;使用BorderLayout常量替代字符串,更规范;添加SwingUtilities.invokeLater避免Swing线程安全问题。 - 调整形状尺寸:重新定义基础尺寸,让矩形、椭圆的比例更符合预期,避免图形变形。
现在点击DrawShape按钮,就能根据你的选择绘制对应的图形了!
内容的提问来源于stack exchange,提问作者that1guy89
相关产品推荐
相关产品推荐

