Eseménykezelés. Aszinkron kommunikáció

Hasonló dokumentumok
Eseménykezelés. Aszinkron kommunikáció

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

Java Programozás 11. Ea: MVC modell

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Eseményvezérelt alkalmazások fejlesztése I 3. előadás. Dinamikus felületű alkalmazások. Giachetta Roberto

Grafikus felhasználói felületek. Dr. Szendrei Rudolf Informatikai Kar Eötvös Loránd Tudományegyetem. Programozási technológia I. Dr.

Concurrency in Swing

ESEMÉNY VEZÉRELT ALKALMAZÁSOK FEJLESZTÉSE I. Bevezetés. Készítette: Gregorics Tibor

Adatbázis alapú rendszerek gyakorlat Adatbázis alapú alkalmazásfejlesztés Java, C# környezetben

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III. A Qt assistant elindítása. Ajánlott ir odalom. A Qt assistant nyitó ablaka

Elemi alkalmazások fejlesztése IV. Adatbázis-kezelő GUI alkalmazás készítése 3. Összetett tábla karbantartása

Programozási technológia

Tervezőeszközök, fejlesztőeszközök használata Qt alapú alkalmazásoknál. Saját vezérlő használata tervezőben (worldclocks)

Budapest, március. ELTE Informatikai Kar

Alkalmazások fejlesztése III. Qt 4 /C++ alapú grafikus alkalmazás Bevezetés I.

Elemi alkalmazások fejlesztése III

Dinamikus felületű alkalmazások. Stílusok, időzítő, képek

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Java Programozás 3. Gy: Java GUI. Swing, AWT

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

Szoftvertechnológia alapjai Java előadások

Programozás II. ATM példa Dr. Iványi Péter

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

QLabel *label = new Qlabel("Hello Qt!",0);

