Shall we dance? (Swing Dance)
Arkitektura MVC e prezantuar për herë të parë nga Trygve Reenskaug, zhvillues i Smalltalk, ndan aksesimin e të dhënave dhe logjikën e veprimit (business logic) nga mënyra se si këto i shfaqen përdoruesit. Tre elementët kryesore të saj janë:
Model — përfaqëson të dhënat dhe rregullat për të aksesuar dhe përditësuar këto të dhëna.
View — ofron përmbajtjen e modelit. Specifikon ekzakaktesisht se si duhet të prezantohen të dhënat. Në qoftë se të dhënat e modelit ndryshojnë, view duhet të update-oj prezantimin sipas nevojës. Kjo mund të arrihet duke përdorur një push model, në të cilin view regjistron veten tek modeli për të marr njoftime ne rast ndryshimesh, ose duke përdorur një pull model, në të cilin view është përgjegjës për të thirrur modelin kur i duhet të marrë të dhënat më të fundit.
Controller — përkthen ndërveprimin e përdoruesve me view-n në veprime të cilat do të kryhen nga modeli. Në një stand-alone GUI client, ndërveprimet e përdoruesve mund të jenë një klikim butoni ose selektim menu-je, kurse në një aplikacion web, këto shfaqen si kërkesa HTTP GET dhe POST. Në varësi të kontekstit, një kontroller mund të selektoj edhe një view të re- për shembull, një faqe web me rezultate për tiu prezantuar përdoruesit.
Modeli ka një ndërfaqe plotësisht funksionale të ndërtuar nga funksione publike që përdoren për realizimin e funksionalitetit. Disa funksione janë metoda pyetëse (query) që i japin mundësin “përdoruesit” të marr informacion mbi gjendjen e përkohshme të modelit. Funksione të tjerë janë ndryshues, pra ata mundësojne modifikimin e statusit. Gjithashtu një model duhet të jetë në gjendje të “regjistroj” pamje (views) dhe duhet të jetë në gjendje ti “lajmëroj” të gjitha ato kur gjendja e modelit ndryshon për shkak të ndonjërit funksion. Në Java një model përbërbëhet nga një ose më shumë klasa që trashëgojnë java.util.Observable. Kjo klasë bazë mundëson infrastrukturën regjistro/njofto, e nevojshme për një set me view. Një view i mundëson modelit komponentët për ndërfaqen grafike të përdoruesit (GUI). Vlerat e shfaqura në këtë ndërfaqe janë marrë nëpërmjet funksioneve pyetëse të modelit. Kur një përdorues manipulon një view të një modeli, kjo view njofton një kontrollor për ndryshimin e dëshiruar. Në Java një view ndërtohet me komponenet të AWT ose SWING. Gjithsesi ato duhet të implementojnë ndërfaqen java.util.Observer. Kur një përdorues ndërvepron me një view në MVC e cila është e lidhur me kontrollues, ky i fundit përditëson modelin sipas nevojës. Kontrolluesi mund të thërras metodat ndryshuese të modelit në mënyrë që të përditësoj statusin e saj. Më pas modeli do të njoftoj të gjitha ndërfaqet e regjistruar se është bërë një ndryshim, kështu ato do të përditësojnë pamjen për përdoruesin. Në Java kontrolluesit janë vëzhguesit (listeners) e strukturës së Java event.
GUI (elementet e GUI)
Ekzistojnë dy Java APIs për programimin grafik: AWT (Abstact Windowing Toolkit) dhe Swing (si kërcimi).
AWT API u prezantua me JDK1.0. (Pjesa më e madhe e komponentëve AWT janë bllokuar dhe duhet të zëvendësohen me komponentët më të rinj të Swing). Ndërsa Swing Api u prezantua si pjesë e Java Foundation Classes (JFC) pas daljes së JDK 1.1 dhe u integrua në JDK1.2.
Programimi GUI me AWT
AWT përmban 12 paketa (ndërsa Swing ka 18). Dy paketat më të përdorura janë – java.awt dhe java.awt.event
- Paketa java.awt pvrmban klasat grafike AWT kryesore si psh:
- Klasat e komponentëve GUI (si Button, Label, TextField)
- Klasat e përmbajtjeve (Container) (si Frame, Panel, Dialog dhe ScrollPane)
- Menaxherët e layout (si FlowLayout, BorderLayout dhe GridLayout)
- Klasat e ndryshimeve grafike (si Graphics, Color, Font)
- Paketa java.awt.event përdoret për menaxhimin e ngjarjeve (event handling)
- Klasat e ngjarjeve(si ActionEvent, MouseEvent, KeyEvent dhe WindowEvent)
- Ndërfaqet për vëzhguesit e ngjarjeve (si ActionListener, MouseListener, KeyListener dhe WindowListener)
- Klasat për adaptimin e vëzhguesve të ngjarjeve (si MouseAdapter, KeyAdapter dhe WindowAdapter)
Ka dy tipe elementësh GUI:
Komponentët janë entitete elementare GUI(Button, Label dhe TextField)
Përmbajtësit (si Frame, Panel dhe Applet) përdoren për të mbajtur komponentët në një formë specifike si për shembull flow ose grid. Një container mund gjithashtu të përmbaj sub-containers.
AWT Container Classes
Çdo program GUI ka një top-level container. Kryesisht përdoren Frame, Dialog dhe Applet.
- Frame ofron “dritaren kryesore” për applikimin GUI, që përmban një title bar (ikona, titulli, butonat për minimizim, maksimizim dhe mbyllje të faqes) një menu opsionale, dhe zonën për shfaqen e përmbajtjes.
- Dialog është një dritare pop-up që shërben për të ndërvepruar me përdoruesin. Gjithashtu ka një title-bar (me ikon, titull dhe butonin e mbylljes së dritares) dhe zonën për shfaqjen e përmbajtjes.
- Applet është një program Java që ekzekutohet në browser.
Container sekondar janë Panel dhe ScrollPane
- Panel vendoset në një container të nivelit më të latrë, në mënyrë që të formoj një set me komponent të ndërlidhur GUI në form gride ose flow.
- ScrollPane ofron lëvizje automatike horizontale dhe/ose vertikale për një komponent të vetëm.
AWT Event-Handling
Java adapton të ashtëquajturin Event-Driven programming model, ku një kod që menaxhon ngjarjet ekzekutohet në përgjigje të inputit të dhënë nga përdoruesi. Kjo është e ndryshme nga modeli proçedurial, ku kodi ekzekutohet në mënyrë sekuenciale.
Tre objekte përfshihen në menaxhimin e ngjarjeve: source, listener(s), event object.
Source object si psh Button dhe TextField ndërveprojnë me përdoruesit dhe kur një prej këtyre objekteve përdoret krijohet një event object. Ky objekt i dërgohet si mesazh të gjithë objekteve të regjistruar listener dhe një metod listener e përshtatshme për menaxhimin e ngjarjeve thërritet mbrapsht për të dhënë përgjigje
Layout Managers and Panel
Nje container mund të organizoj komponentët e tij duke përdorur loayout manager. Layout manager ofron një nivel abstraksioni për të përshtatur ndërfaqen e përdoruesit me dritaret e të gjitha sistemeve, në mënyrë që layout të jetë i pavarur nga platforma. AWT ofron menaxherët e tipeve FlowLayout, GridLayout, BorderLayout, GridBagLayout, BoxLayout, CardLayout dhe të tjera. (Swing ofron edhe menaxher të tjerë)
Përdorimi i Swing API
Në ndryshim nga klasat e AWT, komponentët e klasave Swing fillojn me prefiksin “J”, psh, JButton, JTextField, JLabel, JPanel, JFrame ose JApplet.
Rregull: Mos përdorni se bashku komponentët AWT (me pesh më të rënd) me komponentët Swing (me pesh më të lehtë), sepse komponetët me pesh të rënd do të vendosen gjithmon mbi komponetët me peshë të lehtë.
Container të nivelit të lartë dhe sekondar në Swing
Ashtu si edhe aplikimet AWT edhe ne aplikimet Swing duhet një container i nivelit të lartë. Ka tre container të këtij niveli:
- JFrame
- JDialog
- JApplet
Ndërsa JComponents ndryshe nga aplikimet AWT nuk i shtohen direkt container-ave të nivelit të lartë sepse ato janë komponentë me pesh të lehtë. JComponents shtohen në të ashtëquajturin content-pane të containerit të nivelit të lartë. Content-pane është në fakt një java.awt.Container që mund të përdoret për të grupuar komponentët.
public class Test extends JFrame { //konstruktori public Test(){ Container c = this.getContentPane(); c.setLayout(new FlowLayout); c.add(new JLabel("Në content-pane të këtij JFame mund të shtojmë komponent")); c.add(new JButton("Button")); } }
Përsa i përket event-handeling Swing përdor kryesisht klasat e AWT në paketën java.awt.event pavarësisht se ekzistojnë edhe disa klasa të reja në javax.swing.event.
Shëmbulli i mëposhtëm përfshin disa nga komponentët kryesor në ndërtimin e një aplikimi GUI.
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class LlogaritSipDrejtkendeshit extends JFrame { private JLabel gjatesiaL, gjeresiaL, sipL; private JTextField gjatesiaT, gjeresiaT, sipT; private JButton butoniLlogarit, butoniMbyll; private static final int GJATESIA = 700; private static final int GJERESIA = 200; private LlogaritHandler llogaritHandler; private MbyllHandler mbyllHandler; public LlogaritSipDrejtkendeshit(){ gjatesiaL = new JLabel("Gjatesia e drejtkendeshit"); gjeresiaL = new JLabel("Gjeresia e drejtkendeshit"); sipL = new JLabel("Siperfaqja eshte: ", SwingConstants.RIGHT); gjatesiaT = new JTextField(12); gjeresiaT = new JTextField(12); sipT = new JTextField(12); //Ky seksin specifikon handlers dhe shton ActionListener butoniLlogarit = new JButton("Sa eshte siperfaqja?"); llogaritHandler = new LlogaritHandler(); butoniLlogarit.addActionListener(llogaritHandler); butoniMbyll = new JButton("Mbyll"); mbyllHandler = new MbyllHandler(); butoniMbyll.addActionListener(mbyllHandler); setTitle("Llogaritesi i Siperfaqes se Drejtkendeshit"); Container pane = getContentPane(); pane.setLayout(new GridLayout(4,2)); //Ne content-pane do te vendosen komponentet sips rradhes qe ato do te shfaqen ne grid pane.add(gjatesiaL); pane.add(gjatesiaT); pane.add(gjeresiaL); pane.add(gjeresiaT); pane.add(sipL); pane.add(sipT); pane.add(butoniLlogarit); pane.add(butoniMbyll); setSize(GJATESIA, GJERESIA); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } private class LlogaritHandler implements ActionListener { @Override public void actionPerformed(ActionEvent e) { double gjatesia, gjeresia, sip; gjatesia = Double.parseDouble(gjatesiaT.getText()); gjeresia = Double.parseDouble(gjeresiaT.getText()); sip = gjatesia*gjeresia; sipT.setText(""+sip); } } public class MbyllHandler implements ActionListener { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } } public static void main(String[] args) { LlogaritSipDrejtkendeshit drejtkendesh = new LlogaritSipDrejtkendeshit(); } }
Ndërkohë JPanel mund të përdoret edhe për të vizatuar. Klasat e JPanel mund zgjerohen duke bërë të mundur mbishkrimin e metodave të vizatimit.
public class Vizatim extends JPanel { @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.RED); g2d.fillOval(0, 0, 30, 30); g2d.drawOval(0, 50, 30, 30); g2d.fillRect(50, 0, 30, 30); g2d.drawRect(50, 50, 30, 30); g2d.draw(new Ellipse2D.Double(0, 100, 30, 30)); } public static void main(String[] args) { JFrame frame = new JFrame("Mini Tennis"); frame.add(new Vizatim()); frame.setSize(300, 300); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }