Wątek to program sekwencyjny, który może być wykonywany współbieżnie z innymi wątkami.
run()start()run()
Uwaga - wywołanie run() wykona funkcję, ale nie jako osobny wątek.
Zadeklaruj klasę Clock
public class Clock extends Thread{ @Override public void run() { } public static void main(String[] args) { new Clock().start(); } }
Następnie w metodzie run()
LocalTime time = LocalTime.now(); System.out.printf("%02d:%02d:%02d\n", time.getHour(), time.getMinute(), time.getSecond());
Prawdopodobnie ten sam czas drukuje się wielokrotnie.
Uśpij wątek na jedną sekundę (1000 milisekund) wprowadzając wywołanie metody sleep()
Zaimplementujemy zegar analogowy wyświetlający (i przesuwający wskazówki).
ClockWithGui dziedziczącej po JPanel. main() utworzona zostanie ramka, dodany do niej panel, itdpublic class ClockWithGui extends JPanel { LocalTime time = LocalTime.now(); public static void main(String[] args) { JFrame frame = new JFrame("Clock"); frame.setContentPane(new ClockWithGui()); frame.setSize(700, 700); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(true); frame.setVisible(true); } }
Kod umieszczamy w paintComponent()
Poniżej przykład rysowania cyfr na tarczy.
360/12 stopniy rosną w dół. Lokalizacja cyfr nie jest idealna, warto odjąć od x (przed przekształceniem) szerokość tekstu. Jeszcze lepiej zrealizowana metoda powinna odczytać wymiary tekstu dla danej czcionki.public void paintComponent(Graphics g){ Graphics2D g2d=(Graphics2D)g; g2d.translate(getWidth()/2,getHeight()/2); for(int i=1;i<13;i++){ AffineTransform at = new AffineTransform(); at.rotate(2*Math.PI/12*i); Point2D src = new Point2D.Float(0,-120); Point2D trg = new Point2D.Float(); at.transform(src,trg); g2d.drawString(Integer.toString(i),(int)trg.getX(),(int)trg.getY()); } }
Gdyby ktoś potrzebował inspiracji - można zajrzeć na kod rysujący tarczę zegara w JavaScript.
Kontekst graficzny ctx w JavaScript jest analogiem Grapics2D w bibliotece Swing. Transformacje afiniczne mają podobną postać…
Tak możemy narysować jedną ze wskazówek (godzinową)…
Ale popraw poniższy kod, ponieważ położenie wskazówek na ogół nie zmienia się skokowo np. przy zmianie z 11:59:59 na 12:00:00.
AffineTransform saveAT = g2d.getTransform(); g2d.rotate(time.getHour()%12*2*Math.PI/12); g2d.drawLine(0,0,0,-100); g2d.setTransform(saveAT);
Możesz zmienić kształt (np. narysować wielobok) lub użyć pogrubienia g2d.setStroke(new BasicStroke(???, CAP_ROUND,JOIN_MITER))
Dorysuj samodzielnie…
W klasie ClockWithGui zadeklaruj klasę wewnętrzną będącą wątkiem.
class ClockThread extends Thread{ @Override public void run() { for(;;){ time = LocalTime.now(); System.out.printf("%02d:%02d:%02d\n",time.getHour(),time.getMinute(),time.getSecond()); //sleep(1000); repaint(); } } }
ClockThread możliwy jest dostęp do atrybutu time?repaint()? Jest to metoda wątku czy JPanel?