abkezel.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.sql.*; public class abkezel extends JFrame {

Form1 Form Size 400;400 Text Mozgó kör timer1 Timer Enabled True Interval 100

Programozás II gyakorlat. 4. Öröklődés

BME MOGI Gépészeti informatika 4.

BME MOGI Gépészeti informatika 7.

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Grafikus Qt programok írása segédeszközök nélkül

Java programozási nyelv 4. rész Osztályok II.

Java Programozás 8. Gy: Java alapok. Adatkezelő 4.rész

Programozási technológia

Hálózati alkalmazások

Tervminták a valósidejű gyakorlatban

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Ugráló gomb oktatási segédlet Ugráló gomb

Osztályok. 4. gyakorlat

Konkurens TCP Szerver

components : IContainer dx : int dy : int tmidőzítő : Timer toolstripseparator1 : ToolStripSeparator tsmikilépés : ToolStripMenuItem

Access adatbázis elérése OLE DB-n keresztül

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Giachetta Roberto

Elemi alkalmazások fejlesztése IV.

MySql elindítása. Elemi alkalmazások fejlesztése IV. Feladat. Az alkalmazás adatbázisa

Swing GUI készítése NetBeans IDE segítségével

GenerikusOsztály<objektumtípus> objektum = new GenerikusOsztály<objektumtípus>();

Szoftvertechnológia alapjai Java előadások

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

Eseménykezelés - Lottó játék

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

Informatika terméktervezőknek

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

CAN alapú járműves adatokat megjelenítő szoftver fejlesztése

OOP: Java 8.Gy: Abstract osztályok, interfészek

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

// keressük meg a legnagyobb faktoriális értéket, ami kisebb, // mint százmillió

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

Johanyák Zsolt Csaba: Grafikus felület programozása. Copyright 2008 Johanyák Zsolt Csaba

Helyes-e az alábbi kódrészlet? int i = 1; i = i * 3 + 1; int j; j = i + 1; Nem. Igen. Hányféleképpen lehet Javaban megjegyzést írni?

Elemi alkalmazások fejlesztése III

Java és web programozás

Elemi alkalmazások fejlesztése III.

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

2. Beadandó feladat dokumentáció

Alkalmazások fejlesztése III. Qt 4 /C++ alapú MDI alkalmazás: Számlakészítő program 3/3

Java felhasználói felület

C#, OOP. Osztályok tervezése C#-ban

BME MOGI Gépészeti informatika 8.

Végrehajtási szálak - kiegészítések. Szinkronizálás, érvénytelenített metódusok helyettesítése

A C# programozási nyelv alapjai

Vé V g é r g e r h e a h j a tá t s á i s s z s ál á ak a Runnable, Thread

3D-s számítógépes geometria és alakzatrekonstrukció

Sorosítás (szerializáció) és helyreállítás. 1. Bináris sorosítás és helyreállítás Szükséges névterek Attribútumok. 1.3.

Objektum elvű alkalmazások fejlesztése Kifejezés lengyel formára hozása és kiértékelése

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Programozási nyelvek Java

Programozás BMEKOKAA146. Dr. Bécsi Tamás 1. Előadás

2. Beadandó feladat dokumentáció

BME MOGI Gépészeti informatika 1.

Mérési adatgyűjtés és adatfeldolgozás 2. előadás

Segédanyag: Java alkalmazások gyakorlat

CREATE TABLE student ( id int NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name varchar(100) NOT NULL, address varchar(100) NOT NULL )

Kölcsönös kizárás, atomicitás, szemafor.

1. Alapok. Programozás II

Elemi alkalmazások fejlesztése III.

osztályok kapcsolata Származtatatás C++ Izsó Tamás március 19. Izsó Tamás Származtatatás/ 1

Segítség a megoldáshoz: 1. Készítse el a Window-t az ábrának és az osztálydiagramnak megfelelően.

Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

Java Programozás 5. Gy: Java alapok. Adatkezelő 1.rész

Qt rajzolás munkafüzet. Elemi Alkalmazások fejlesztése 3.

Átírás:

Eseménykezelés Aszinkron kommunikáció

Feladat Készítsünk egy stoppert, amely másodpercenként jelzi a múló időt. Ez a folyamat egy adott jelzés hatására induljon el; ugyanezen jelzés ismétléseinek hatására váltakozva szüneteljen, illetve folytatódjon tovább; egy adott másik jelzés hatására álljon le. 2

Használati eset diagram inicializálja az alkalmazást <<invoke>> kijelző nulla másodpercet mutat elindítja a stoppert <<invoke>> kijelző értéke másodpercenként eggyel nő user megállítja a stoppert <<invoke>> kijelző nem változik kilép a programból 3

user Kommunikációs diagram click quit szinkron metódus hívás a user által okozott esemény váltja ki a click szignált, amely aszinkron üzenetként érkezik a stopperhez display(seconds) start() stop() : Stopwatch : Timer : LcdNumber tick az időzítő aszinkron módon küldi a tick szignált a stopperhez A stopper és az időzítő önálló működéssel bíró ún. aktív objektumok. A stoppernek a számára küldött szignálokat azok érkezésével párhuzamosan kell feldolgoznia. Az időzítőnek mindentől függetlenül másodpercenként kell szignált küldenie. 4

Szekvencia diagram <<create>> : Stopwatch <<create>> start() : Timer <<create>> : LcdNumber loop tick [ per seconds] loop click loop tick [ per seconds] display() click loop quit tick [ per seconds] stop() 5

Osztálydiagram Stopwatch Timer seconds : int owner timer + start() + stop() «enumeration» Signal tick click quit lcd display(int) LcdNumber 6

Stopwatch állapotgépe / seconds := 0 / lcd.display(seconds) / timer.start() tick stopped quit / timer.stop() click click tick / lcd.display(++seconds) quit / timer.stop() operate statemachine() seconds := 0 lcd.display(seconds) timer.start() currentstate := stopped active := true while active loop transition(getsignal()) endloop timer.stop() transition(signal : Signal) switch (currentstate) case stopped: switch (signal) case click: currentstate := operate case tick: skip case quit: active := false endswitch case operate: switch (signal) case click: currentstate := stopped case tick: lcd.display(++seconds) case quit: active := false endswitch endswitch 7

Timer állapotgépe / send tick to owner start() do/várakozik 1 mp-ig stop() start() active := true statemachine() statemachine() while (active) wait 1 sec send tick to owner endwhile stop() active := false 8

Megvalósítás Többszálú alkalmazásra van szükség, hisz több aktív objektum is van. Külön szálon kell futnia a stopper és az időzítő állapotgépének. A stopper objektum a hozzá több irányból érkező aszinkron üzeneteket (a szignálokat) egy eseménysorba gyűjti. Az eseménysorba egy szignált a küldő objektum úgy tesz be, hogy a saját szálán (ez fő program vagy az időzítő szála) meghívja a stoppernek a send() metódusát, amely eléri az eseménysort. Az eseménysorból egy szignált a stopper külön szálon futó állapotgépe vesz ki a stopper getsignal() metódusa segítségével. Az eseménysor betesz és kivesz műveleteit szinkronizálni kell: kölcsönösen kizárásos módon kell működniük. Ráadásul üres sor esetén a kivesz műveletet várakozó utasítással blokkolni kell. 9

Kommunikációs diagram (megvalósítási szint) user send(click) send(quit) display(seconds) : ThreadSafeQueue enqueue() dequeue() start() stop() : Stopwatch : Timer send(tick) : LcdNumber A stopper a saját szálán hívja a dequeque()-t, hogy feldolgozza az eseményeket, ami aszinkron reakciót szimulál. Az aszinkron üzenet küldést a stopper állapotgépétől eltérő szálakon kezdeményezett szinkron hívás helyettesíti, amely az enqueue()-t hívja. Gregorics Tibor: Objektumelvű alkalmazások fejlesztése 10

Osztálydiagram (megvalósítási szint) «enumeration» State operate stopped eventqueue.enqueue(s) Stopwatch - seconds : int - currentstate : State - active : bool - statemachine() : void - transition(signal) : void + send(s : Signal):void - getsignal() : Signal - owner - timer - lcd eventqueue.dequeue(s) Timer - active : bool + start() + stop() - statemachine() : void + display(int) LcdNumber Item ThreadSafeQueue «enumeration» Signal tick click quit Item/Signal - eventqueue + enqueue(item) + dequeue(item) 11

Stopwatch osztály class Stopwatch public: Stopwatch(); enum Signal tick, click, quit; ~Stopwatch(); void send(signal event) _eventqueue.enqueue(event); private: enum State operate, stopped; void statemachine(); void transition(signal event); Signal getsignal() ; Timer _timer; LcdNumber _lcd; ThreadSafeQueue<Signal> _eventqueue; State _currentstate; int _seconds; külön szál a Stopwatch::stateMachine()-nek #include <thread> bool _active; std::thread _thread; ; stopwatch.h 12

Stopwatch osztály Stopwatch::Stopwatch():_timer(this) _eventqueue.startqueue(); _thread = std::thread(&stopwatch::statemachine, this); Stopwatch::~Stopwatch() _thread.join(); _eventqueue.stopqueue(); bevárja amíg az állapotgép le nem áll külön szálon indul el a Stopwatch állapotgépe void Stopwatch::stateMachine() _seconds = 0; _lcd.display(_seconds); _timer.start(); _currentstate = stopped; _active = true; while(_active) //amíg nincs terminálás transition(getsignal()); _timer.stop(); Signal getsignal() Signal s; _eventqueue.dequeue(s); return s; stopwatch.cpp 13

Stopwatch eseménykezelője void Stopwatch::transition(Signal signal) switch (_currentstate) // mi az állapot case stopped: switch (signal) // mi a szignál case click: _currentstate = operate; break; case tick : break; case quit : _active = false; break; break; case operate: switch (signal) // mi a szignál case click: _currentstate = stopped; break; case tick : _lcd.display(++_seconds); break; case quit : _active = false; break; break; stopwatch.cpp 14

Timer osztály class Stopwatch; A "timer.h"-t már inklúdolja a "stopwatch.h". Itt viszont szükség lenne a Stopwatch-ra. class Timer typedef std::chrono::milliseconds milliseconds; public: Timer(Stopwatch *s) : _owner(s), _active(false) void start() ; void stop() ; private: void statemachine(); ; Stopwatch *_owner; bool _active; std::thread _thread; külön szál a Timer::stateMachine()-nek #include <thread> timer.h 15

Timer osztály void Timer::start() _active = true; _thread = std::thread(&timer::statemachine, this); void Timer::stop() _active = false; _thread.join(); void Timer::stateMachine() std::condition_variable _cond; std::mutex mu; while (_active) std::unique_lock<std::mutex> lock(mu); _cond.wait_for(lock, milliseconds(1000)); _owner->send(tick); külön szálon indul el a Timer állapotgépe feltételes változó és szemafor a várakozás megvalósításához #include <condition_variable> #include <mutex> egy másodpercig blokkolja a szálat timer.cpp 16

LcdNumber osztály class LcdNumber public: void display(int seconds) std::cout << extend((seconds % 3600) / 60) + ":" + extend((seconds % 3600) % 60) << std::endl; private: std::string extend(int n) const std::ostringstream os; os << n; return (n < 10? "0" : "") + os.str(); ; lcdnumber.h 17

ThreadSafeQueue osztálysablon template <typename Item> class ThreadSafeQueue public: ThreadSafeQueue() _active = false; void enqueue(const Item& e); void dequeue(item& e) ; void startqueue() _active = true; void stopqueue() _active = false; _cond.notify_all(); bool empty() const return _queue.empty(); private: std::queue<item> _queue; ; bool _active; std::mutex _mu; std::condition_variable _cond; a _cond objektummal blokkolt összes szálnak (azaz a dequeue()-t használó Stopwatch állapotgépének) engedélyezi a folytatást szemafor az enqueue() és dequeue() kölcsönös kizárásos módon való használatához #include <mutex> feltételes változó a dequeue() várakoztatásához #include <condition_variable> threadsafequeue.hpp 18

ThreadSafeQueue osztálysablon template <typename Item > void ThreadSafeQueue::enqueue(const Item& e) std::unique_lock<std::mutex> lock(_mu); _queue.push(e); _cond.notify_one(); template <typename Item > void ThreadSafeQueue::dequeue(Item& e) std::unique_lock<std::mutex> lock(_mu); while(empty() && _active) _cond.wait(lock); if(_active) e = _queue.front(); _queue.pop(); a _cond objektummal blokkolt szálnak (csak egy van) engedélyezi a folytatást várakozik, amíg a sor üres és aktív az enqueue() a dequeue()-val kölcsönösen kizárásos módon hívható a dequeue() a enqueue()-val kölcsönösen kizárásos módon hívható threadsafequeue.hpp 19

main() függvény int main() Stopwatch stopwatch; std::cout << "Choise option:" << std::endl; char o; do std::cin >> o; if(o == 's') stopwatch.send(click); while(o!= 'q'); stopwatch.send(quit); return 0; main.cpp 20

Stopwatch Qt-val fejlesztve Stopwatch : public QWidget Ablakszerű vezérlő objektum, amely más vezérlőket (időzítő, kijelző, nyomógomb) tartalmaz. Lezárása váltja ki a quit szignált. QLCDNumber display metódussal QPushButton típusú objektum váltja ki a click szignált #include <QApplication> QApplication #include "stopwatch.h" Többek között gondoskodik arról, hogy az int main(int argc, char *argv[]) események a megfelelő vezérlőkhöz jussanak el, hogy ott szignálokat váltsanak ki. QApplication app(argc,argv); Stopwatch *stopwatch = new Stopwatch; stopwatch ->show(); return app.exec(); main.cpp 21

Stopwatch osztály, mint QWidget #include <QWidget> class QTimer; class QLCDNumber; class QPushButton; enum State stopped, operate; class Stopwatch: public Qwidget Q_OBJECT public: Stopwatch(QWidget *parent=0); protected: ; void closeevent(qcloseevent * event) _timer->stop(); private: QTimer *_timer; QLCDNumber *_lcd; QTimer típusú objektum QPushButton *_button; váltja ki a tick szignált State _currentstate; int _seconds; QString Stopwatch::format(int n) const; QString Stopwatch::extend(int n) const; private slots: void onesecondpass(); // tick void buttonpressed(); // click a kilépéskor generált (quit) szignál eseménykezelője többi szignál eseménykezelője stopwatch.h 22

Stopwatch Qt eseménykezelői Stopwatch::oneSecondPass() switch (_currentstate) case operate: _lcd->display(format(++_seconds)); break; case stopped: break; Stopwatch::buttonPressed() switch (_currentstate) case operate: _currentstate = stopped; break; case stopped: _currentstate = operate; break; QString Stopwatch::format(int n) const return extend((n % 3600) / 60) + ":" + extend((n % 3600) % 60); QString Stopwatch::extend(int n) const return (n < 10? "0" : "") + QString::number(n); tick szignál eseménykezelője a korábbi natív C++ kód transition() metódusának része click szignál eseménykezelője a korábbi natív C++ kód transition() metódusának része a korábbi natív C++ kód LcdNumber osztályának metódusai stopwatch.cpp 23

Stopwatch Qt konstruktora Stopwatch::Stopwatch(QWidget *parent) : Qwidget(parent) setwindowtitle(tr("stopwatch")); resize(150, 60); itt kerül sor a grafikus vezérlőknek az ablakban való elrendezésére _timer = new QTimer; _lcd = new QLCDNumber; és egyéb tulajdonságainak megadására _button = new QPushButton("Start/Stop"); szignálok és kezelőik egymáshoz rendelése: tick (timeout()) ~ onesecondpass() click (clicked()) ~ buttonpressed() connect(_timer, SIGNAL(timeout()), this, SLOT(oneSecondPass())); connect(_button, SIGNAL(clicked()), this, SLOT(buttonPressed())); _currentstate = stopped; _seconds = 0; _lcd->display(_seconds); _timer->start(1000); a kód egy része automatikusan is generálható, ha vizuális tervezőt (QtDesigner) használunk stopwatch.cpp 24

Stopwatch.net alatt fejlesztve Stopwatch : Form Ablakszerű vezérlő objektum, amely más vezérlőket (időzítő, kijelző, nyomógomb) tartalmaz. Lezárása váltja ki a quit szignált. TextBox display metódussal Button típusú objektum váltja ki a click szignált Application static class Program Többek között gondoskodik arról, hogy az események a megfelelő vezérlőkhöz jussanak [STAThread] el, hogy ott szignálokat váltsanak ki. static void Main() Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Stopwatch()); program.cs 25

