Reputation: 73
I posted this code earlier, and got a very good answer, but not a working answer. Could someone please show me how to change my code in order to get this fixed? This will run and compile. It is supposed to draw a line on top of a line, but instead it is drawing under the previous line. I have tried using Collections.reverse(segments); but it doesn't take care of element at zero. I also have tried changing to segments.add(new Segment()); but I am not sure what to change in MouseMotionListener to get this to work accordingly. Any help with this would be great! Thank You! :)
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);
}
}
Upvotes: 0
Views: 31
Reputation: 1842
To fix your issue, you need to add to the end of the List
and not the beginning:
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();
}
});
Additionally, the second mouseDragged()
implementation appears redundant, if you remove it, it still functions as expected.
// Can be removed
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
points.add(e.getPoint());
repaint();
}
});
Also, you should really use a JComponent
or JPanel
to paint your sketch, @Override
paintComponent()
as opposed to paint()
with this approach. This will help (or should completely) remove the flickering you see. Coupled with a javax.swing.Timer
to repaint()
as opposed to dragging which could update extremely (and unnecessarily) quickly.
Finally, you should ensure your GUI is running on the event dispatch thread using SwingUtilities.invokeLater(Runnable doRun)
, since 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);
}
});
}
Upvotes: 1