绘图程序:数组向后写入面板

时间:2016-11-04 23:57:39

标签: java

我之前发布了这段代码,得到了一个非常好的答案,但不是一个有效的答案。有人可以告诉我如何更改我的代码,以解决这个问题吗?这将运行并编译。它应该在一条线的顶部绘制一条线,而是在前一条线下绘制。我尝试过使用Collections.reverse(segments);但它没有处理零元素。我也尝试过更改为segments.add(new Segment());但我不确定要在MouseMotionListener中更改什么才能使其相应地工作。任何帮助都会很棒!谢谢! :)

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

public class SimplePaint extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;
JButton action = new JButton();
JButton red = new JButton();
JButton blue = new JButton();
JButton yellow = new JButton();
Color initial = Color.MAGENTA;
JButton thin = new JButton();
JButton medium = new JButton();
JButton thick = new JButton();
Stroke stroke = new BasicStroke(3);
private static ArrayList<Point> points = new ArrayList<Point>();

JButton erase = new JButton();
JButton drawing = new JButton();
Point start = null;
Point end = null;
Line2D draw = new Line2D.Float();
JPanel panel = new JPanel();

private class Segment {
    private final List<Point> points = new ArrayList<Point>();
    private final Color color = initial;
    private final Stroke stroke = SimplePaint.this.stroke;
}

private final List<Segment> segments = new ArrayList<>();

public SimplePaint() {
    getContentPane().add(panel);
    setSize(450, 450);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    design();

    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            segments.add(0, new Segment());
        }
   });

    addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseDragged(MouseEvent e) {
            segments.get(0).points.add(e.getPoint());
            repaint();
        }
    });

    addMouseMotionListener(new MouseMotionAdapter(){

        @Override
        public void mouseDragged(MouseEvent e){
            points.add(e.getPoint());
            repaint();
        }
    });

    blue.addActionListener(this);
    red.addActionListener(this);
    yellow.addActionListener(this);
    thin.addActionListener(this);
    medium.addActionListener(this);
    thick.addActionListener(this);
    erase.addActionListener(this);
    drawing.addActionListener(this);
}

public void design() {
    panel.setBackground(Color.BLACK);

    blue.setBackground(Color.BLUE);
    blue.setPreferredSize(new Dimension(50, 25));
    panel.add(blue);

    red.setBackground(Color.RED);
    red.setPreferredSize(new Dimension(50, 25));
    panel.add(red);

    yellow.setBackground(Color.yellow);
    yellow.setPreferredSize(new Dimension(50, 25));
    panel.add(yellow);

    thin.setText("Thin");
    panel.add(thin);

    medium.setText("Medium");
    panel.add(medium);

    thick.setText("Thick");
    panel.add(thick);

    erase.setText("Erase");
    panel.add(erase);

    drawing.setText("Draw");
    panel.add(drawing);
}

public void actionPerformed(ActionEvent e) {
    if(e.getSource() == blue){
        initial = Color.BLUE;
    }else if(e.getSource() == red){
        initial = Color.RED;
    }else if(e.getSource() == yellow){
        initial = Color.YELLOW;
    }else if(e.getSource() == thin){
        stroke = new BasicStroke(1);
    }else if(e.getSource() == medium){
        stroke = new BasicStroke(5);
    }else if(e.getSource() == thick){
        stroke = new BasicStroke(10);
    }else if(e.getSource() == erase){
        initial = Color.WHITE;
        stroke = new BasicStroke(15);
    }

    //repaint();
}

@Override
public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2 = (Graphics2D) g;

    int x1, y1, x2, y2;

    for (Segment segment : segments) {
        g2.setColor(segment.color);
        g2.setStroke(segment.stroke);

        for (int p = 0; p < segment.points.size() - 1; p++) {
            x1 = segment.points.get(p).x;
            y1 = segment.points.get(p).y;
            x2 = segment.points.get(p + 1).x;
            y2 = segment.points.get(p + 1).y;
            g2.drawLine(x1, y1, x2, y2);


        }

    }
    g2.dispose();

}  

public static void main(String []args){
    SimplePaint s = new SimplePaint();
    s.setVisible(true);
}
}

1 个答案:

答案 0 :(得分:1)

要解决您的问题,您需要添加到List的末尾而不是开头:

addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        segments.add(new Segment());
    }
});

addMouseMotionListener(new MouseMotionAdapter() {
    @Override
    public void mouseDragged(MouseEvent e) {
       segments.get(segments.size() - 1).points.add(e.getPoint());
       repaint();
    }
});

此外,第二个mouseDragged()实现似乎是多余的,如果删除它,它仍然按预期运行。

// Can be removed
addMouseMotionListener(new MouseMotionAdapter() {    
    @Override
    public void mouseDragged(MouseEvent e) {
        points.add(e.getPoint());
        repaint();
    }
});

此外,您应该使用JComponentJPanel绘制草图,@Override paintComponent()而不是paint()。这将有助于(或应该完全)消除您看到的闪烁。加上javax.swing.Timerrepaint(),而不是拖动,可以快速更新(并且不必要)。

最后,您应该使用SwingUtilities.invokeLater(Runnable doRun)确保您的GUI在事件派发线程上运行,因为Swing objects are not thread safe

e.g。

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            SimplePaint s = new SimplePaint();
            s.setVisible(true);
        }
    });
}