Stopwatch osztály, mint.net Form public partial class Stopwatch : Form enum State stopped, operate ; State _currentstate; DateTime _seconds = new DateTime(0); private System.Windows.Forms.Timer _timer; private System.Windows.Forms.Button _button; private System.Windows.Forms.TextBox _lcd; public Stopwatch() a kód egy része itt is generálható automatikusan vizuális tervezéssel private void timer_tick(object sender, EventArgs e) private void button_click(object sender, EventArgs e) private void MainForm_FormClosed(object sender,formclosedeventargs e) private void display() A display() itt sem az lcd kijelző metódusa, hanem a stopperé _lcd.text = string.format("0:1", seconds.minute.tostring().padleft(2, '0'), seconds.second.tostring().padleft(2, '0')); Stopwatch.cs 26

Stopwatch.net eseménykezelői private void timer_tick(object sender, EventArgs e) switch (currentstate) case State.operate: seconds = seconds.addseconds(1); display(); break; case State.stopped: break; private void button_click(object sender, EventArgs e) switch (currentstate) case State.operate: currentstate = State.stopped; break; case State.stopped: currentstate = State.operate; break; tick szignál eseménykezelője a transition() metódus része private void MainForm_FormClosed(object sender,formclosedeventargs e) quit szignál eseménykezelője _timer.stop(); a transition() metódus része stopwatch.cs click szignál eseménykezelője a transition() metódus része 27

