Witam, nowicjusz ze mnie i dlatego w ramach nauki piszę sobie jakieś tam programy w Swingu. Aktualnie mam problem z tym kodem:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
/**
* Created by sokar on 03.11.15.
*/
public class MouseEventsInPainLikeAPP {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
@Override
public void run() {
JFrame ramka = new RamkaDoRysowania();
ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ramka.setVisible(true);
}
});
}
}
class RamkaDoRysowania extends JFrame{
public RamkaDoRysowania(){
this.setTitle("Rysuj");
this.setSize(600,400);
JPanel panel = new PanelDoRysowania();
this.add(panel);
}
}
class PanelDoRysowania extends JPanel{
private JPanel panel = null;
ArrayList<Line> lines = null;
public PanelDoRysowania(){
panel = this;
lines = new ArrayList<Line>();
//definiowanie kursora, zmiana na krzyżyk
panel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
});
this.addChangingBackgroundButton(Color.RED, "Red");
this.addChangingBackgroundButton(Color.GREEN, "Green");
this.addChangingBackgroundButton(Color.BLUE, "Blue");
this.addPaintALineButton();
}
private void addChangingBackgroundButton(final Color c, String colorName){
JButton button = new JButton(colorName);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
panel.setBackground(c);
}
});
//zmiana kusrosra na domyśny
button.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
});
panel.add(button);
}
private void addPaintALineButton(){
final Point startPoint = new Point();
final Point stopPoint = new Point();
JButton button = new JButton("Paint a line");
panel.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
panel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startPoint.setLocation(e.getPoint());
}
@Override
public void mouseReleased(MouseEvent e) {
stopPoint.setLocation(e.getPoint());
Line line = new Line(startPoint, stopPoint);
lines.add(line);
System.out.println(lines.size());
System.out.println(startPoint.toString() + stopPoint.toString());
System.out.println(lines.get(0).getStartPoint().toString() + lines.get(0).getStopPoint().toString());
repaint();
}
});
}
});
}
private static class Line{
private Point startPoint = null;
private Point stopPoint = null;
public Line(Point startPoint, Point stopPoint) {
this.startPoint = startPoint;
this.stopPoint = stopPoint;
}
public Point getStartPoint(){
return startPoint;
}
public Point getStopPoint() {
return stopPoint;
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(Line l: lines){
g2d.drawLine(l.getStartPoint().x, l.getStartPoint().y, l.getStopPoint().x, l.getStopPoint().y);
//System.out.println(lines.size());
//System.out.println(l.getStartPoint().toString() + l.getStopPoint().toString());
}
}
}
Problem polega na tym, że metoda JPanel.paintComponent() rysuje przy repaint() tylko jedną linie a właściwie wiele linii znajdujących się w *ArreyList lines * tyle, że te zawsze są takie same. Błąd jest gdzieś w metodzie addPaintALineButton() polegający na tym, że wszystkie linie line należące do ArreyList List mają wewnętrzne referencje do tych samych startPoint i stopPoint.
Tyle że ja nowicjusz i nie bardzo widzę co gdzie pomotałem z tymi klasami wewnętrznymi i finalnymi zmiennymi, także jak by ktoś dobry łopatologicznie wytłumaczył gdzie popełniłem błąd i dlaczego.
Pozdrawiam