You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing:如何在已有JPanel中绘制线条而非创建新面板

解决在同一JPanel中绘制多条线条的问题

你的问题核心是Line类继承了JPanel,导致每个HorizontalLine、VerticalLine实例都是独立的小面板,添加到原有JPanel后,Swing会把它们当作组件布局,而不是在原面板上绘制线条。要在同一面板中绘制多条线条,按以下步骤修改:

1. 重构Line类为普通数据类

让Line不再继承JPanel,只负责存储线条的起点、终点,并提供绘制方法:

import java.awt.Point;

class Line {
    private Point startPoint;
    private Point endPoint;

    public Line(Point pointStart, int length, String direction) {
        startPoint = new Point(pointStart);
        if ("horizontal".equals(direction)) {
            endPoint = new Point(pointStart.x + length, pointStart.y);
        } else {
            endPoint = new Point(pointStart.x, pointStart.y + length);
        }
    }

    public void draw(java.awt.Graphics g) {
        g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
    }
}

class HorizontalLine extends Line {
    public HorizontalLine(Point startPoint, int length) {
        super(startPoint, length, "horizontal");
    }
}

class VerticalLine extends Line {
    public VerticalLine(Point startPoint, int length) {
        super(startPoint, length, "vertical");
    }
}

注意:把Vector换成了Point类(更适合存储坐标),同时字符串比较用equals()替代==(避免引用比较的错误)。

2. 创建自定义绘图面板

新建一个继承JPanel的类,用来管理所有线条,并负责绘制:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;

class DrawingPanel extends JPanel {
    private List<Line> lines = new ArrayList<>();

    public DrawingPanel() {
        setPreferredSize(new Dimension(500, 500));
        setBackground(Color.RED);
    }

    public void addLine(Line line) {
        lines.add(line);
        repaint(); // 添加后立即重绘
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // 遍历所有线条并绘制
        for (Line line : lines) {
            line.draw(g);
        }
    }
}

3. 修改主方法和DrawLines方法

使用自定义的DrawingPanel替代原JPanel,把线条添加到绘图面板的线条列表中:

import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class LineTest {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            LineTest main = new LineTest();
            JFrame window = new JFrame();
            DrawingPanel panel = new DrawingPanel();

            window.setTitle("Line-Test");
            window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

            window.add(panel);
            window.pack();
            window.setLocationRelativeTo(null);
            window.setResizable(false);
            window.setVisible(true);

            main.DrawLines(panel);
        });
    }

    private void DrawLines(DrawingPanel panel) {
        Point startPoint = new Point(2, 0);

        HorizontalLine lineH = new HorizontalLine(startPoint, 360);
        VerticalLine lineV = new VerticalLine(startPoint, 360);
        panel.addLine(lineH);
        panel.addLine(lineV);
    }
}

关键说明

  • 自定义的DrawingPanel负责所有绘制逻辑,重写paintComponent方法时必须先调用super.paintComponent(g),确保面板背景和原有组件被正确绘制。
  • 每次添加新线条后调用repaint(),触发面板重新绘制所有线条。
  • 用Point存储坐标比Vector更简洁,符合AWT/Swing的设计习惯。

内容的提问来源于stack exchange,提问作者AllMakeIt LP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:05:09