JavaSwing-如何在画布中绘制新线并将其添加到现有线中?

JavaSwing-如何在画布中绘制新线并将其添加到现有线中?,java,swing,Java,Swing,我已经在JavaSwing中绘制了哥本哈根的地图,但是我希望能够在地图上绘制新的线条,然后将它们添加到现有的线条中,我从缓冲读取器中获取这些线条。我曾尝试将新绘制的线条添加到临时线条的arraylist中,但这似乎不起作用-我再也无法在画布上绘制了。有人能帮忙吗 public class Model extends Observable implements Iterable<Line2D>, Serializable { private List<Line2D>

我已经在JavaSwing中绘制了哥本哈根的地图,但是我希望能够在地图上绘制新的线条,然后将它们添加到现有的线条中,我从缓冲读取器中获取这些线条。我曾尝试将新绘制的线条添加到临时线条的arraylist中,但这似乎不起作用-我再也无法在画布上绘制了。有人能帮忙吗

public class Model extends Observable implements Iterable<Line2D>, Serializable {
    private List<Line2D> lines;
    private List<Line2D> tmpLines;

    public Model() {
        lines = new ArrayList<>();
        tmpLines = new ArrayList<>();
    }

    public Model(String filename) {
        readFromFile(filename);
    }

    public void add(Line2D line) {
        lines.add(line);
        dirty();
    }

    public void dirty() {
        setChanged();
        notifyObservers();
    }

    public void readFromFile(String filename) {
        lines = new ArrayList<>();
        tmpLines = new ArrayList<>();
        try {
            BufferedReader b = new BufferedReader(new FileReader(filename));
            for (String line = b.readLine(); line != null; line = b.readLine() ) {
                String[] tokens = line.split(" ");
                if (tokens[0].equals("LINE")) {
                    double x1 = Double.parseDouble(tokens[1]);
                    double y1 = Double.parseDouble(tokens[2]);
                    double x2 = Double.parseDouble(tokens[3]);
                    double y2 = Double.parseDouble(tokens[4]);
                    lines.add(new Line2D.Double(x1, y1, x2, y2));
                }

            }

        } 
        catch (FileNotFoundException e) {
            e.printStackTrace();
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    @Override
    public Iterator<Line2D> iterator() {
        return lines.iterator();
    }

    public Line2D removeLastFromTmpLines() {
        Line2D line = tmpLines.remove(tmpLines.size() - 1);
        dirty();
        return line;
    }

    public Line2D removeLastFromLines() {
        Line2D line = lines.remove(lines.size() - 1);
        dirty();
        return line;
    }

    public void addTmpLinesToLines() {
        lines.addAll(tmpLines);
        dirty();
    }

    public void addToTmpLines(Line2D line2D) {
        tmpLines.add(line2D);
        dirty();
    }

    public List<Line2D> getTmpLines() {
        return tmpLines;
    }
}
public class MouseController extends MouseAdapter {
    private Model model;
    private CanvasView canvas;
    private Point2D lastMousePosition;

    public MouseController(CanvasView c, Model m) {
        canvas = c;
        model = m;

        canvas.addMouseListener(this);
        canvas.addMouseWheelListener(this);
        canvas.addMouseMotionListener(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        Point2D currentMousePosition = e.getPoint();
        if (canvas.inDrawingMode()) {
            Point2D origin = model.removeLastFromTmpLines().getP1();
            model.addToTmpLines(new Line2D.Double(origin, canvas.toModelCoords(currentMousePosition)));
        }
        else {
            double dx = currentMousePosition.getX() - lastMousePosition.getX();
            double dy = currentMousePosition.getY() - lastMousePosition.getY();
            canvas.pan(dx, dy);
        }
        lastMousePosition = currentMousePosition;
    }

    @Override
    public void mousePressed(MouseEvent e) {
       lastMousePosition = e.getPoint();
       if (canvas.inDrawingMode()) {
           model.addToTmpLines(new Line2D.Double(
               canvas.toModelCoords(lastMousePosition),
               canvas.toModelCoords(lastMousePosition)));
       }
    }

    public void mouseMoved(MouseEvent e) {
        Point2D modelCoords = canvas.toModelCoords(e.getPoint());
        //System.out.println("Screen: [" + e.getX() + ", " + e.getY() + "], "+"Model: [" + modelCoords.getX() + ", " + modelCoords.getY() + "]");
    }


    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        double factor = pow(1.1, e.getWheelRotation());
        canvas.zoom(factor, -e.getX(), -e.getY());
    }
}
public类模型扩展了Observable实现,可移植、可序列化{
私有列表行;
私人名单;
公共模型(){
行=新的ArrayList();
tmpLines=新的ArrayList();
}
公共模型(字符串文件名){
readFromFile(文件名);
}
公共空白添加(Line2D线){
行。添加(行);
脏的();
}
公共空间{
setChanged();
通知观察员();
}
public void readFromFile(字符串文件名){
行=新的ArrayList();
tmpLines=新的ArrayList();
试一试{
BufferedReader b=新的BufferedReader(新文件读取器(文件名));
对于(字符串行=b.readLine();行!=null;行=b.readLine()){
String[]tokens=line.split(“”);
if(标记[0]。等于(“行”)){
double-x1=double.parseDouble(令牌[1]);
double y1=double.parseDouble(令牌[2]);
double x2=double.parseDouble(令牌[3]);
double y2=double.parseDouble(令牌[4]);
添加(新的Line2D.Double(x1,y1,x2,y2));
}
}
} 
catch(filenotfounde异常){
e、 printStackTrace();
} 
捕获(IOE异常){
e、 printStackTrace();
}
}
/**
*返回{@code T}类型元素的迭代器。
*
*@返回一个迭代器。
*/
@凌驾
公共迭代器迭代器(){
返回行。迭代器();
}
public Line2D RemoveLastFromtPlines(){
Line2D line=tmpLines.remove(tmpLines.size()-1);
脏的();
回流线;
}
public Line2D removeLastFromLines(){
Line2D line=lines.remove(lines.size()-1);
脏的();
回流线;
}
public void addTmpLinesToLines(){
行。添加所有(tmpLines);
脏的();
}
公共void addToTemplines(Line2D Line2D){
tmpLines.add(line2D);
脏的();
}
公共列表getTemplines(){
返回tmpLines;
}
}
公共类MouseController扩展了MouseAdapter{
私有模型;
私人画布;
私人鼠标位置;
公共鼠标控制器(CanvasView c,m型){
canvas=c;
模型=m;
canvas.addMouseListener(本);
canvas.addMouseWheelListener(此);
canvas.addMouseMotionListener(此);
}
@凌驾
公共无效鼠标标记(鼠标事件e){
Point2D currentMousePosition=e.getPoint();
if(canvas.inDrawingMode()){
Point2D origin=model.removeLastFromTmpLines().getP1();
model.addToTemplines(新的Line2D.Double(origin、canvas.toModelCoords(currentMousePosition));
}
否则{
double dx=currentMousePosition.getX()-lastMousePosition.getX();
double dy=currentMousePosition.getY()-lastMousePosition.getY();
canvas.pan(dx,dy);
}
lastMousePosition=currentMousePosition;
}
@凌驾
公共无效鼠标按下(MouseEvent e){
lastMousePosition=e.getPoint();
if(canvas.inDrawingMode()){
model.AddToTemplines(新的Line2D.Double(
canvas.toModelCoords(lastMousePosition),
canvas.toModelCoords(lastMousePosition));
}
}
public void mouseMoved(MouseEvent e){
Point2D modelCoords=canvas.toModelCoords(e.getPoint());
//System.out.println(“屏幕:[“+e.getX()+”,“+e.getY()+”],“+”模型:[“+modelCoords.getX()+”,“+modelCoords.getY()+”);
}
@凌驾
已移动公共无效鼠标滚轮(鼠标滚轮事件e){
双因素=功率(1.1,即getWheelRotation());
缩放(factor,-e.getX(),-e.getY());
}
}

老实说,我不太理解代码,因为我看不到绘制方法,所以我看不到对数组的处理。我支持在列表中添加行,并使用迭代器方法将它们返回到paint方法

我支持在按下鼠标按钮时添加点,而不是线:

model.addToTmpLines(new Line2D.Double(
               canvas.toModelCoords(lastMousePosition),
               canvas.toModelCoords(lastMousePosition)));
点,因为坐标相同。然后,拖动鼠标时,删除最后一条线(点),并从点的起始坐标添加一条新线到实际鼠标位置。是这样吗?但是,您什么时候将tmp列表中的行传递到真实列表中?您不需要一个mousererelease方法来将tmp列表中的行传递到实际列表吗?迭代器方法只返回列表行,因此我支持不绘制最后一行,即正在拖动的行,因为实际的新行位于tmpLines列表中,并且不会返回


但是我认为我没有看到整个画面,所以我的评论可能没有用…

当你更新模型时,你必须重新绘制视图。我正在视图类中更新模型。我解决了我的问题,现在可以在画布上画画了。但是,当我试图将添加的行保存到现有行时,会得到一个NullPointerException。您知道这可能是什么原因吗?好的,使用ex.printStackTrace查看引发异常的行,并使用调试器查看哪个变量为null。如果使用addTmpLinesToLines方法,则averything看起来不错,因为创建了两个列表,但问题可能出在调用dirty()后激发的方法中。例如,printStackTrace非常适合于此