AWT rysowanie figur na podstawie elementów kolekcji

0

Cześć, jestem nowy na forum i piszę w sprawie problemu, który mam z moim aktualnym zadaniem. Mam zrobić za pomocą AWT program w stylu painta, w którym mam przykładowo malować linie za pomocą myszki(naciskam, przeciągam, puszczam) i mamy linię. Tylko problem polega na tym, że chciałbym przy tym tworzyć element klasy Linia i dodać go do kolekcji takich elementów, a następnie na podstawie tej kolekcji nanieść wszystkie linie na ekran. Mój problem polega na tym, że nie bardzo wiem jak właśnie zrobić by program nanosił linie na podstawie elementów kolekcji. Aktualnie jak nacisnę klawisz myszy, przeciągnę ją i puszczę, to jest tworzony obiekt linia i jest sama linia namalowana, lecz nie na podstawie kolekcji. Domyślam się, że wypadałoby zrobić pętle, w której pobierałbym elementy kolekcji i je rysował, ale przyznam, że nie mam pojęcia gdzie taką pętle zamieścić i jak to technicznie rozwiązać. Poniżej zamieszczam część kodu, który napisałem.

public Zbior zbiorLinii= new Zbior();

    public Point p1;
    public Point p2;

    private WindowListener frameList = new WindowAdapter()
    {  
        public void windowClosing (WindowEvent ev)
        {
            MyFrame.this.dispose();
        }
    };
    private MouseListener mouseList = new MouseAdapter()
    {
        
        public void mouseReleased(MouseEvent ev) 
        {
            p2 = new Point(ev.getX(), ev.getY());
            Linia l1 = new Linia(p1, p2);
            zbiorLinii.add(k1);
            Graphics graph = can.getGraphics();
            graph.setColor(Color.RED);
            graph.drawLine(l1.poczatek.x, l1.poczatek.y, l1.koniec.x, l1.koniec.y);
            repaint ();
        }
        
        public void mousePressed ( MouseEvent ev )
        {
            p1 = new Point(ev.getX(), ev.getY());
            repaint ();
        }
    };

    private MyCanvas can = new MyCanvas();
    

    public MyFrame ()
    {
        super("Paint");
        setSize(800,600);
        setLocation(300,100);
        add(can,BorderLayout.CENTER);
        can.addKeyListener(keyList);
        can.addMouseListener(mouseList);
        can.setFocusable(true);
        can.requestFocus();
        addWindowListener(frameList);
        setVisible(true);
    }
}
0

W metodzie

public void paint(Graphics g)

klasy MyCanvas.
W metodzie mouseReleased niczego nie rysuj. To i tak zniknie jak użytkownik zminimalizuje okno programu.

0
for(Linia l : kolekcjaLini)
   rysuj(l);

To taki szablon, po prostu przelatujesz przez całą kolekcję, wyciągasz następny element i mając ten element rysujesz go.

0

Dzięki wielkie za odpowiedź. Teraz mam jeszcze parę pytań. Czy wyłapywać "akcję" myszy powinienem w klasie myframe czy mycanvas?
Wydaje mi się, że w myframe, ale z drugiej strony utrudnia to przekazywanie kolekcji linii do funkcji rysowania w klasie mycanvas.
Poza tym jeśli chciałbym dodać funkcję usuwania linii to wydaje mi się że nawet jeśli usunę linię z kolekcji to i tak nie zniknie dopóki nie użyję metody repaint, a jeśli dodam tę funkcję po pętli rysowania linii z kolekcji to wszystko zaczyna migać, co jest dla mnie zrozumiałe, ale nie widzę alternatywy. Przepraszam za kłopot, ale mam problem ze "skumaniem" schematu działania aplikacji w AWT.

1

Nigdy nie wywołuj repaint w metodzie paint. Tworzysz wtedy nieskończony ciąg wywołań (repaint pośrednio wywołuje paint).
MouseListener może być w klasie MyFrame. W klasie MyCanvas przechowuj referencję do klasy MyFrame

//w klasie MyFrame
private MyCanvas can = new MyCanvas(this);
//w klasie MyCanvas
public class MyCanvas extends Canvas
{
      private MyFrame okno = null;
      ...
      public MyCanvas(MyFrame okno)
      {
          this.okno = okno;
...
    public void paint(Graphics g)
    {
        super.paint(g); 
        //iteracja po kolekcji okno.listaOdcinkow
0

Dzięki, prawie działa, tylko linie mi się pojawiają dopiero jak zminimalizuje okno lub zmienię jego rozmiar. Czyli metoda paint jest tylko raz wywoływana i potem podczas modyfikacji rozmiaru okna, tak? Powinienem ją wrzucić do pętli ?

Już wszystko elegancko działa. Problemem okazało się złe wywoływanie metody repaint() - nie wywoływałem jej na obiekcie canvas.

1 użytkowników online, w tym zalogowanych: 0, gości: 1