Trükkimine Lühike näide Lihtsaks trükkimiseks tuleb luua liidest Printable realiseeriv klass, kus meetodis print öeldakse, kuidas tuleb trükkida. Printerisse joonistamine käib samuti graafilise konteksti Graphics abil nagu ekraanile või mällugi joonistamine. Meetodi print parameetrina tuleva PageFormat'i abil saab teada, kui suure trükitava lehega tegemist on ning millisele osale lehest on võimalik joonistada. Enamasti on lehe serva määratud vaikimisi selline osa, kuhu joonistada ei saa. Joonistuskõlbuliku osa alguse x- koordinaadi annab getImageableX(). Samuti saab PageFormat'i käest küsida y-koordinaati ning joonistatava ala kõrgust ja laiust. Siin näites transleeritakse graafilise konteksti nullkoht joonistatava ala algusesse. Kolmanda parameetrina tulev leheküljenumber näitab, millist lehekülge soovitakse trükkida. Isendil on täiesti võimalik mitmele leheküljele trükkida. Lihtsalt tuleb meetodis print igale leheküljenumbrile vastavalt reageerida. Kui vastava numbriga lehekülge ei soovita trükkida, peab meetod tagastama väärtuse Printable.NO_SUCH_PAGE, muul juhul Printable.PAGE_EXISTS. Trükkimise käivitamiseks luuakse isend tüübist PrinterJob, määrakse, milline Printable oskusega isend trükitöö ära teeb ning siis palutakse trükkima hakata. import java.awt.print.*; import java.awt.*; public class Trykk1{ public static void main(String argumendid[]) throws PrinterException{ PrinterJob pj=PrinterJob.getPrinterJob(); pj.setPrintable(new Trykitoo1()); pj.print(); } } class Trykitoo1 implements Printable{ public int print(Graphics g, PageFormat pf, int lk) throws PrinterException{ if(lk>0) return Printable.NO_SUCH_PAGE; g.translate((int)pf.getImageableX(), (int)pf.getImageableY()); g.drawOval(10, 10, 200, 200); return Printable.PAGE_EXISTS; } } Komponendi trükkimine Kuna nii ekraanile kui printerisse joonistab klassi Graphics järglane, siis saab joonistamisel kasutada sama meetodit. Siin näites joonistatakse mõlemasse meetodi paint abil. Programm loob ekraanile nupu ning omaloodud komponendi Kiri2. Nupule vajutades trükitakse Kiri2 printerisse. Trükkimine on korraldatud nii, et vajutamise peale trükitakse Kiri2 tüüpi isendit 2 lehekülge, kummalegi lehele joonistatakse tema kujutis ning lehe alla kirjutatakse lehekülje number. Klassi PrinterJob meetod printDialog kutsub välja dialoogiakna, kust kasutaja saab määrata printerit ning väljastatavate lehekülgede numbreid ja koopiate arvu. import java.awt.*; import java.awt.event.*; import java.awt.print.*; class Kiri2 extends Canvas implements Printable { public void paint(Graphics g) { g.setColor(Color.black); int W = (int)getSize().getWidth(); int H = (int)getSize().getHeight(); g.drawRect(1, 1, W-3, H-3); g.drawString("Tere!", W/2, H/2); } public int print(Graphics g, PageFormat pf, int lk) throws PrinterException { if (lk >= 2) { return Printable.NO_SUCH_PAGE; } g.translate((int)pf.getImageableX(), (int)pf.getImageableY()); g.setColor(Color.black); paint(g); g.drawString("lk nr. "+(lk+1), 100, (int)pf.getImageableHeight()-50); return Printable.PAGE_EXISTS; } } public class Trykk2 extends Panel implements ActionListener { Kiri2 kiri=new Kiri2(); Button b = new Button("Tryki"); public Trykk2() { b.addActionListener(this); add(b); kiri.setSize(100, 50); add(kiri); } public void actionPerformed(ActionEvent e) { PrinterJob pj = PrinterJob.getPrinterJob(); pj.setPrintable(kiri); try { if(pj.printDialog()) pj.print(); } catch (Exception PrintException) { } } public static void main(String s[]) { Frame f = new Frame("Trykkimisraam"); f.add("Center", new Trykk2()); f.pack(); f.setSize(400,300); f.show(); } } Trükitava ala suuruse muutmine Trükitava ala suurust lehel saab ka ise muuta. Sel juhul tuleb PageFormat'i käest küsida Paper tüüpi isend, talle määrata soovitud suurusega joonistusala. Siis määrata PageFormat'ile vastav paber ning paluda PrinterJob'il vastava PageFormat'i järgi trükkida. Siin näites luban trükkida lehel servast serva. import java.awt.print.*; import java.awt.*; public class Trykk3{ public static void main(String argumendid[]) throws PrinterException{ PrinterJob pj=PrinterJob.getPrinterJob(); PageFormat pf=pj.defaultPage(); Paper p=pf.getPaper(); p.setImageableArea(0, 0, p.getWidth(), p.getHeight()); pf.setPaper(p); pj.setPrintable(new Trykitoo3(), pf); pj.print(); } } class Trykitoo3 implements Printable{ public int print(Graphics g, PageFormat pf, int lk)throws PrinterException{ if(lk>0) return Printable.NO_SUCH_PAGE; g.drawOval(0, 0, 300, 200); return Printable.PAGE_EXISTS; } } Trükitava ala suurust saab lasta ka kasutajal dialoogiakna abil määrata. Sellise akna manab ekraanile pageDialog. public class Trykk3a{ public static void main(String argumendid[]) throws PrinterException{ PrinterJob pj=PrinterJob.getPrinterJob(); pj.setPrintable(new Trykitoo3a(), pj.pageDialog(pj.defaultPage())); pj.print(); } } Lisavõimalused Printable liidese abil saab trükkida ühesuguse suurusega lehekülgi. Kui peaks aga vaja olema ühte trükitavasse dokumenti kokku panna mitmesuguseid (näiteks püsti- ning põikiformaadis) lehti, siis tuleb algul panna kirjutatavatest lehtedest kokku Book ning seda trükkima hakata. Muusikafailide mängimine Algusest peale ning ka praegu kõige kindamalt suudavad java programmid mängida au lihtsamas formaadis faile. Versioonist 1.2 on juurde liidetud ka muude (wav, midi) helifailitüüpide mängimise võimalus. Muusika mängimiseks tuleb luua AudioClip. Selle meetoditega play, loop ning stop saab panna klipi mängima ning mängimine katkestada. Loop tähendab, et klippi mängitakse pidevalt, s.t. pärast lõpetamist hakatakse mängimisega uuesti algusest peale. Keerulisemaid helisünteesi ning muid muusika juurde kuuluvaid valdkondi java keele juures alles luuakse (1999). import java.applet.*; public class Muusika1 extends Applet{ public void start(){ AudioClip lugu=getAudioClip(getCodeBase(), "spacemusic.au"); lugu.play(); } } Järgneva näite puhul hakatakse korduvalt mängima lehele tulles ning lehelt lahkudes lõpetatakse mängimine. import java.applet.*; public class Muusika2 extends Applet{ AudioClip lugu; public void init(){ lugu=getAudioClip(getCodeBase(), "spacemusic.au"); } public void start(){ lugu.loop(); } public void stop(){ lugu.stop(); } } Iseseisva programmi puhul saab klipi kätte klassi Applet staatilise meetodi newAudioClip abil, meetodi parameetriks on helifaili URL. import java.applet.*; import java.net.URL; public class Muusika3a{ public static void main(String argumendid[]) throws Exception{ AudioClip lugu=Applet.newAudioClip( new URL("http://minitorn.tpu.ee/~jaagup/kool/java/"+ "abiinfo/tutorial/sound/example-1dot2/bottle-open.wav") ); lugu.play(); Thread.sleep(5000); } } Kui soovitakse mängida lugu samast masinast, siis tuleb ka see kohalik aadress enne URLiks muuta. import java.applet.*; import java.net.URL; public class Muusika3{ public static void main(String argumendid[]) throws Exception{ AudioClip lugu=Applet.newAudioClip( new File("spacemusic.au").toURL() ); lugu.play(); Thread.sleep(5000); } } MIDI Lisaks varemvalminud lugude esitamisele saab ka ise meloodiaid kokku panna. MIDI abil saame määrata, millist nooti millal mängida. Salvestatud pillide helinäidete järgi luuakse selle tulemusena meie poolt küsitud hääl. Kui soovitakse samaaegselt kuulda mitme pilli meloodiat, tuleb need paigutada eri kanalitele. Iga kanal võib korraga teha ühe pilli häält ning harilikult on kanaleid kokku kuni 16. Kanalist väljuvat heli saab kontrollida sinna saadetavate käskudega. Enamkasutatavad on noteOn ja noteOff. Esimene neist palub nooti mängima hakata, teine mängimise lõpetada. Meetod noteOn vajab kahte parameetrit: heli kõrgust ja valjust, noodi kõlamise lõpetamiseks piisab noodi numbrist. MIDI standardi järgi on igal pooltoonil oma number vahemikus 0-127. Esimese oktaavi C väärtuseks on näiteks 60, sealt saab siis vastavalt poole tooni kaupa üles ja allapoole arvutada. Valjust tähistab samuti number samast vahemikust. MIDI vahendid asuvad paketis javax.sound, mis kuulub standardvahendite hulka alates JDK versioonist 1.3. Operatsiooni muusikavahendite poole pöördumiseks saab kasutada klassi MidiSystem. Järgnevas näites küsitakse selle klassi kaudu helitekitamise seade ehk süntesaator ning avatakse. Viimase käest küsitakse tema külge kuuluv kanalite massiiv ning sealt omakorda kanal nr. 0. Järgnevalt palun vastaval kanalil mängida A nooti (noot nr. 69) valjusega 65. Ootan sekundi ning siis lasen noodi kõlamise lõpetada. System.exit viimase käsuna on tarvilik, kuna MIDI vahendite tarvitamisega virtuaalmasina poolt loodud lõim ei oska nootide lõpuga oma tööd lõpetada ning programm jääks viimasele reale rippuma. Analoogiline olukord on ka graafikakomponentide juures, kus programmi töö lõpetamiseks tuleb kirjutada System.exit(0). import javax.sound.midi.*; public class Noot{ public static void main(String argumendid[]) throws Exception{ Synthesizer synthesizer=MidiSystem.getSynthesizer(); synthesizer.open(); MidiChannel kanal=synthesizer.getChannels()[0]; //kanal 0; int korgus=69; //A int valjus=65; //keskmine kanal.noteOn(korgus, valjus); Thread.sleep(1000); kanal.noteOff(korgus); System.exit(0); } } Kromaatilist heliredelit võib mängida tsükli abil: for(int i=40; i<120; i++){ kanal.noteOn(i, 60); Thread.sleep(200); kanal.noteOff(i); } Kui soovida, et samal kanalil mängiks korraga mitu nooti, tuleb lihtsalt ükshaaval määrata, millised helikõrgused peavad kõlama. Kõikide mängimise saab korraga lõpetada käsuga allNotesOff(). Kuigi MIDI puhul öeldakse helikõrgus numbriga ette, on ka siin võimalik toonil ujuda lasta. Seda saab käsuga setPitchBend, andes ette numbri, palju kõrgust muuta. Vaikimisi väärtuseks on 8192, sellisel juhul vastab noodi number tema helikõrgusele. Iga number sellest ülespoole viib helikõrgust kõrgemale, allapoole aga madalamaks. Vaikiva kokkuleppe järgi tähistab number 0 tooni võrra madalamat ning 16363 tooni jagu kõrgemat heli, kuid see kõikumise piirkond võib ka erineda. Järgnevas näites peaks tooni ülalt alla ujumine kuulda olema. kanal.noteOn(60, 70); kanal.noteOn(64, 70); for(int korgus=16383; korgus>0; korgus-=500){ Thread.sleep(200); kanal.setPitchBend(korgus); } kanal.allNotesOff(); Kanalil mängivat instrumenti saab muuta käsuga programChange, andes parameetritena ette uue pilli helipanga ning panga sees sellele pillile vastava programmijupi järjenumbri. Süntesaatorile kättesaadavad pillid saab küsida getDefaultSoundbank().getInstruments() abil. All näites paiknevad trükitakse tsüklis järgemööda välja pillide nimed ning mängitakse igal pillil noot. Instrument[] pillid=synthesizer.getDefaultSoundbank(). getInstruments(); MidiChannel kanal=synthesizer.getChannels()[0]; for(int i=0; i\n"+ "

Tervist!

\n"+ "" ); } } QueryString HttpServletRequesti meetod getQueryString annab URLi küsimärgile järgneva osa. Näiteks http://www.ee/kass.html?nurr puhul on QueryStringiks nurr. Juhul kui servletti välja kutsuval lehel on vorm ning väljad, siis laotakse väljade nimed ning nende väärtused üksteise otsa ja paigutatakse QueryStringi. Eri väljade andmed eraldatakse teineteisest & märgiga, välja nimi ning väärtus = märgiga. Alljärgneva näite puhul võib see välja näha näiteks: eesnimi=Peeter&perenimi=Tamm. Servlet saab vajaduse korral saabunud sõne jälle osadeks jaotada. import javax.servlet.*; import javax.servlet.http.*; import java.util.StringTokenizer; import java.io.*; public class ServletGet1 extends HttpServlet{ public void doGet(HttpServletRequest kysimus, HttpServletResponse vastus) throws IOException, ServletException{ vastus.setContentType("text/html"); PrintWriter valja=new PrintWriter(vastus.getWriter()); valja.println( "Edastati info: "+kysimus.getQueryString()+"
\n"+ "Ühendus tuli masinast "+kysimus.getRemoteHost()+"
\n"+ "Selle masina number on "+kysimus.getRemoteAddr()+"

\n" ); StringTokenizer stk=new StringTokenizer(kysimus.getQueryString(), "&"); while(stk.hasMoreTokens()){ valja.println(stk.nextToken()+"
\n"); } } }

Eesnimi:
Perekonnanimi:
Post Kui andmeid saadetakse post-protokolli abil, siis jõuavad nad kohale eraldi voona. HttpServletRequestilt saab küsida selle voo ning sealt andmeid lugema hakata. Samas on siia loodud ka automaatsed vahendid parameetrite väärtuste leidmiseks, et programmeerija ei peaks oma pead vaevama pika sõne osadeks jagamise, kodeeritud tähtede lahtiharutamise ning vajalike parameetrite väärtuste üles leidmisega. Kui meetodi getParameter parameetriks anda välja nimi, siis tulemusena väljastatakse selle välja väärtus. import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServletPost1 extends HttpServlet{ public void doPost(HttpServletRequest kysimus, HttpServletResponse vastus)throws IOException, ServletException{ String eesnimi=kysimus.getParameter("eesnimi"); String perenimi=kysimus.getParameter("perenimi"); vastus.setContentType("text/plain"); PrintWriter valja=vastus.getWriter(); valja.println(eesnimi+" "+perenimi); } }
Eesnimi:
Perekonnanimi:
Andmete loetelu Nii väljade väärtused kui väljakutsujat iseloomustavad suurused on võimalik kätte saada üheskoos. HtteServletRequesti getParameterNames() annab väljade nimed Enumerationi ehk jadana. Samuti annab getHeaderNames() väljakutsuja tunnuste loetelu. Nime järgi saab küsida tunnuse väärtuse. Kui soovida, et servlet oskaks nii get- kui post-protokollis andmeid saata, siis võib ühte servletti kirjutada mõlemad meetodid. Kui soovitakse, et nad käituksid sarnaselt, siis võib üks meetod lihtsalt teise välja kutsuda. import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Enumeration; public class ServletPost2 extends HttpServlet{ public void doPost(HttpServletRequest kysimus, HttpServletResponse vastus)throws IOException, ServletException{ vastus.setContentType("text/plain"); PrintWriter valja=vastus.getWriter(); Enumeration parameetrid=kysimus.getParameterNames(); while(parameetrid.hasMoreElements()){ String parameetriNimi=(String)parameetrid.nextElement(); valja.println(parameetriNimi+" = "+kysimus.getParameter(parameetriNimi)+"\n"); } valja.println(); Enumeration teated=kysimus.getHeaderNames(); while(teated.hasMoreElements()){ String teateNimi=(String)teated.nextElement(); valja.println(teateNimi+" - "+kysimus.getHeader(teateNimi)+"\n"); } } public void doGet(HttpServletRequest kysimus, HttpServletResponse vastus)throws IOException, ServletException{ doPost(kysimus, vastus); } }
kasutajanimi:
parool:
ASP, PHP, JSP CGI või servlettide kirjutamisel tuleb paratamatult kokku puutuda märkimisväärse hulga programmikoodiga. Mõnele tundub igasugune kodeerimine hirmuäratav, teisalt on ka tülikas, kui peab pikemaid tekste väljundisse kirjutama selleks, et saaks seal sees üksikuid väärtusi muuta. Kliendipoolsete arvutuste puhul saab selliseks tegevuseks kasutada Javaskripti, serveripoolsete lisanduste jaoks mõeldi aga välja mitmesugused *SP-d. Seal saab HTML teksti sisse vastavate märkide (kas <% %> või siis ) vahele kirjutada käsud, mida programm tegema peaks. Eeliseks kliendipoolse skripti ees on, et saab kasutada ka serveris paiknevaid andmeid, puuduseks, et ei saa kasutaja tegevusele vahetult reageerida, kogu teave jõuab temani alles uue lehe laadimise järel. ASP töötab peamiselt MS Windowsi keskkonna all ja seal sees levinumaks programmeerimiskeeleks on Visual Basicust loodud VBScript. JSP käsud kirjutatakse Java keeles, andmeid talletatakse ja töödeldakse enamjaolt ubade (bean) abil. Kasutajale järjestikuseid näidatavaid lehti nimetatakse sessioonideks. Nende abil hoitakse näiteks meeles sisestatud kasutajanime ja parooli, et neid ei tuleks igale lehele sisenedes uuesti sisestada.