Stopwatch osztály, mint.net Form public Stopwatch() this.components = new System.ComponentModel.Container(); this.button = new System.Windows.Forms.Button(); this.lcd = new System.Windows.Forms.TextBox(); this.timer = new System.Windows.Forms.Timer(this.components); this.text = "Stopwatch"; this.button.text = "Start/Stop"; this.lcd.text = "00:00"; this.timer.interval = 1000; this.controls.add(this.lcd); this.controls.add(this.button); this._timer.tick += new System.EventHandler(this.timer_Tick); this._button.click += new System.EventHandler(this.button_Click); this.formclosed += new System.Windows.Forms. FormClosedEventHandler(MainForm_FormClosed); _currentstate = State.stopped; display(); _timer.start(); vezérlők elrendezésének és egyéb tulajdonságainak megadása vizuális tervezéssel is végezhető, és a kód automatikusan generálható szignálok és kezelőik egymáshoz rendelése Stopwatch.cs 28

Stopwatch Java-ban Stopwatch extends JFrame Ablakszerű vezérlő objektum, amely más vezérlőket (időzítő, kijelző, nyomógomb) tartalmaz. Lezárása váltja ki a quit szignált. LCDNumber display metódussal JButton típusú objektum váltja ki a click szignált public class Stopwatch extends JFrame public static void main(string[] args) new Stopwatch(); Stopwatch.java 29

