Ponieważ to mój pierwszy post tutaj, na początek witam wszystkich i zgłaszam się z prośbą o pomoc.
Dla wyjaśnienia mojego problemu napisałem prostą aplikację wzorowaną na przykładzie z książki "Java podstawy". Tworzy ona okno z dodanym komponentem i na każde kliknięcie reaguje dodaniem/narysowaniem kwadratu w miejscu kliknięcia. Ostatnio dodany kwadrat jest wyróżniony wypełnieniem.
Kod programu: listing1 na końcu post'a.
Co chciałbym uzyskać: chciałbym, aby wyróżnienie ostatniego kwadratu stopniowo zanikało, co teoretycznie udało mi się uzyskać (listing2), ale jest problem, którego nie potrafię rozwiązać. Timer, który wywołuje obiekt klasy FillFadeHandler zmniejszający wartosc alpha dla koloru wypełnienia, działa w nieskończoność. Zauważalne to jest, jeśli porówna się szybkość, z jaką maleje wartość zmiennej iFillAlpha w przypadku gdy na komponencie jest jeden kwadrat, lub wiele kwadratów.
Czyli rozwiązanie którego potrzebuję, to możliwość zakończenia działania Timera w dwóch sytuacjach:
- gdy zmniejszana wartość zmiennej iFillAlpha dojdzie do 0
- gdy nastąpi kolejne kliknięcie tworzące nowy Timer
Jednak nie wiem, gdzie i w jaki sposób należy zakończenie Timer'ów wstawić.
Z góry dziękuję za wszelką pomoc.
PS. Jeśli w prezentowanym kodzie są rzeczy zrobione w sposób nieprawidłowy, też sie chętnie o tym dowiem. W tematyce Javy dopiero startuję, więc sporo jest ekspetymentów ;)
listing1 TimerTest1.java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class TimerTest1
{
public static void main(String[] args)
{
EventQueue.invokeLater(
new Runnable()
{
public void run()
{
JFrame oOkno = new JFrame();
oOkno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
oOkno.setMinimumSize(new Dimension(640, 480));
oOkno.setPreferredSize(new Dimension(640, 480));
oOkno.setLocationRelativeTo(null);
TimerComponent oComponent = new TimerComponent();
oOkno.add(oComponent);
oOkno.setVisible(true);
}
}
);
}
}
class TimerComponent
extends JComponent
{
private static final int DLUGOSC_BOKU = 10;
private ArrayList<Rectangle2D> aKwadraty;
private Rectangle2D oOstatniDodany;
private class MouseHandler
extends MouseAdapter
{
@Override public void mousePressed(MouseEvent event)
{
dodaj(event.getPoint());
repaint();
}
}
public TimerComponent()
{
aKwadraty = new ArrayList<Rectangle2D>();
oOstatniDodany = null;
addMouseListener(new MouseHandler());
}
@Override public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.drawString("Ilość: " + aKwadraty.size(), 3, 12);
for (Rectangle2D oKwadrat: aKwadraty)
{
if (oKwadrat == oOstatniDodany)
{
g2.setColor(new Color(255, 0, 0));
g2.fill(oKwadrat);
g2.setColor(new Color(0, 0, 0));
}
g2.draw(oKwadrat);
}
}
public void dodaj(Point2D oPunkt)
{
oOstatniDodany = new Rectangle2D.Double(oPunkt.getX() - DLUGOSC_BOKU / 2, oPunkt.getY() - DLUGOSC_BOKU / 2, DLUGOSC_BOKU, DLUGOSC_BOKU);
aKwadraty.add(oOstatniDodany);
}
}
listing2 TimerTest2.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class TimerTest2
{
public static void main(String[] args)
{
EventQueue.invokeLater(
new Runnable()
{
public void run()
{
JFrame oOkno = new JFrame();
oOkno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
oOkno.setMinimumSize(new Dimension(640, 480));
oOkno.setPreferredSize(new Dimension(640, 480));
oOkno.setLocationRelativeTo(null);
TimerComponent oComponent = new TimerComponent();
oOkno.add(oComponent);
oOkno.setVisible(true);
}
}
);
}
}
class TimerComponent
extends JComponent
{
private static final int DLUGOSC_BOKU = 10;
private ArrayList<Rectangle2D> aKwadraty;
private Rectangle2D oOstatniDodany;
private int iFillAlpha;
private class FillFadeHandler
implements ActionListener
{
public void actionPerformed(ActionEvent oEvent)
{
if (iFillAlpha > 0)
{
--iFillAlpha;
repaint();
}
}
}
private class MouseHandler
extends MouseAdapter
{
@Override public void mousePressed(MouseEvent event)
{
dodaj(event.getPoint());
repaint();
Timer oTimer = new Timer(20, new FillFadeHandler());
oTimer.start();
}
}
public TimerComponent()
{
aKwadraty = new ArrayList<Rectangle2D>();
oOstatniDodany = null;
iFillAlpha = 255;
addMouseListener(new MouseHandler());
}
@Override public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.drawString("Ilość: " + aKwadraty.size(), 3, 12);
g2.drawString("FillAlpha: " + iFillAlpha, 3, 24);
for (Rectangle2D oKwadrat: aKwadraty)
{
if (oKwadrat == oOstatniDodany)
{
g2.setColor(new Color(255, 0, 0, iFillAlpha));
g2.fill(oKwadrat);
g2.setColor(new Color(0, 0, 0));
}
g2.draw(oKwadrat);
}
}
public void dodaj(Point2D oPunkt)
{
oOstatniDodany = new Rectangle2D.Double(oPunkt.getX() - DLUGOSC_BOKU / 2, oPunkt.getY() - DLUGOSC_BOKU / 2, DLUGOSC_BOKU, DLUGOSC_BOKU);
aKwadraty.add(oOstatniDodany);
iFillAlpha = 255;
}
}