Stopwatch Java-ban public class Stopwatch extends JFrame enum State operate, stopped private State currentstate; private int seconds = 0; private final static int SECOND = 1000 /* milliseconds */; private Timer timer = new Timer(SECOND, null); private LcdNumber lcd = new LcdNumber("00:00"); private JButton button = new JButton("Start/Stop"); private JPanel buttonpanel = new JPanel(); public Stopwatch() void click() void tick() protected void finalize() throws Throwable public static void main(string[] args) new Stopwatch(); Stopwatch.java 30

Stopwatch Java eseménykezelője void click() switch (currentstate) click szignál eseménykezelője case operate : a transition() metódus része currentstate = State.stopped; break; case stopped : currentstate = State.operate; break; void tick() switch (currentstate) case operate : ++seconds; lcd.display(seconds); break; case stopped : break; protected void finalize() throws Throwable if (timer.isrunning()) timer.stop(); super.finalize(); Stopwatch.java tick szignál eseménykezelője a transition() metódus része quick szignál maga után vonja az időzítő leállítását 31

Stopwatch konstruktora Java-ban public Stopwatch() super("stopwatch"); setbounds(250, 250, 300, 200); setdefaultcloseoperation(exit_on_close); buttonpanel.setbackground(color.white); buttonpanel.add(button); add(lcd); add(buttonpanel, "South"); quit button.addactionlistener(new ActionListener() @Override public void actionperformed(actionevent e) click(); ); események és kezelésük egymáshoz rendelése timer.addactionlistener(new ActionListener() @Override public void actionperformed(actionevent e) tick(); ); currentstate = State.stopped; lcd.display(seconds); timer.start(); setvisible(true); Stopwatch.java 32

LCD kijelző Java-ban public class LcdNumber extends JLabel public LcdNumber(String text) super(text); sethorizontalalignment(jlabel.center); setopaque(true); setbackground(color.white); setforeground(color.blue); setfont(new Font(Font.DIALOG, Font.PLAIN, 40)); public void display(int seconds) settext(string.format("%02d:%02d", (seconds % 3600) / 60, // minutes (seconds % 3600) % 60)); // seconds a formázás az lcd kijelző része LcdNumber.java 33