Sunteți pe pagina 1din 57

Introducere in Java

Autor: Radu Candea


Laborator 1

Limbajul de programare Java


Java este un limbaj de programare de nivel înalt, dezvoltat de JavaSoft, companie în cadrul firmei
Sun Microsystems. Dintre caracteristicile principale ale limbajului amintim:
• simplitate, elimină supraîncarcarea operatorilor, mostenirea multipla si toate "facilitatile" ce pot
provoca scrierea unui cod confuz.
• robustete, elimina sursele frecvente de erori ce apar in programare prin eliminarea pointerilor,
administrarea automata a memoriei si eliminarea fisurilor de memorie printr-o procedura de
colectare a 'gunoiului' care ruleaza în fundal. Un program Java care a trecut de compilare are
proprietatea ca la executia sa nu "crapa sistemul".
• complet orientat pe obiecte - elimina complet stilul de programare procedural
• usurinta in ceea ce priveste programarea in retea
• securitate, este cel mai sigur limbaj de programare disponibil în acest moment, asigurând
mecanisme stricte de securitate a programelor concretizate prin: verificarea dinamica a codului
pentru detectarea secventelor periculoase, impunerea unor reguli stricte pentru rularea programelor
lansate pe calculatoare aflate la distanta, etc
• este neutru din punct de vedere arhitectural
• portabililtate, cu alte cuvinte Java este un limbaj independent de platforma de lucru, aceeasi
aplicatie ruland, fara nici o modificare, pe sisteme diferite cum ar fi Windows, UNIX sau
Macintosh, lucru care aduce economii substantiale firmelor care dezvolta aplicatii pentru Internet.
• compilat si interpretat
• asigura o performanta ridicata a codului de octeti
• permite programarea cu fire de executie (multitheaded)
• dinamicitate
• este modelat dupa C si C++, trecerea de la C, C++ la Java facându-se foarte usor.
• permite creearea unor documente Web îmbunatatite cu animatie si multimedia.

In functie de modul de executie al programelor, limbajele de programare se împart în doua


categorii :
• interpretate : instructiunile sunt citite linie cu linie de un program numit interpretor si traduse în
instructiuni masina; avantaj : simplitate; dezavantaje : viteza de executie redusa => Java
• compilate : codul sursa al programelor este transformat de compilator într-un cod ce poate fi
executat direct de procesor; avantaj : executie rapida; dezavantaj : lipsa portabilitatii, codul
compilat într-un format de nivel scazut nu poate fi rulat decât pe platforma pe care a fost compilat.
=> C++

Cod sursa Java -> (compilare) -> Cod de octeti -> (interpretare)

Toate aplicatiile Java contin o clasa principala(primara) în care trebuie sa se gaseasca metoda
main. Clasele aplicatiei se pot gasi fie într-un singur fisier, fie în mai multe.
Salvarea fisierelor sursa se va face în fisiere cu extensia .java. Fiserul care contine codul sursa
al clasei primare trebuie sa aiba acelasi nume cu clasa primara a aplicatiei (clasa care contine metoda
main)
Obs: Java face distinctie între literele mari si mici.

Pentru compilarea aplicatiei se foloseste compilatorul Java, javac. Apelul compilatorului se


face pentru fisierul ce contine clasa principala a aplicatiei. Compilatorul creeaza câte un fisier separat
pentru fiecare clasa a programului; acestea au extensia .class si sunt plasate în acelasi director cu fisierele
sursa.
javac NumeProgr.java va rezulta NumeProgr.class

Pentru rularea aplicatiei se va folosi interpretorul java, apelat pentru unitatea de compilare
corespunzatoare clasei principale, fiind însa omisa extensia .class asociata acesteia.

java NumeProgr

Java Developer Kit (JDK) este însoţit de documentaţie pentru toate bibliotecile de clase Java,
documentaţie care conţine descrierea tuturor variabilelor de instanţă, a metodelor, constructorilor,
interfeţelor şi aşa mai departe. Studierea bibliotecilor de clase Java, a metodelor şi variabilelor de instanţă,
este o metodă foarte bună de a cunoaşte posibilităţile Java, precum şi un bun punct de plecare pentru
creaţiile proprii.
Iată pachetele de clase care fac parte din bibliotecile de clase Java:
• java.lang: Clase care se aplică limbajului însuşi, şi include clasa Object, clasa String şi clasa
System. Tot aici se află şi clasele speciale pentru tipurile primitive de date (Integer, Character, Float
etc.).
• java.util: Clase utilitare, cum ar fi Date, împreună cu colecţii simple de clase, cum ar fi Vector şi
Hashtable.
• java.io: Clase pentru operaţiile de intrare/ieşire pentru scrierea şi citirea fluxurilor (cum ar fi
intrarea şi ieşirea standard) şi pentru tratarea fişierelor.
• java.net: Clase pentru lucrul în reţea, inclusiv Socket şi URL (o clasă pentru reprezentarea
referinţelor spre documente din World Wide Web).
• java.awt: (Abstract Window Toolkit): clase care implementează o interfaţă grafică cu utilizatorul,
inclusiv clase pentru Window, Menu, Button, Font, CheckBox, etc. Tot acest pachet include clase
pentru prelucrarea imaginilor (pachetul java.awt.Image).
• java.applet: Clase pentru implementarea applet-urilor Java, inclusiv clasa Applet.

PROGRAM 1
class LinieComanda
{
public static void main(String[] args)
{
/*System.out.println("Urmeaza cele "+args.length+" elemente date in linia de comanda");
for (int i=0;i<args.length;i++)
System.out.println(args[i]);*/
System.out.print("Bine ai venit in universul Java ");
for (int i=0;i<args.length;i++)
System.out.print(args[i]+" ");
}
}

PROGRAM 2
// Pachete folosite
//import java.io.*;
// Sf Pachete folosite

class Tablouri // contine main


{
// exista un constructor implicit
// Main
public static void main(String[]arg)
{
// Declaratii de variaunidle
int[] uni = new int[10];
int [][] bi=new int[10][10];

int i,j;
// Sf Declaratii de variabile

for (i=0; i<uni.length; i++)


{
uni[i]=i;
System.out.print(uni[i]+" ");
}
System.out.println();

for (i=0; i<bi.length; i++)


for (j=0; j<bi.length; j++)
{
bi[i][j]=10*i+j;
System.out.print(bi[i][j]+" ");
}
System.out.println();
}
}

PROGRAM3
class Matrice
{
private final int SIZE=5;
private int[][] a;

public Matrice()
{
a=new int[SIZE][SIZE];
for (int i=0;i<SIZE;i++)
for (int j=0;j<SIZE;j++)
{
int aux=(int)(java.lang.Math.random()*10);
a[i][j]=aux;
}
}

public void afisare()


{
int s=0;
for(int i=0;i<SIZE;i++)
{
System.out.println();
for(int j=0;j<SIZE;j++)
System.out.print(" "+a[i][j]);
}
System.out.println("\n");
}

public void suma_elem()


{
int s=0;
for(int i=0;i<SIZE;i++)
for(int j=0;j<SIZE;j++)
s+=a[i][j];
System.out.println("Suma tuturor elementelor matricii este: "+s);
}

public void suma_diag_princ()


{
int s=0;
for(int i=0;i<SIZE;i++) s+=a[i][i];
System.out.println("Suma elementelor de pe diagonala principala este: "+s);
}
public void suma_diag_sec()
{
int s=0;
for(int i=SIZE-1;i>=0;i--) s+=a[i][SIZE-i-1];
System.out.println("Suma elementelor de pe diagonala secundara este: "+s);
}

public void suma_sus()


{
int s=0;
for(int i=0;i<SIZE;i++)
for(int j=i+1;j<SIZE;j++)
s+=a[i][j];
System.out.println("Suma elementelor de deasupra diagonalei principale este: "+s);
}

public void suma_jos()


{
int s=0;
for(int i=1;i<SIZE;i++)
for(int j=0;j<=i-1;j++)
s+=a[i][j];
System.out.println("Suma elementelor de sub diagonala principala este: "+s);
}

public static void main(String[] args)


{
Matrice a = new Matrice();
a.afisare();
a.suma_elem();
a.suma_diag_princ();
a.suma_diag_sec();
a.suma_sus();
a.suma_jos();
}

}
PROGRAM 4

import java.util.*;

class Oclasa
{
private Vector vector;
private char[] sir={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','z','y'};

public Oclasa()
{
vector=new Vector();
umple();
afiseaza();
}

public void umple()


{
for (int i=0;i<sir.length;i++)
vector.add(sir[i]);
// vector.add(new Clasa(sir[i]));
vector.add(5,"cuvant nou");
}

public void afiseaza()


{
int k=0;
while (k<vector.size())
{
// System.out.print(" "+vector.elementAt(k).getVal());// nu merge
//un obiect de tip Vector contine obiecte de tip Object
//cu toate ca am introdus Stringuri in Vector metoda getVal() nu este cunoscuta
System.out.print(" "+vector.elementAt(k));
k++;
}
}

public static void main(String[] args)


{
new Oclasa();
}
}

//-------------------------------------------------------------

class Clasa
{
// Date-membru = Atribute
private char a;
// Sf Date-Membru
// Constructori
public Clasa(char a)
{
this.a=a;
}
// Sf Constructori
// Metode
public char getVal()
{
return a;
}
// Sf Metode
}
Laborator 2
Appleturi
Un applet reprezintă un program Java ce gestionează o suprafaţă de afişare container) ce poate fi
inclusă într-o pagină Web.
Pachete necesare a fi importate: java.applet
Clasa principală extinde Applet
Un applet nu poate fi executat independent. El este executat de către browser-ul în care a fost
încărcată pagina Web ce conţine appletul sau de către programe specializate cum ar fi appletviewer un
utilitar inclus în distribuţia J2SDK.
Exemple de browsere
• Internet Explorer
• Netscape
• Mozilla
• Opera
import java.awt.* ;
import java.applet.* ;
public class FirstApplet extends Applet {
Image img;
public void init() {
img = getImage(getCodeBase(), "taz.gif");
}
public void paint (Graphics g) {
g.drawImage(img, 0, 0, this);
g.drawOval(100,0,150,50);
g.drawString("Hello!", 110, 25);
g.fillOval(100,0,150,50);
}
}

Pentru rularea appletului se creează un fişier HTML de tipul


<html>
<head>
<title>Primul applet Java</title>
</head>
<body>
<applet code=FirstApplet.class width=400 height=400> </applet>
</body>
</html>

Vizualizarea appletului se face prin comanda appletviewer nume.html sau folosind un browser.
Ciclul de viaţă
• Incărcarea în memorie - este instanţiată clasa principală
• Iniţializarea - este apelată metoda init
• Pornirea - este apelată metoda start
• Execuţia propriu-zisă
• Oprirea temporară - este apelată metoda
• Oprirea definitivă - este apelată metoda destroy

Structura generală a unui applet va fi:


import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class StructuraApplet extends Applet {
public void init() {........}
public void start() {.......}
public void stop() {........}
public void destroy() {........}
}
Aceste metode sunt apelate automat de browser şi nu trebuie apelate explicit
din program !
Pentru desenare în cadrul appletului desenarea se va suprascrie metoda:
public void paint(Graphics g) {
// Desenare
...
}
Definirea şi folosirea parametrilor permit personalizarea aspectului sau comportării unui applet
fără a-i schimba codul. Definirea se face în felul următor:

<APPLET CODE="TestParametri.class" WIDTH=100 HEIGHT=50


<PARAM NAME=textAfisat VALUE="Salut">
<PARAM NAME=numeFont VALUE="Times New Roman">
<PARAM NAME=dimFont VALUE=20>
</APPLET>

Folosirea parametrilor se va face prin apelarea- getParameter()


”Documentarea” parametrilor se va face prin apelarea getParameterInfo() care va returna un
vector de triplete: (numele, tipul, descriere).

import java . applet . Applet ;


import java . awt .*;
public class TestParametri extends Applet
{
String text , numeFont ;
int dimFont ;
public void init () {
text = getParameter (" textAfisat ");
if ( text == null ) text = " Hello "; // valoare implicita
numeFont = getParameter (" numeFont ");
if ( numeFont == null ) numeFont = " Arial ";
try {
dimFont = Integer . parseInt ( getParameter (" dimFont "));
} catch ( NumberFormatException e) {
dimFont = 16;
}
}
public void paint ( Graphics g)
{
g. setFont (new Font ( numeFont , Font .BOLD , dimFont ));
g. drawString (text , 20, 20);
}
public String [][] getParameterInfo ()
{
String [][] info = {
// Nume Tip Descriere
{" textAfisat ", " String ", " Sirul ce va fi afisat "},
{" numeFont ", " String ", " Numele fontului "},
{" dimFont ", "int ", " Dimensiunea fontului "}
};
return info ;
}
}

Tag-ul APPLET atunci când se vor defini parametrii vor arăta ceva de genul:

<APPLET
CODE = clasaApplet
WIDTH = latimeInPixeli
HEIGHT = inaltimeInPixeli
[ARCHIVE = arhiva.jar]
[CODEBASE = URLApplet]
[ALT = textAlternativ]
[NAME = numeInstantaApplet]
[ALIGN = aliniere]
[VSPACE = spatiuVertical]
[HSPACE = spatiuOrizontal] >
[< PARAM NAME = parametru1 VALUE = valoare1 >]
[< PARAM NAME = parametru2 VALUE = valoare2 >]
...
[text HTML alternativ]
</APPLET>

Arhivarea appleturilor reprezintă cea mai eficientă modalitate de a distribui un applet. Arhivarea
fişierelor se face folosind comanda
jar cvf arhiva.jar ClasaPrincipala.class AltaClasa.class imagine.jpg sunet.au
sau
jar cvf arhiva.jar *.class *.jpg *.au

Includerea unui applet arhivat într-o pagină Web se va face puţin diferit şi anume:

<applet archive=arhiva.jar code=ClasaPrincipala width=400 height=200 />

Restricţii de securitate Browser-ul instalează un manager de securitate (SecurityManager) care va


”superviza” activitatea appletului, aruncând excepţii de tip Security Exception pentru operaţii nepermise.
Din motive de securitate un applet nu poate să:
• Citească sau să scrie fişiere pe calculatorul pe care a fost încarcat (client).
• Deschidă conexiuni cu alte maşini în afară de cea de pe care provine (host).
• Pornească programe pe maşina client.
• Citească diverse proprietăţi ale sistemului de operare al clientului.

import java.awt.*;
import java.applet.*;

public class Applet1 extends Applet {

public void paint(Graphics g)


{

Font font=new Font("Arial", Font.BOLD, 15);


Color color=new Color(155,200,55);
g.setFont(font);
g.setColor(color);

int a=Integer.parseInt(getParameter("param1"), 10);


// sau int a=Integer.decode(getParameter("param1"));
int b=Integer.parseInt(getParameter("param2"), 10);
String c=new Integer(a+b).toString();

g.drawString("Salutare natiune! ", 0,30);


g.drawString("Suma numerelor date ca parametru este "+c.toString(), 20,50);

g.drawImage(getToolkit().getImage(Applet1.class.getResource("/"+"a.jpg")), 40, 60, this);


// se porneste din stanga sus si se face deplasarea in dreapta-jos
}

Pot fi acreate appleturi care sunt rulează şi ca aplicaţii. Acest lucru se face urmărind paşii:
• Adăugăm metoda main clasei care descrie appletul, în care vom face operaţiunile următoare.
• Creăm o instanţă a appletului şi o adăugăm pe suprafaţa unei ferestre.
• Apelăm metodele init şi start, care ar fi fost apelate automat de către browser.
• Facem fereastra vizibilă.

import java . applet . Applet ;


import java . awt .*;
public class AppletAplicatie extends Applet {
public void init ()
{
add (new Label (" Applet si aplicatie "));
}
public static void main ( String args [])
{
AppletAplicatie applet = new AppletAplicatie ();
Frame f = new Frame (" Applet si aplicatie ");
f. setSize (200 , 200) ;
f.add(applet , BorderLayout . CENTER );
applet . init ();
applet . start ();
f. setVisible(true);
}
}
Laborator 3
Crearea obiectelor
In Java obiectele sunt create prin instantierea unei clase, cu alte cuvinte prin crearea unei instante a unei
clase.Crearea unui obiect presupune trei lucruri: declararea, instanţierea şi iniţializarea

Declararea obiectului
NumeClasa numeObiect;
Ex: Rectangle patrat;

Instantierea
Se realizeaza prin intermediul operatorului new si are ca efect crearea efectiva a obiectului cu alocarea
spatiului de memorie corespunzator.
patrat = new Rectangle();

Initializarea
Se realizeaza prin intermediul constructorilor clasei respective. Rectangle() este un apel catre constructorul
clasei Rectangle care este responsabil cu initializarea obiectului. Initializarea se poate face si cu anumiti
parametri, cu conditia sa existe un constructor al clasei respective care sa accepte parametrii respectivi;
patrat = new Rectangle(0, 0, 100, 200);
Fiecare clasa are un set de constructori care se ocupa cu initializare obiectelor nou create. De exemplu clasa
Dreptunghi poate avea urmatorii constructori:
public Rectangle(int w, int h)
public Rectangle(int x1, int y1, int x2, int y2)

Referirea valorii unei variabile se face prin


obiect.variabila
Ex: Dreptunghi patrat = new Dreptunghi(0, 0, 100, 200);
System.out.println(patrat.width);

Apelul unei metode se face prin


obiect.metoda(parametru1, parametru2,........)
Dreptunghi patrat = new Dreptunghi(0, 0, 100, 200);
patrat.setDimension(10, 20); //schimba dimensiunile

Distrugerea obiectelor: nu mai este responsabilitatea programatorului. În momentul rularii unui program,
simultan cu interpretorul Java ruleaza si un proces care se ocupa cu distrugerea obiectelor care nu mai sunt
folosite. Acest proces este pus la dispozitie de platforma Java de lucru şi se numeste garbage collector

Declararea claselor
[public][abstract][final] class NumeClasa
[extends NumeSuperclasa]
[implements Interfata1 [, Interfata2 ... ]]
{
//corpul clasei
}
Se observa ca, spre deosebire de C++, Java permite doar mostenirea simpla, asadar o clasa poate avea un
singur un singur parinte (superclasa). Evident o clasa poate avea oricâţi mostenitori (subclase). Extinderea
unei clase se realizeaza deci astfel:
class B extends A {...} //A este superclasa clasei B

Modificatorii unei clase:


Public - Implicit, o clasa poate fi folosita doar de clasele aflate în acelasi pachet cu clasa respectiva (daca
nu se specifica un anume pachet, toate clasele din directorul curent sunt considerate a fi în acelasi pachet).
O class declarată cu public poate fi folosita de orice clasa, indiferent de pachetul în care se gaseste.
Abstract - Declară o clasa abstracta (sablon). O clasa abstracta nu poate fi instantiata, fiind folosita doar
pentru a crea un model comun pentru o serie de subclase;
Final - Declara ca respectiva clasa nu poate avea subclase. Declarare claselor finale are doua scopuri:
• securitate : unele metode pot astepta ca parametru un obiect al unei anumite clase si nu al unei
subclase, dar tipul exact al unui obiect nu poate fi aflat cu exactitate decât în momentul executiei;
În felul acesta nu s-ar mai putea realiza obiectivul limbajului Java ca un program care a trecut
compilarea nu mai este susceptibil de nici o eroare (nu "crapa sistemul").
• programare în spririt orientat-obiect : "O clasa perfecta nu trebuie sa mai aiba subclase"
Corpul unei clase
Urmeaza declararea clasei si este cuprins între acolade. Conţine:
declararea variabilelor de instanta si de clasa (cunoscute împreuna ca variabile membre)
declararea si implementarea metodelor de instanta si de clasa (cunoscute împreuna ca metode membre)
Spre deosebire de C++, nu este permisa doar declararea metodei în corpul clasei, urmând ca implementarea
să fie făcuta în afara ei. Implementarea metodelor unei clase trebuie sa se faca "inline" in corpul clasei.
In C++ In Java
class A
{
void
metoda1(); class A
int metoda2() {
{ void metoda()
//implementare {
} //implementare
} }
A::metoda1() }
{
//implementare
}
Constructorii unei clase
Constructorii unei clase sunt metode speciale care au acelasi nume cu cel al clasei, nu returneaza nici o
valoare si sunt folositi pentru initializarea obiectelor acelei clase în momentul instantierii lor.
class Dreptunghi {
Dreptunghi() {
//constructor
}
}
Constructorii sunt apelati automat la instantierea unui obiect. O clasa poate avea unul sau mai multi
constructori care trebuie însa sa difere prin lista de argumente primite. In felul acesta sunt permise diverse
tipuri de initializari ale obiectului la crearea sa, în functie de numarul parametrilor cu care este apelat
constructorul
In cazul în care scrieti o clasa care nu are declarat nici un constructor, sistemul îi creeaza automat un
constructor implicit care nu primeste nici un argument si care nu face nimic. Deci prezenta constructorilor
în corpul unei clase nu este obligatorie. Dacă însa ati scris un constructor pentru o clasa care are mai mult
de un argument, atunci constructorul implicit (fara nici un argument) nu va mai fi furnizat implicit de catre
sistem.

Declararea variabilelor membre


[modificatori] TipDeDate numeVariabila [ =
valoareInitiala ] ;
Variabilele unei clase se declara în corpul clasei dar nu în corpul unei metode. Variabilele declarate în
cadrul unei metode sunt locale metodei respective.
Declararea unei variabile presupune specificarea urmatoarelor lucruri:
• numele variabilei
• tipul de date
• nivelul de acces la acea variabila de catre alte clase
• daca este constanta sau nu
• daca este variabila de instanta sau de clasa
O clasa Java poate contine doua tipuri de variabile si metode :
• de instanta: declarate fara modificatorul static, specifice fiecarei instante si
• de clasa: declarate cu modificatorul static, specifice clasei

Implementarea metodelor

Metodele sunt responsabile cu descrierea comportamentului unui obiect. Generic, o metoda se declara
astfel:
[modificatori] TipReturnat numeMetoda ( [argumente] )
[throws TipExceptie]
{
//corpul metodei
}

! Şi pentru variabile şi pentru metode modificatorii pot fi : public, private, protected, final, static

Listing 1 Listing 2

import java.io.*; import java.io.*;


class Punct class Dreptunghi
{ {
private int x,y; protected Punct stg_sus, dr_jos;
public Dreptunghi(int x, int y, int z, int t)
public Punct(int xx, int yy) {
{ stg_sus=new Punct(x,y);
x=xx; y=yy; dr_jos=new Punct(z,t);
} }
public Dreptunghi(Punct p1, Punct p2)
public Punct(Punct p) {
{ stg_sus=p1;
x=p.x; dr_jos=p2;
y=p.y; }
} public Dreptunghi(int a, int b)
{
public int getX() this(a, b, 0, 0);
{ return x; } stg_sus=new Punct(a,b);
dr_jos=new Punct(0,0);
public int getY() }
{ return y; } public Dreptunghi()
public void setX(int a) {
{ x=a;; } this(0, 0, 10, 10);
stg_sus=new Punct(0,0);
public void setY(int a) dr_jos=new Punct(10,10);
{ y=a; } }
public int width()
public void afisare() {
{ ClientPunct
class returnMath.max(Math.abs(a.getX()-
class ClientDretunghi
{ System.out.println(x+" , "+y); b.getX()), {
}
public static void main(String[]arg) Math.abs(a.g
public static void main(String[]arg)
{ etY()-b.getY()));
{
static
Punctdouble distanta(Punct
p1 = new a, Punct b)
Punct(10,20); } Punct p1 = new Punct(0,0);
{Punct p2 = new Punct(30,40); Punct p2 = new Punct(3,4);
returnp3
Punct Math.sqrt(Math.pow((a.x-
= new Punct(p1); public int height() Dreptunghi d1 =new
b.x),2)+Math.pow((a.y-b.y),2));
System.out.println("(x1,y1)=("+p1.getX()+","+p1.getY() { Dreptunghi(p1,p2);
}
+")"); return Math.min(Math.abs(a.getX()-
Dreptunghi d2 =new
} System.out.println("(x2,y2)=("+p2.getX()+","+p2.getY()b.getX()), Dreptunghi(0,10,2,9);
+")"); Dreptunghi Math.abs(a.g
d3 =new
System.out.println("Distanta dintre p1 si pe este : etY()-b.getY()));
”+ Dreptunghi();
Punct.distanta(p1,p2)); } Dreptunghi d4 =new
} Dreptunghi(4,3);
} public int arie()
{ return width()*height(); }
System.out.println(d1.arie()+"
"+d1.diagonala());
public double diagonala() System.out.println(d2.arie()
{ return Punct.distanta(stg_sus,de_jos); }
+" "+d2.diagonala());
} System.out.println(d3.arie()
+" "+d3.diagonala());
System.out.println(d4.arie()
+" "+d4.diagonala());
}
}

Listing 3 Listing 4

Listing 5 Listing 6
import java.io.*; class ClientPatrat
class Patrat extends Dreptunghi {
{ public static void main(String[]arg)
public Patrat (Punct p, int latura) {
{ Punct p1 =new Punct(3,4);
stg_sus=new Punct(p.getX(),p.getY()); Patrat d1 =new Patrat(p1,2);
dr_jos=new Punct(p.getX()+latura,p.getY() Patrat d2 =new Patrat();
+latura); Patrat d3 =new Patrat(4,3,5);
}
System.out.println(d1.arie()+"
public Patrat(int a, int b, int latura) "+d1.diagonala()+" "+d1.height()+" "+d1.width());
{ super(a, b, a+latura, b+latura); } System.out.println(d2.arie()+"
"+d2.diagonala()+" "+d2.height()+" "+d2.width());
public Patrat() System.out.println(d3.arie()+"
{ "+d3.diagonala()+" "+d3.height()+" "+d3.width());
super(); }
// este bun doar pentru ca Dreptunghi() genereaza un }
patrat
}
// mosteneste toate metodele si variabilele publicsi
protected din Dreptunghi
}
Laborator 4

INTERFETE

Definirea unei interfeţe


[public] interface NumeInterfata [extends SuperInterfata1, SuperInterfata2...]
{
// Corpul interfetei:
Declaratii de constante
Declaratii de metode abstracte
}

interface Exemplu
{
int MAX = 100; // echivalent cu: public static final int MAX = 100;
int MAX; // Incorect, lipseste initializarea
private int x = 1; // Incorect, modificator nepermis
void metoda(); // Echivalent cu: public void metoda();
protected void metoda2(); // Incorect, modificator nepermis
}
Implementarea unei interfeţe: class NumeClasa implements Interfata1, Interfata2, ...

O clasă care implementează o interfaţă trebuie obligatoriu să specifice cod pentru toate metodele
interfeţei. Implementarea unei interfeţe poate să fie şi o clasă abstractă. Spunem că un obiect are tipul X,
unde X este o interfaţă, dacă acesta este o instanţă a unei clase ce implementează interfaţa X.

Exemplu: implementarea unei stive


Listing 1: Interfaţa ce descrie stiva
public interface Stack
{
void push ( Object item ) ;
void pop () ;
Object peek () ;
boolean empty ();
String toString ();
}

Listing 2: Implementarea stivei folosind un vector


// Implementarea stivei folosind un array de obiecte .
public class StackImpl1 implements Stack
{
private Object items []; // arrayul ce contine obiectele
private int n=0; // Numarul curent de elemente din stiva
public StackImpl1 (int max)
{ // Constructor
items = new Object [max];
}
public StackImpl1 ()
{
this (100);
}
public void push ( Object item )
{
if (n == items . length ) System.out.println (" Stiva este plina !");
else items [n++] = item ;
}
public void pop ()
{
if (empty()) System.out.println (" Stiva este vida !");
else items [--n] = null ;
}
public Object peek ()
{
if (empty ()) System.out.println (" Stiva este vida !");
return items [n -1];
}
public boolean empty ()
{
return (n ==0) ;
}
public String toString ()
{
String s="";
for (int i=n-1;i>=0;i--) s += items [i]. toString () + " ";
return s;
}
}

Listing 3: Folosirea stivei


public class TestStiva
{
public static void afiseaza (Stack s)
{ System.out.println ("Continutul stivei este : " + s.toString()); }
public static void main (String args [])
{
Stack s1 = new StackImpl1 (3);
System.out.println(s1.peek()); // va fi aruncata o exceptie
s1. push (new Integer(4));
s1. push ("a");
s1.push(new Double(9));
System.out.println(s1.peek());
s1.pop();
afiseaza (s1);
}
}

Interfeţe şi clase abstracte


• Extinderea unei clase abstracte forţează o relaţie între clase (de moştenire);
• Implementarea unei interfeţe specifică doar necesitatea implementării unor anumie metode.
Interfeţele şi clasele abstracte nu se exclud, fiind folosite împreună.(Ex: List, AbstractList,
LinkedList, ArrayList)
Moştenire multiplă prin interfeţe
class NumeClasa implements Interfata1, Interfata2, ...
interface NumeInterfata extends Interfata1, Interfata2, ...
Ierarhia interfeţelor este independentă de ierarhia claselor care le implementează.
interface I1 interface I1
{ {
int a=1; int x=1;
void metoda1(); void metoda();
} }

interface I2 interface I2
{ {
int b=2; int x=2;
void metoda2(); void metoda(); //corect
} //int metoda(); //incorect
}
class C implements I1, I2
{ class C implements I1, I2
void metoda1() {...} {
void metoda2() {...} public void metoda()
} {
System.out.println(I1.x); //corect
System.out.println(I2.x); //corect
System.out.println(x); //ambiguitate
}
}

Utilitatea interfeţelor
• Definirea unor similaritati între clase independente.
• Impunerea unor specificaţii
• Definirea unor grupuri de constante
• Transmiterea metodelor ca parametri

EXCEPTII

O exceptie este un eveniment „exceptional” ce se produce în timpul executiei unui program si care
provoaca întreruperea cursului normal al executiei

Exceptiile pot aparea din diverse cauze si pot avea nivele diferite de gravitate, iar in momentul când o
asemenea eroare se produce în timpul executiei sistemul genereaza automat un obiect de tip exceptie ce
contine:
• informatii despre exceptia respectiva
• starea programului în momentul producerii acelei exceptii
public class Exceptii {
public static void main(String args [] ) {
int v[] = new int[10];
v[10] = 0; //exceptie, vectorul are elementele v[0]...v[9]
System.out.println("Aici nu se mai ajunge...");
}
}
La rularea programului va fi generata o exceptie si se va afisa mesajul :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException :10
at Exceptii.main (Exceptii.java:4)

Crearea unui obiect de tip exceptie se numeste aruncarea unei exceptii ("throwing an exception"). In
momentul în care o metoda genereaza o exceptie (arunca o exceptie) sistemul de executie este responsabil
cu gasirea unei secvente de cod dintr-o metoda care sa trateze acea exceptie. Cautarea se face recursiv,
începând cu metoda care a generat exceptia si mergând înapoi pe linia apelurilor catre acea metoda.
Cu alte cuvinte la aparitia unei erori este "aruncata" o exceptie iar cineva trebuie sa o "prinda" pentru a o
trata. Daca sistemul nu gaseste nici un analizor pentru o anumita exceptie atunci programul Java se opreste
cu un mesaj de eroare (în cazul exemplului de mai sus mesajul "Aici nu se mai ajunge..." nu va fi tiparit).

Atentie: In Java tratarea erorilor nu mai este o optiune ci o constrângere. Orice cod care poate provoca
exceptii trebui sa specfice modalitatea de tratare a acestora.
Tratarea exceptiilor se realizeaza prin intermediul blocurilor de instructiuni try, catch si
finally. O secventa de cod care trateaza anumite exceptii trebuie sa
arate astfel:
try {
Instructiuni care pot genera o exceptie
}
catch (TipExceptie1 ) {
Prelucrarea exceptiei de tipul 1
}
catch (TipExceptie2 ) {
Prelucrarea exceptiei de tipul 2
}
...
finally {
Cod care se executa indiferent daca apar sau nu exceptii
}

Java permite unei metode sa arunce exceptiile aparute în cadrul ei la un nivel superior, adica functiilor care
o apeleaza sau sistemului. Cu alte cuvinte o metoda poate sa nu îsi asume responsabilitatea tratarii
exceptiilor aparute în cadrul ei. Acet lucru se realizeaza prin specificarea în
declaratia metodei a clauzei throws:
metoda throws TipExceptie1, TipExceptie2, ... {
...
}
Atentie! O metoda care nu trateaza o anumita exceptie trebuie obligatoriu sa o ”arunce”.

Aruncarea unei exceptii se poate face si implicit prin instructiunea


throw ce are formatul: throw obiect_de_tip_Exceptie .
Exemple:
throw new IOException();
if (index >= vector.length)
throw new ArrayIndexOutOfBoundsException();
catch(Exception e) {
System.out.println("A aparut o exceptie);
throw e;
}
Aceasta instructune este folosita mai ales la aruncarea exceptiilor proprii care, evident, nu sunt detectate de
catre mediul de executie.

class MyException extends Exception {


public MyException() {}
public MyException(String msg) {
super(msg);
//apeleaza constructorul superclasei Exception
}
}
Exceptii la executie (RuntimeException) cum ar fi:
• operatii aritmetice (împartire la zero) ArithmeticException
• accesarea membrilor unui obiect ce are valoarea null NullPointerException
• operatii cu vectori (accesarea unui index din afara domeniului)ArrayIndexOutOfBoundsException

pot aparea oriunde în program si pot fi extrem de numeroare iar


încercarea de "prindere" a lor ar fi extrem de anevoioasa. Din acest
motiv compilatorul permite ca aceste exceptii sa ramâna netratate,
tratarea lor nefiind însa ilegala.

Listing 4
public class Exceptii
{
int v[];
public Exceptii()
{
v = new int[10];
metoda();
}

void metoda() //throws ArrayIndexOutOfBoundsException


{
v[10]=0;
}

public static void main (String args [])


{
try {
//new Exceptii();
System.out.println("Aici nu se mai ajunge...");
} catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Atentie la indecsi!");
e.printStackTrace();
}//legal
finally
{
System.out.println("In schimb aici se ajunge...");
}
}
}
Avantajele trat¢arii exceptiilor:
• Separarea codului
• Propagarea erorilor
• Gruparea erorilor dupa tip.
Laborator 5
Adeseori programele necesita citirea unor informatii care se gasesc pe o sursa externa sau
trimiterea unor informatii catre o destinatie externa. Informatia se poate gasi oriunde : într-un fisier pe disc,
în retea, în memorie sau în alt program si poate fi de orice tip: date primitive, obiecte, imagini, sunete, etc.
Pentru a aduce informatii dintr-un mediu extern, un progam Java trebui sa deschida un canal de
comunicatie (flux) catre sursa informatiilor (fisier, memorie, socket,etc) si sa citeasca serial informatiile
respective.
Similar, un program poate trimite informatii catre o destinatie externa deaschizând un canal de
comunicatie (flux) catre acea destinatie si scriind serial informatiile respective.
Indiferent de tipul informatiilor, citirea/scrierea informatiilor de pe/catre un mediu extern respecta
urmatoriul algoritm:
deschide canal comunicatie
while (mai sunt informatii) {
citeste/scrie informatie
}
inchide canal comunicati;
Definitii:
• Un flux este un canal de comunicatie unidirectional între doua procese pe 8 sau 16 biti.
• Un proces care descrie o sursa externa de date se numeste proces producator si este unic pt acel
flux.
• Un proces care descrie o destinatie externa pentru date se numeste proces consumator si este unic
pt acel flux.
Clasele si intefetele standard pentru lucu cu fluxuri se gasesc în pachetul java.io. Deci orice
program care necesita operatii de intrare/iesire trebuie sa contina instructiunea de import a pachetului
java.io: import java.io.*;
Exista trei tipuri de clasificare a fluxurilor:
1. Dupa "directia" canalului de comunicatie deschis fluxurile se împart în:
o fluxuri de intrare (pentru citirea datelor)
o fluxuri de iesire (pentru scrierea datelor)
2. Dupa tipul de date pe care opereaza:
o fluxuri de octeti (comunicare seriala se realizeaza pe 8 biti)
o fluxuri de caractere (comunicare seriala se realizeaza pe 16 biti)
3. Dupa actiunea lor:
o fluxuri primare de citire/scriere a datelor (se ocupa efectiv cu citirea/scrierea datelor)
o fluxuri pentru procesarea datelor

Fluxuri pe caractere:
Fluxuri de octeti:

Atentie: Pentru majoritatea programelor scrierea si citirea datelor se vor face prin intermediul
fluxurilor de caractere deoarece acestea permit manipularea caracterelor Unicode (16-biti), în timp ce
fluxurile de octeti permit doar lucrul pe 8 biti - caractere ASCII.

Fluxuri primitive
• Fisier FileReader, FileWriter,
FileInputStream, FileOutputStream
• Memorie CharArrayReader, CharArrayWriter,
ByteArrayInputStream, ByteArrayOutputStream,
StringReader, StringWriter
• Pipe PipedReader, PipedWriter,
PipedInputStream, PipedOutputStream
Fluxuri de procesare
• ”Buferizare” BufferedReader, BufferedWriter
BufferedInputStream, BufferedOutputStream
• Conversie octeti-caractere InputStreamReader, OutputStreamWriter
• Concatenare SequenceInputStream
• Serializare ObjectInputStream, ObjectOutputStream
• Conversie tipuri de date DataInputStream, DataOutputStream
• Numarare LineNumberReader, LineNumberInputStream
• Citire in avans PushbackReader, PushbackInputStream
• Afisare PrintWriter, PrintStream

Crearea unui flux primitiv


FluxPrimitiv numeFlux = new FluxPrimitiv(dispozitivExtern);
//crearea unui flux de intrare pe caractere
FileReader in = new FileReader("fisier.txt");
//crearea unui flux de iesire pe caractere
FileWriter out = new FileWriter("fisier.txt");
//crearea unui flux de intrare pe octeti
FileInputStream in =new FileInputStream("fisier.dat");
//crearea unui flux de iesire pe octeti
FileOutputStrem out =new FileOutputStream("fisier.dat");

Crearea unui flux de procesare


FluxProcesare numeFlux = new FluxProcesare(fluxPrimitiv);
//crearea unui flux de intrare printr-un buffer
BufferedReader in = new BufferedReader(new FileReader("fisier.txt"));
//echivalent cu
FileReader fr = new FileReader("fisier.txt");
BufferedReader in = new BufferedReader(fr);
//crearea unui flux de iesire printr-un buffer
BufferedWriter out = new BufferedWriter(new FileWriter("fisier.txt")));
//echivalent cu
FileWriter fo = new FileWriter("fisier.txt");
BufferedWriter out = new BufferedWriter(fo);

Citirea si scrierea cu buffer


BufferedReader, BufferedWriter
BufferedInputStream, BufferedOutputStream

Aceste clase Introduc un buffer (zona de memorie) in procesul de citire/scriere a informatiilor.


BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("out.dat"), 1024);
//1024 este dimensiunea bufferului
Avantaje: eficienta si viteza de executie mai mare precum si un numar mai scazut de accesari ale
dispozitivului extern

Analiza lexicala pe fluxuri (clasa StreamTokenizer)


Clasa StreamTokenizer parcurge un flux de intrare de orice tip si îl împarte în "atomi lexicali". Rezultatul
va consta în faptul ca în loc sa se citeasca octeti sau caractere se vor citi, pe rând, atomii lexicali ai fluxului
respectiv.
Printr-un atom lexical se în]elege în general:
o un identificator (un sir care nu este între ghilimele)
o un numar
o un sir de caractere
o un comentariu
o un separator
Atomii lexicali sunt despartiti între ei de separatori. Implicit acesti separatori sunt cei
obisnuti( spatiu, tab, virgula, punct si virgula), însa pot fi schimbati prin diverse metode ale clasei.
Constructorii acestei clase sunt:
public StreamTokenizer( Reader r )
public StreamTokenizer( InputStream is )
Identificarea tipului si valorii unui atom lexical se face prin intermediul variabilelor:
TT_EOF - atom ce marcheaz sfârsitul fluxului
TT_EOL - atom ce marcheaz sfârsitul unei linii
TT_NUMBER - atom de tip numar
TT_WORD - atom de tip cuvânt
nval - valoarea unui atom numeric
sval - sirul continut de un atom de tip cuvânt
ttype - tipul ultimului atom citit din flux

Citirea atomilor din flux se face cu metoda nextToken(), care returneza tipul atomului lexical citit
si scrie în variabilele nval sau sval valoarea corespunzatoare atomului.
Exemplul tipic de folosire a unui analizor lexical este citirea unei secvente de numere si siruri
aflate într-un fisier sau primite de la tastatura:
//Citirea unei secvente de numere si siruri
import java.io.*;
public class TestTokenizer {
public static void main(String args[]) throws IOException{
FileInputStream fis = new FileInputStream("test.dat");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));

StreamTokenizer st = new StreamTokenizer(br);

int tip = st.nextToken(); //citesc primul atom lexical


while (tip != StreamTokenizer.TT_EOF) {
switch (tip) {
case StreamTokenizer.TT_WORD : //cuvant
System.out.println(st.sval); break;
case StreamTokenizer.TT_NUMBER : //numar
System.out.println(st.nval); break;
}
tip = st.nextToken();//urmatorul atom
}
}
}

Avantajele folosirii constructiei try-catch-finaly pt lucrul cu fisiere:


In locul unui if la fiecare iteratie un program Java poate arata asa:
int citesteFisier {
try {
deschide fisierul;
determina dimensiunea fisierului;
aloca memorie;
citeste fisierul in memorie;
inchide fisierul;
}
catch (fisierul nu s-a deschis) {trateaza eroarea;}
catch (nu s-a determinat dimensiunea) {trateaza eroarea;}
catch (nu s-a alocat memorie) {trateaza eroarea}
catch (nu se poate citi dun fisier) {trateaza eroarea;}
catch (nu se poate inchide fisierul) {trateaza eroarea;}
}

Atentie: Iorice flux s-ar folosi el trebuie inchi la sfarsit, aceasta inchidere facandu-se folosind metoda:
close.
Aplicatii

Copiere de fisiere ca fluxuri de biti


import java.io.*;
public class CopiereFisierEOF {
public static void main(String[] a) {
try
{
String intrare = “Intrare.dat”, iesire = ”Iesire.txt”;
DataInputStream in = new DataInputStream(new BufferedInputStream(new
FileInputStream(intrare)));
DataOutputStream out = new DataOutputStream( new BufferedOutputStream( new
FileOutputStream(iesire)));
while(in.available() != 0) out.writeByte(in.readByte());
out.close();
in.close();
} catch (Exception e)
{
System.err.println(e.getMessage());
e.printStackTrace();
}//catch
}//CopiereFisierEOF.main
} //CopiereFisierEOF

Redirectare de fisiere sistem


System.in - InputStream
System.out - PrintStream
System.err - PrintStream

import java.io.*;
class CopyTextRedirectari {
public static void main(String[] a) {
if (a.length != 3) {
System.err.println("Apel \"CopyTextRedirectari intrare iesire erori\"");
System.exit(1);
}//if
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(a[0]));
PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(a[1])));
PrintStream err = new PrintStream(new BufferedOutputStream(new FileOutputStream(a[2])));
System.setIn(in);
System.setOut(out);
System.setErr(err);
BufferedReader brin = new BufferedReader(new InputStreamReader(System.in));
String s;
for (;;) {
s = brin.readLine();
if (s==null)
break;
System.out.println(s);
}//for
System.out.println("Terminare normala redirectare out");
System.err.println("Terminare normala redirectare err");
brin.close();
in.close();
out.close();
err.close();
}//try
catch(IOException e) {
System.err.println("Eroare IO probabil dupa redirectari");
e.printStackTrace();
}//catch
}//CopyTextRedirectari.main
} //CopyTextRedirectari

Alte tipuri de operatii I/O

import java.io.*;
public class IODemo {
public static void main(String[] args) {
try {
// 1. Citirea din intrare, linie cu linie,
BufferedReader in1 = new BufferedReader(new FileReader("Intrare.txt"));
String s, t = new String();
while((s = in1.readLine())!= null)
t += s + System.getProperty("line.separator");
in1.close();

// 2. Intrare din memorie


StringReader in3 = new StringReader(t);
int c;
while((c = in3.read()) != -1) System.out.print((char)c);

// 3. Citire o linie de la intrarea standard


int contor=1;
String sir="";
BufferedReader in2 = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Iesirea din bucla se face tastand \"Exit\"");
while (!sir.equalsIgnoreCase("Exit"))
{
System.out.println("Da linia cu numarul "+contor+++": ");
sir=in2.readLine();
System.out.println(sir);
}

// 4. Salvare / refacere date


DataOutputStream out4 = new DataOutputStream(new BufferedOutputStream(new
FileOutputStream("Data.txt")));
out4.writeDouble(Math.PI);
out4.writeInt(36);
out4.writeBytes("Acesta este numarul PI");
out4.close();
DataInputStream in4 = new DataInputStream(new BufferedInputStream(new
FileInputStream("Data.txt")));
BufferedReader in4br = new BufferedReader(new InputStreamReader(in4));
// Trebuie folosit DataInputStream pentru date:
System.out.println(in4.readDouble());
System.out.println(in4.readInt());
// Se poate folosi readLine():
System.out.println(in4br.readLine());
// 5. RandomAccessFiles
RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");
for(int i = 0; i < 10; i++) rf.writeLong(i*10);
rf.close();
rf = new RandomAccessFile("rtest.dat", "rw");
rf.seek(6*8);
rf.writeLong(999);
rf.close();
rf = new RandomAccessFile("rtest.dat", "r");
for(int i = 0; i < 10; i++) System.out.println("Pozitia " +i+": "+rf.readLong());
rf.close();
}//try
catch(Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}//catch
}//IODemo.main
}// IODemo

!!! Mai multe informatii despre metodele claselor care apar de-a lungul acestui laborator gasiti in help.
Laborator 6
Interfata grafica (GUI), se refera la toate tipurile de comunicare vizuala între un program si
utilizatorii sai. Aceasta este o particularizare a interfetei cu utilizatorul (UI), prin care vom întelege
conceptul generic de interactiune între un program si utilizatorii sai. Asadar, UI se refera nu numai la ceea
ce utilizatorul vede pe ecran ci la toate mecanismele de comunicare între acesta si program.
Biblioteca de clase care ofera servicii grafice se numeste java.awt, AWT fiind prescurtarea de la
Abstract Window Toolkit.
Crearea unei aplicatii grafice presupune urmatoarele lucruri:
• crearea unei suprafete de afisare (cum ar fi o fereastra) pe care vor fi asezate obiectele grafice care
servesc la comunicarea cu utilizatorul (butoane, controale de editare, texte, etc);
• crearea si asezarea obiectelor grafice pe suprafata de afisare în pozitiile corespunzatoare;
• definirea unor actiuni care trebuie sa se execute în momentul când utilizatorul interactioneaza cu
obiectele grafice ale aplicatiei;
• "Ascultarea" evenimentelor generate de obiecte în momentul interactiunii cu utilizatorul si
executarea actiunilor corespunzatoare asa cum au fost ele definite.
Majoritatea obiectelor grafice sunt subclase ale clasei Component, clasa care defineste generic o
componenta grafica care poate interactiona cu utilizatorul. Singura exceptie o constituie meniurile care
descind din clasa MenuComponent.
Exemple de componente sunt ferestrele, butoanele, bare de defilare, etc. In general, toate
componentele sunt definte de clase proprii ce se gasesc în pachetul java.awt, clasa Component fiind
superclasa abstracta a tuturor acestor clase.
Crearea obiectelor grafice nu realizeaza automat si afisarea lor pe ecran. Mai întâi ele trebuie
asezate pe o suprafata de afisare, care poate fi o fereastra sau suprafata unui applet, si vor deveni vizibile în
momentul în care suprafata pe care sunt afisate va fi vizibila. O astfel de suprafata pe care se aseaza
obiectele grafice reprezinta o instanta a unei clase obtinuta prin extensia clasei Container; din acest motiv
suprafetele de afisare vor mai fi numite si containere. Clasa Container este o subclasa aparte a clasei
Component, fiind la rândul ei superclasa tuturor suprafetelor de afisare Java (ferestre, applet-uri, etc). Iată
are unt principalele suprafete de afisare (cele derivate din Container):

Obiectele grafice trebuie sa genereze evenimente în functie de actiunea pe care au suferit-o


(actiune transmisa de la tastatura, mouse, etc.). Evenimentele se implementeaza ca obiecte instanta ale
clasei AWTEvent sau ale subclaselor ei.
Un eveniment este produs de o actiune a utilizatorului asupra unui obiect grafic, deci evenimentele
nu trebuie generate de programator. In schimb într-un program trebuie specificat codul care se executa la
aparitia unui eveniment. Interceptarea evenimentelor se realizeaza prin intermediul unor clase de tip
listener definite în pachetul java.awt.event.
Iată mai js care este ierarhia claselor pe care le vom folosi in cadrul aplicaţiilor.
import java.awt.*;
public class TestAWT1 {

public static void main(String args[]) {

// creez fereastra - un obiect de tip frame


Frame f = new Frame("Fereastra AWT");
f.setBackground(Color.yellow);
// setez modul de dipunere a ob. pe suprafata ferestrei
f.setLayout(new FlowLayout());

// creez o eticheta
Label eticheta = new Label("Eticheta");
eticheta.setBackground(Color.blue);
f.add(eticheta);

// creez un buton
Button buton = new Button("OK");
f.add(buton);

// creez un textfield
TextField parola = new TextField("", 10);
// parola.setEchoChar('*');
f.add(parola);

// creez un textarea
TextArea textarea = new TextArea("Ceva",20,10,TextArea.SCROLLBARS_NONE);
f.add(textarea);

// creez un checkbox
Checkbox cbx = new Checkbox("Bifeaza");
f.add(cbx);

// creez un choice
Choice alege = new Choice();
alege.add("alege1");
alege.add("alege2");
alege.add("alege3");
alege.select("alege3");
f.add(alege);

// creez o lista
List alegere = new List();
alegere.add("alege1");
alegere.add("alege2");
alegere.add("alege3");
alegere.add("alege4");
alegere.add("alege5");
f.add(alegere);

CheckboxGroup cbg = new CheckboxGroup();


Checkbox cbx1 = new Checkbox("Radio 1", cbg, false);
Checkbox cbx2 = new Checkbox("Radio 2", cbg, false);
Checkbox cbx3 = new Checkbox("Radio 3", cbg, false);
f.add(cbx1);
f.add(cbx2);
f.add(cbx3);
f.pack();

//afisez fereastra (o fac vizibila)


f.setVisible(true);
}
}

Gestionari de pozitie = intefeţe implementate de către container-ul folosit care contin metode de
aranjare a obiectelor pe interfaţa grafică.
Atasarea explicita a unui gestionar de pozitionare la un container se face cu metoda setLayout a
clasei Container. Secventa de atasare a unui gestionar pentru un container este:
container.setLayout(gestionar);
În cazul cβnd avem nevoie de obiectul gestionar îl putem obtine cu metoda getLayout din clasa
Container.
Una din facilitatile cele mai utile oferite de gestionarii de pozitionare este rearanjarea
componentele unui container atunci cβnd acesta este redimesionat. Sunt însa situatii când dorim sa plasam
componentele la anumite pozitii fixe iar acestea sa ramâna acolo chiar daca redimensionam containerul.
Acest lucru se poate realizza doar prin trimiterea argumentului null metodei setLayout:
container.setLayout(null);
Folosind pozitionarea absoluta, nu va mai fi suficient sa adaugam cu metoda add componentele în container
ci va trebui sa specificam pozitia si dimensiunea lor - acest lucru era facut automat de gestionarul de
pozitionare.
container.setLayout( null );
Button b = new Button("Buton");
b.setSize(10, 10); // era facut automat de gestionar
b.setLocation (0, 0); // // era facut automat de gestionar
b.add();
1. FlowLayout

2. BorderLayout
public class TestBorderLayout {
public static void main(String args[]) {
Frame f = new Frame("Border Layout");
f.setLayout(new BorderLayout());//poate sa
lipseasca
f.add(new Button("Nord"),
BorderLayout.NORTH);
f.add(new Button("Sud"),
BorderLayout.SOUTH);
f.add(new Button("Est"), BorderLayout.EAST);
f.add(new Button("Vest"),
BorderLayout.WEST);
f.add(new Button("Centru"),
BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
}

3. GridLayout
import java.awt.*;
public class TestGridLayout {
public static void main(String args[]) {
Frame f = new Frame("Grid
Layout");
f.setLayout(new GridLayout(3, 2));
f.add(new Button("1"));
f.add(new Button("2"));
f.add(new Button("3"));
f.add(new Button("4"));
f.add(new Button("5"));
f.add(new Button("6"));
f.pack();
f.setVisible();
}
}
3. CardLayout
Gestionarul CardLayout va avea componentele aşezate pe suprafata una peste altaastfel încât la un
moment dat numai o singura componenta este vizibila ("cea de deasupra").
Clasa dispune de metode prin care sa poata fi afisata o anumita componenta din pachet, sau sa se
poata parcurge secvential pachetul, ordinea în care componentele se gasesc în pachet fiind interna
gestionarului.
Acest gestionar este util pentru implementarea unor cutii de dialog de tip tab, pentru o gestionare mai
eficienta a spatiului.

4. GridBagLayout
Asemănător gestionarului GridLayout, diferenţa constând în faptul că numarul de linii si de
coloane a tabelelui sunt determinate automat, în functie de componentele amplasate pe suprafata de afisare.
Pentru a specifica modul de afisare a unei componente, acesteia îi este asociat un obiect de tip
GridBagConstraints (constrângeri cu privire la felul cum va fi plasata componenta respectiva), în care se
specifica diferite proprietati ale componentei referitoare la regiunea sa de afisare si la modul în care va fi
plasata în aceasta regiune. Legatura dintre o componenta si un obiect GridBagConstraints se realizeaza prin
metode setConstraints:
GridBagLayout gridBag = new GridBagLayout();
container.setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints();
...
//se specifica proprietatile referitoare la afisarea unei componente
gridBag.setConstraints(componenta, c);
container.add(componenta);

Gruparea componentelor (Clasa Panel)


Un panel este cel mai simplu model de container. El nu are o reprezentare vizibila, rolul sau fiind
de a oferi o suprafata de afisare pentru componente grafice, inclusiv pentru alte panel-uri.
Clasa care instantiaza aceste obiecte este Panel, extensie a superclasei Container.
Pentru a aranja corespunzator componentele grupate într-un panel (cele care nu trebuie sa fie
despartite de gestionarul de pozitionare al ferestrei), i se poate specifica acestuia un gestionar de
pozitionare anume, folosind metoda setLayout. Gestionarul implicit pentru containerele de tip Panel este
FlowLayout.

import java.awt.*;
public class TestPanel {
public static void main(String args[]) {
Frame f = new Frame("Panel");

Panel panel = new Panel();


panel.setLayout(new FlowLayout());
panel.add(new Label("Text:"));
panel.add(new TextField("", 20));
panel.add(new Button("Reset"));

f.add(panel, BorderLayout.NORTH);
f.add(new Button("OK"), BorderLayout.EAST);
f.add(new Button("Cancel"), BorderLayout.WEST);
f.pack();

f.show();
}
}

import java.awt.*;
import java.awt.event.*;
import java.io.*;

class Fereastra extends Frame implements ActionListener {


private TextArea text;
private Label eticheta;
private Button save;

public Fereastra(String titlu) {


super(titlu);
}

public void initializare() {


setBackground(Color.green);

text = new TextArea();


eticheta = new Label("Salvare in Fisier.txt");
save = new Button("Salveaza text");

Panel fisier = new Panel();


fisier.add(eticheta);

add(fisier, BorderLayout.NORTH);
add(text, BorderLayout.CENTER);
add(save, BorderLayout.SOUTH);

save.addActionListener(this);
pack();
setSize(300, 200);
}
//metoda interfetei ActionListener
public void actionPerformed(ActionEvent e) {
String continut = text.getText();
try {
eticheta.setText("Fisier.txt");
PrintStream out = new PrintStream(new FileOutputStream(eticheta.getText()));
out.println(continut);
out.close();
text.requestFocus();
eticheta.setText("Salvare reusita");
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}

public class TestTextArea {


public static void main(String args[]) {
Fereastra f = new Fereastra("TextArea");
f.initializare();
f.setVisible(true);
}
}
Laborator 7
Un eveniment este produs de o actiune a utilizatorului asupra unei componente grafice si
reprezinta mecanismul prin care utilizatorul comunica efectiv cu programul. Exemple de evenimente sunt:
apasarea unui buton, modificarea textului într-un control de editare, închiderea, redimensionarea unei
ferestre, etc. Componentele care genereaza anumite evenimente se mai numesc si surse de evenimente.
Interceptarea evenimentelor generate de componentele unui program se realizeaza prin intermediul unor
clase de tip listener (ascultator, consumator de evenimente). In Java, orice obiect poate "consuma"
evenimentele generate de o anumita componenta grafica.

Asadar, pentru a scrie cod care sa se execute în momentul în care utilizatorul interactioneaza cu o
componenta grafica trebuie sa facem urmatoarele lucruri:
• sa scriem o clasa de tip listener care sa "asculte" evenimentele produse de acea componenta si în
cadrul acestei clase sa implementam metode specifice pentru tratarea lor;
• sa comunicam componentei sursa ca respectiva clasa îi "asculta" evenimentele pe care le
genereaza, cu alte cuvinte sa înregistram acea clasa drept "consumator" al evenimentelor produse
de componenta respectiva.
Evenimentele sunt, ca orice altceva în Java, obiecte. Clasele care descriu aceste obiecte se împart
în mai multe tipuri în functie de componenta care le genereaza, mai precis în functie de actiunea
utilizatorului asupra acesteia. Pentru fiecare tip de eveniment exista o clasa care instantiaza obiecte de acel
tip; de exemplu: evenimentul generat de actionarea unui buton este implementat prin clasa ActionEvent, cel
generat de modificarea unui text prin clasa TextEvent, etc.
Toate aceste clase au ca superclasa comuna clasa AWTEvent. Lista completa a claselor care
descriu evenimente va fi data într-un tabel în care vom specifica si modalitatile de utilizare ale acestora.
O clasa consumatoare de evenimente (listener) poate fi orice clasa care specifica în declaratia sa ca
doreste sa asculte evenimente de un anumit tip. Acest lucru se realizeaza prin implementarea unei interfete
specifice fiecarui tip de eveniment. Astfel, pentru ascultarea evenimentelor de tip ActionEvent clasa
respectiva trebuie sa implementeze interfata ActionListener, pentru TextEvent interfata care trebuie
implementata este TextListener, etc.

Toate aceste interfete au suprainterfata comuna EventListener.


class AscultaButoane implements ActionListener
class AscultaTexte implements TextListener
Intrucât o clasa poate implementa oricâte interfete ea va putea sa asculte evenimente de mai multe
tipuri:
class Ascultator implements ActionListener, TextListener
Vom vedea în continuare metodele fiecarei interfete pentru a sti ce trebuie sa implementeze o
clasa consumatoare de evenimente.
Asa cum spus mai devreme, pentru ca evenimentele unei componente sa fie interceptate de catre o
instanta a unei clase ascultator, aceasta clasa trebuie înregistrata în lista ascultatorilor componentei
respective. Am spus lista, deoarece evenimentele unei componente pot fi ascultate de oricâte clase - cu
conditia ca acestea sa fie înregistrate la componenta respectiva. Inregistrarea unei clase în lista
ascultatorilor unei componente se face cu metode din clasa Component de tipul addXXXListener, iar
eliminarea ei din aceasta lista cu removeXXXListener unde XXX reprezenta tipul evenimentului.
Exemplu de tratare a evenimentelor
Inainte de a detalia aspectele prezentate mai sus, sa consideram un exemplu de tratare a evenimentelor.
Vom crea o fereastra care sa contina doua butoane cu numele "OK", repectiv "Cancel". La apasarea fiecarui
buton vom scrie pe bara titlu a ferestrei mesajul " Ati apasat butonul ...".
//Exemplu:Ascultarea evenimentelor de la doua butoane
import java.awt.*;
import java.awt.event.*;

class Fereastra extends Frame {


public Fereastra(String titlu) {super(titlu); }
public void initializare() {
setLayout(new FlowLayout()); //se stabileste gestionarul
setSize(200, 100); //se dimensioneaza fereastra

Button b1 = new Button("OK");


add(b1); //se adauga primul buton
Button b2 = new Button("Cancel");
add(b2); //se adauga al doilea buton

Ascultator listener = new Ascultator(this);


b1.addActionListener(listener);
b2.addActionListener(listener);
//ambele butoane sunt ascultate de obiectul "listener"
//instanta a clasei Ascultator, definita mai jos
}
}

class Ascultator implements ActionListener {


private Fereastra f;
public Ascultator(Fereastra f) {
this.f = f;
}
//metoda interfetei ActionListener
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
//numele comenzii este numele butonului apasat
System.out.println(e.toString());
if (command.equals("OK"))
f.setTitle("Ati apasat OK");
else
if (command.equals("Cancel"))
f.setTitle("Ati apasat Cancel");
}
}

public class TestEvent { //fereastra principala


public static void main(String args[]) {
Fereastra f = new Fereastra("ActionEvent");
f.initializare();
f.show();
}
}
Nu este obligatoriu sa definim clase speciale pentru ascultarea evenimentelor. In exemplul de mai sus am
definit o clasa speciala "Ascultator" pentru a intercepta evenimentele produse de cele doua butoane si din
acest motiv a trebuit sa trimitem ca parametru acestei clase instanta la fereastra noastra. Mai corect ar fi fost
sa folosim chiar clasa "Fereastra" pentru a-si asculta evenimentele produse de componentele sale:
class Fereastra extends Frame implements ActionListener{
public Fereastra(String titlu) {
super(titlu);
}
public void initializare() {
...
b1.addActionListener(this);
b2.addActionListener(this);
//ambele butoane sunt ascultate chiar din clasa Fereastra
//deci ascultatorul este instanta curenta: this
}

public void actionPerformed(ActionEvent e) {


String command = e.getActionCommand();
//numele comenzii este numele butonului apasat
System.out.println(e.toString());
if (command.equals("OK"))
this.setTitle("Ati apasat OK");
else
if (command.equals("Cancel"))
this.setTitle("Ati apasat Cancel");
}
}

Asadar, orice clasa poate asculta evenimnte de orice tip cu conditia sa implementeze interfetele
specifice acelor evenimente.

Folosirea adaptorilor si a claselor interne în tratarea evenimentelor


O fereastra care nu are specificat cod pentru tratarea evenimentelor sale nu poate fi închisa cu
butonul standard marcat cu 'x' din coltul dreapta sus si nici cu combinatia de taste Alt+F4. Pentru a realiza
acest lucru trebuie interceptat evenimentul de închidere a ferestrei în metoda windowClosing si apelata apoi
metoda dispose de închidere a ferestrei, eventual umata de iesirea din program, în cazul când este vorba de
fereastra principala a aplicatiei. Aceasta înseamna ca trebuie sa implementam interfata WindowListener
care are nu mai putin de sapte metode.

//Crearea unei ferestre cu ascultarea evenimentelor sale


//folosind implementarea directa a interfetei WindowListener

import java.awt.*;
import java.awt.event.*;

class Fereastra extends Frame implements WindowListener {


public Fereastra(String titlu) {
super(titlu);
this.addWindowListener(this);
}

//metodele interfetei WindowListener


public void windowOpened(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
dispose(); //inchid fereastra
System.exit(0); //termin programul
}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
}
public class TestWindowListener {
public static void main(String args[]) {
Fereastra f = new Fereastra("O fereastra");
f.show();
}
}
Observati ca trebuie sa implementam toate metodele interfetei, chiar daca nu scriem nici un cod
pentru ele. Singura metoda care ne intereseaza este windowClosing în care specificam ce trebuie facut
atunci când utilizatorul doreste sa închida fereastra.
Pentru a evita scrierea inutila a acestor metode exista o serie de clase care implementeaza
interfetele de tip "listener" fara a specifica nici un cod pentru metodele lor. Aceste clase se numesc
adaptori.

Folosirea adaptorilor
Un adaptor este o clasa abstracta care implementeaza o interfata de tip "listener". Scopul unei
astfel de clase este ca la crearea unui "ascultator" de evenimente, în loc sa implementam o anumita interfata
si implicit toate metodele sale, sa extindem adaptorul corespunzator interfetei respective (daca are!) si sa
supradefinim doar metodele care ne intereseaza (cele în care vrem sa scriem o anumita secventa de cod).
De exemplu, adaptorul interfetei WindowListener este WindowAdapter iar folosirea acestuia este data în
exemplul de mai jos:

//Crearea unei ferestre cu ascultarea evenimentelor sale


//folosind extinderea clasei WindowAdapter

import java.awt.*;
import java.awt.event.*;

class Fereastra extends Frame {


public Fereastra(String titlu) {
super(titlu);
this.addWindowListener(new Ascultator());
}
}

class Ascultator extends WindowAdapter {


//suprdefinim metodele care ne intereseaza
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
Avantajul clar al acestei modalitati de tratare a evenimentelor este reducerea codului programului,
acesta devenind mult mai usor lizibil. Insa exista si doua dezavantaje majore. Dupa cum ati observat, fata
de exemplul anterior clasa "Fereastra" nu poate extinde WindowAdapter deoarece ea extinde deja clasa
Frame (In Java mostenirea multipla nu este acceptata) si din acest motiv am construit o noua clasa numita
"Ascultator". Vom vedea însa ca acest dezavantaj poate fi eliminat prin folosirea unei clase interne.
Un alt dezavantaj este ca orice greseala de sintaxa în declararea unei metode a interfetei nu va
produce o eroare de compilare dar nici nu va supradefini metoda interfetei ci, pur si simplu, va crea o
metoda a clasei respective.
class Ascultator extends WindowAdapter {
// in loc de windowClosing scriem WindowClosing
// nu supradefinim vreo metoda a clasei WindowAdapter
// nu da nici o eroare
// nu face nimic !
public void WindowClosing(WindowEvent e) {
System.exit(0);
}
}

Folosirea claselor interne (anonime)


Stim ca o clasa interna este o clasa declarata în cadrul altei clase iar clasele anonime sunt acele
clase interne folosite doar pentru instantierea unui singur obiect de acel tip. Un exemplu tipic de folosire a
lor este instantierea adaptorilor direct în corpul unei clase care contine componente ale caror evenimente
trebuie interceptate. Clasa "Fereastra" din exemplul anterior poate fi scrisa astfel:
class Fereastra extends Frame {
public Fereastra(String titlu) {
super(titlu);
this.addWindowListener(new WindowAdapter() {
//corpul clasei anonime
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
Observati cum codul programului a fost redus substantial prin folosirea unui adaptor si a unei clase
anonime.

import java.awt.*;
import java.awt.event.*;

public class Tratare extends Frame


{
private TextArea text;
private Button scrie;

public Tratare(String titlu)


{
super(titlu);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

desenare();

public void desenare()


{
text=new TextArea(10,30);
add(text, BorderLayout.NORTH);

scrie = new Button("Scrie");


scrie.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {text.setText("A fost apasat butonul
Scrie");}
});
add(scrie, BorderLayout.SOUTH);

pack();
setVisible(true);
}

public static void main(String args[])


{
new Tratare("Fereastra mea");
}
}
//---------------------

import java.awt.*;
import java.awt.event.*;

public class TestMenu extends Frame implements ItemListener, ActionListener


{
private Frame f;
private MenuBar mb;
private Menu fisier, optiuni,help;
private Button scrie;

public TestMenu(String titlu)


{
super(titlu);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

desenare();
}

public void actionPerformed(ActionEvent e)


{
String command = e.getActionCommand();
if (command.equals("Exit")) System.exit(0);
//valabila si pentru meniu si pentru buton
if (command.equals("Help")) new Fer_dialog(this,"Fereastra Diaog",true);

public void itemStateChanged(ItemEvent e) {


if (e.getStateChange() == ItemEvent.SELECTED)
setTitle("Checked!");
else
setTitle("Not checked!");

public void desenare()


{
creare_meniu();
setBackground(Color.lightGray);
setMenuBar(mb);
pack();
setVisible(true);
}

public void creare_meniu()


{
mb = new MenuBar();
Menu test = new Menu("Test");
CheckboxMenuItem check = new CheckboxMenuItem("Check me");
test.add(check);
test.addSeparator();
test.add(new MenuItem("Exit"));
mb.add(test);

Menu help = new Menu("Help");


MenuItem help1 = new MenuItem("Help");
help.add(help1);
help1.addActionListener(this);
mb.add(help);

Button btnExit = new Button("Exit");


// btnExit.setActionCommand("A");
setMenuBar(mb);

add(btnExit, BorderLayout.SOUTH);
setSize(300, 200);
setVisible(true);

test.addActionListener(this);
check.addItemListener(this);
btnExit.addActionListener(this); }

public static void main(String args[])


{
new TestMenu("Fereastra mea");
}
}

class Fer_dialog extends Dialog {

public Fer_dialog(TestMenu parinte, String titlu, boolean modala) {


super(parinte, titlu, modala);
Panel panou = new Panel();
Button inchidere = new Button("Close");
inchidere.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
panou.add(inchidere,BorderLayout.SOUTH);
add(panou,BorderLayout.SOUTH);
int w=320;
int h=130;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setSize(w,h);
setLocation(screenSize.width/2 - w/2, screenSize.height/2 - h/2);// se fixeaza
setVisible(true);
}
}
Laborator 8
Clasa Dialog
Toate interfetele grafice ofera un tip special de ferestre destinate preluarii datelor de la utilizator.
Acestea se numesc ferestre de dialog sau casete de dialog si sunt implementate prin intermediul clasei
Dialog, subclasa directa a clasei Window.
Diferenta majora între ferestrele de dialog si ferestrele normale (obiecte de tip Frame) consta în
faptul ca o fereastra de dialog este dependenta de o alta fereastra (normala sau tot fereastra dialog), numita
si fereastra parinte. Cu alte cuvinte, ferestrele de dialog nu au o existenta de sine statatoare.
Când fereastra parinte este distrusa sunt distruse si ferestrele sale de dialog, când este minimizata
ferestrele sale de dialog sunt facute invizibile iar când este maximizata acestea sunt aduse la starea în care
se gaseau în momentul minimizarii ferestrei parinte.
Ferestrele de dialog pot fi de doua tipuri:
• modale: care blocheaza accesul la fereastra parinte în momentul deschiderii lor - de exemplu,
ferestre de introducere a unor date, de alegere a unui fisier în vederea deschideriii, de selectare a
unei optiuni, mesaje de avertizare, etc;
• nemodale: care nu blocheaza fluxul de intrare catre fereastra parinte - de exemplu, ferestrele de
cautare a unui cuvânt într-un fisier.
Implicit o fereastra de dialog este nemodala si invizibila.
Constructorii clasei Dialog sunt:
Dialog(Frame parinte)
Dialog(Frame parinte, String titlu)
Dialog(Frame parinte, String titlu, boolean modala)
Dialog(Frame parinte, boolean modala)
Dialog(Dialog parinte)
Dialog(Dialog parinte, String titlu)
Dialog(Dialog parinte, String titlu, boolean modala)
unde "parinte" reprezina o instanta ferestrei parinte, "titlu" reprezinta titlul ferestrei iar prin argumentul
"modala" specificam daca fereastra de dialog creata va fi modala (true) sau nemodala (false - valoarea
implicita).
Pe lânga metodele mostenite de la superclasa Window clasa Dialog mai contine metodele:
boolean isModal() ---- Determina daca fereastra de dialog este modala sau nu.
void setModal(boolean modala) ---- Specifica tipul ferestrei de dialog: modala (true) sau
nemodala (false)
Crearea unei ferestre de dialog este relativ simpla si se realizeaza prin crearea unei clase care sa
extinda clasa Dialog. Mai complicat este însa modul în care se implementeaza comunicarea între fereastra
de dialog si fereastra parinte, pentru ca aceasta din urma sa poata folosi datele introduse (sau optiunea
specificata) în caseta de dialog. Exista doua abordari generale :
• obiectul care reprezinta dialogul poate sa capteze evenimentele de la componentele de pe suprafata
sa si sa sa seteze valorile unor variabile ale ferestrei parinte în momentul în care dialogul este
încheiat
• obiectul care creeaza dialogul (fereastra parinte) sa se înregistreze ca ascultator al evenimentelor
de la butoanele care determina încheierea dialogului, iar fereastra de dialog sa ofere metode
publice prin care datele introduse sa fie preluate din exterior.
import java.awt.*;
import java.awt.event.*;

class FerPrinc extends Frame implements ActionListener{


public FerPrinc(String titlu) {
super(titlu);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void initializare() {
setLayout(new FlowLayout());
setSize(300,100);
setBackground(Color.red);
Button b1 = new Button("Buton1");
add(b1);
Button b2 = new Button("Buton2");
add(b2);
b1.addActionListener(this);
b2.addActionListener(this);
}

//metoda interfetei ActionListener


public void actionPerformed(ActionEvent e) {
String buton = e.getActionCommand();
if (buton.equals("Buton1")) new Avertizare(this, "Titlu 1", true, 1);
//astept sa se inchida fereastra modala de dialog
if (buton.equals("Buton2")) new Avertizare(this, "Titlu 2", false,2);
}
}

//fereastra de dialog
class Avertizare extends Dialog {
String string;
public Avertizare(FerPrinc parinte, String titlu, boolean modala, int k) {
super(parinte, titlu, modala);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
if (k==1) {string = new String("S-a apasat butonul 1");}
if (k==2) {string = new String("S-a apasat butonul 2");}

Panel mesaj = new Panel();


mesaj.add(new Label(string),BorderLayout.CENTER);

Panel panou = new Panel();


Button inchidere = new Button("Close");
inchidere.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
panou.add(inchidere,BorderLayout.SOUTH);

add(mesaj,BorderLayout.NORTH);
add(panou,BorderLayout.SOUTH);

int w=320;
int h=130;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setSize(w,h);
setLocation(screenSize.width/2 - w/2, screenSize.height/2 - h/2);// se fixeaza
setVisible(true);
}
}
//clasa principala
public class TestDialog {
public static void main(String args[]) {
FerPrinc f = new FerPrinc("Fereastra principala");
f.initializare();
f.setVisible(true);
}
}

Clasa FileDialog
Pachetul java.awt pune la dispozitie si un tip de fereastra de dialog folosita pentru încarcarea /
salvarea fisierelor : clasa FileDialog, subclasa directa a clasei Dialog. Instantele acestei clase au un
comportament comun dialogurilor de acest tip de pe majoritatea platformelor de lucru, dar forma în care
vor fi afisate este specifica platformei pe care ruleaza aplicatia.
Constructorii clasei sunt:
FileDialog(Frame parinte)
FileDialog(Frame parinte, String titlu)
FileDialog(Frame parinte, String titlu, boolean mod)
unde "parinte" reprezina o instanta ferestrei parinte, "titlu" reprezinta titlul ferestrei iar prin argumentul
"mod" specificam daca încarcam sau salvam un fisier; valorile pe care le poate lua acest argument sunt
FileDialog.LOAD (pentru încarcare), respectiv FileDialog.SAVE (pentru salvare).
//dialog pentru incarcarea unui fisier
new FileDialog(mainWin, "Alegere fisier", FileDialog.LOAD);
//dialog pentru salvarea unui fisier
new FileDialog(mainWin, "Salvare fisier", FileDialog.SAVE);
La crearea unui obiect FileDialog acesta nu este implicit vizibil. Daca afisarea sa se face cu show
caseta de dialog va fi modala. Daca afisarea se face cu setVisible(true) va fi nemodala. Dupa selectarea
unui fisier ea va fi facuta automat invizibila.
Pe lânga metodele mostenite de la superclasa Dialog clasa FileDialog mai contine metodele:
Afla/specifica directorul din care se va face selectia fisierului sau
String getDirectory()
în care se va face salvare. Sunt permise si notatii specifice pentru
void setDirectory(String dir)
directorul curent (.), directorul radacina (/), etc.
String getFile() Returneaza numele fisierului selectat. Stabileste numele implicit al
void setFile(String f) fisierului care va aparea în caseta de dialog
Afla/specifica filtrul care se va aplica fisierelor din directorul din
FilenameFilter getFilenameFilter() care se va face selectia fisierului sau în care se va face salvare
void setFilenameFilter(FilenameFilter f) (vezi interfata FilenameFilter" ) Nu functioneaza pe platformele
Windows !
Afla/specifica daca încarcam sau salvam un fisier;
int getMode()
• FileDialog.LOAD (pentru încarcare)
void setMode(int mod)
• FileDialog.SAVE (pentru salvare)

Sa consideram un exemplu în care vom alege, prin intermediul unui obiect FileDialog, un fisier cu
extensia "java". Directorul initial este directorul curent, iar numele implicit este TestFileDialog.java.
Numele fisierului ales va fi afisat la consola.

import java.awt.*;
import java.awt.event.*;
import java.io.*;

class FerPrinc extends Frame implements ActionListener{

public FerPrinc(String titlu) {


super(titlu);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void initializare() {
setLayout(new FlowLayout());
setSize(300, 100);

Button b = new Button("Alege fisier");


add(b);
b.addActionListener(this);
}

//metoda interfetei ActionListener


public void actionPerformed(ActionEvent e) {
FileDialog fd = new FileDialog(this, "Alegeti un fisier", FileDialog.LOAD);
//stabilim directorul curent
fd.setDirectory(".");

//numele implicit
fd.setFile("TestFileDialog.java");

//specificam filtrul
fd.setFilenameFilter(new FilenameFilter() {
public boolean accept(File dir, String numeFis) {
return (numeFis.endsWith(".java"));
}
});
fd.setVisible(true); //facem vizibila fereastra de dialog

System.out.println("Fisierul ales este:" + fd.getFile());


}
}

public class TestFileDialog {


public static void main(String args[]) {
FerPrinc f = new FerPrinc("Fereastra principala");
f.initializare();
f.setVisible(true);
}
}
Laborator 9
Procese externe lansate din Java
Facilitatile independente de platforma oferite de limbajul Java sunt completate de posibilitatea
utilizarii de cod extern, specific platformei. Astfel, limbajul Java permite lansarea in executie din interiorul
unui program, a unei aplicatii executabile externe JVM. De exemplu se poate lansa un fisier de tip .bat sau.
Exe sub Windows sau un fisier shell sub Unix. Interfata de executie a unor comenzi externe din programe
Java este realizata cu ajutorul metodei statice exec, din clasa Runtime. Exista patru variante de apel ale
acestei metode, si anume:

public Process exec (String command) ;


public Process exec (String[ ] cmdArray) ;
public Process exec (String command, String[ ] envp) ;
public Process exec (String[ ] cmdArray, String[ ] envp) ;

Metoda exec primeste ca parametru un sir sau mai multe siruri de caractere care reprezinta
caomanda (comenzile) externa(e) de executat. Daca este prezent al doilea parametru, acest sir contine
setarile variabilelor de mediu, sub forma nume=valoare.
Meroda exec lanseaza un thread separat pentru executia comenzii (comenzilor) respective si
returneaza un obiect de tip Process, asociat procesului astfel creat in sistem. Daca aplicatia lansata din
programul Java are nevoie de date de intrare, acestea sunt transmise aplicatiei externe cu ajutorul obiectului
OutputStream, atasat obiectului Process.

OutputStream getOutputStream();

Similar eventualele date de iesire ale aplicatiei, se pot obtine folosind obiectul InputStream al
aceluiasi obiect Process.

InputStream getInputStream();

Se recomanda ca inainte de a obtine rezultatele aplicatiei, sa se astepte terminarea procesului creat


folosind metoda waitFor(), din clasa Process. De asemenea cosul de retur al aplicatiei se poate obtine cu
ajutorul metodei exitValue(). Daca intregul intors are valoarea 0, atunci aplicatia s-a terminat cu succes,
altfel a aparut o eroare.

import java.io.*;

/*
exec: Executa comanda, intorcandu-se imediat chiar daca comanda
se mai executa
execWait: Executa comanda, dar nu se intoarce decat daca comanda este
executata (pt mai multe comenzi dependente una de cealalta)
*/

public class Exec {

public static boolean exec(String command) { return(exec(command, false)); }

public static boolean execWait(String command) { return(exec(command, true)); }

private static boolean exec(String command,boolean wait)


{
try{
Process p = Runtime.getRuntime().exec(command);
if (wait) {
int returnVal = p.waitFor();
if (returnVal != 0) {return(false);}// 0 este terminare cu succes
}
} catch (Exception e) {return(false);}
return(true);
}
}

//---------------------------------------------------------------------------

public class ExecTest


{
public static void main(String[] args) {
Exec.exec("explorer");
Exec.exec("fis.bat");
Exec.execWait("javac Test.java");
Exec.exec("java Test");
}
}

Iata si sursa posibila a fisierului fis.bat

help
pause
dir
pause
edit
pause

//---------------------------------------------------------------------------

Interfaţa FilenameFilter
Listing 5: Listarea fişierelor cu o anumită extensie
/* Listarea fisierelor din directorul curent
care au anumita extensie primita ca argument .
Daca nu se primeste nici un argument , vor fi listate toate .
*/
import java .io .*;
class Listare
{
public static void main ( String [] args )
{
try {
File director = new File (".");
String [] list ;
if ( args . length > 0) list = director . list ( new Filtru ( args [0]) );
else list = director . list ();
for (int i = 0; i < list . length ; i ++) System . out. println ( list [i]);
} catch ( Exception e) {e. printStackTrace ();}
}
}
class Filtru implements FilenameFilter
{
String extensie ;
Filtru ( String extensie )
{
this.extensie = extensie ;
}
public boolean accept ( File dir , String nume )
{
return ( nume.endsWith ("." + extensie ) );
}
}
Laborator 10

Fire de execuţie (thread-uri)


Crearea unui thread
API-ul Java permite crearea unui thread în două moduri: implementând o clasă derivată din clasa
predefinită java.lang.Thread sau definind o clasă care implementează interfaţa Runnable.

Subclasă a clasei Thread


În interiorul unei clase derivate din clasa Thread se redefineşte metoda run(), metodă care conţine
corpul de instrucţiuni a thread-ului. După aceea se poate defini şi instanţia noua subclasă. Schematic avem:

class MyThread extends Thread{


// datele subclasei
MyThread(/*parametrii constructorului*/){
//corpul constructorului
}
public void run(){
//corpul thread-ului MyThread
}
}

Crearea şi lansare în execuţie se va face astfel:

MyThread thr=new MyThread(*/parametrii*/);


thr.start();

Clasa Thread conţine trei câmpuri statice MIN_PRIORITY, NORM_PRIORITY,


MAX_PRIORITY care indică prioritatea firelor de execuţie. Un fir de execuţie poate avea o prioritate între
valorile MIN_PRIORITY şi MAX_PRIORITY. La partea de metode avem:

public Thread()
public Thread(Runnable target)
public Thread(ThreadGroup group, Runnable target)
public Thread(String name)
public Thread(ThreadGroup group, String name)
public Thread(Runnable target, String name)
public Thread(ThreadGroup group, Runnable target, String name)

Dacă se specifică în constructor un obiect ţintă, atunci corpul thread-ului (corpul metodei run) este
ataşat acestui obiect. Dacă nu se specifică atunci corpul este ataşat thread-ului nou creat.
public static Thread currentThread() - intoarce thread-ul curent.
public static yield() - cedeaza controlul de la obiectul thread la planificatorul JVM, pentru a permite unui alt
thread sa ruleze
public static void sleep(long millis) throws InterruptedException
public static void sleep(long millis, int nanos) throws InterruptedException - pune thread-ul respective in
asteptare un anumit interval de timp
public void start() - lansează în executie noul thread
public void run() - conţine instructiunile thread-ului curent descrisă prin suprascrierea acestei metode. Întreaga
activitate curentă a thread-ului trebuie descrisa prin suprascrierea acestei metode
public void interrupt() - trimite o întrerupere obiectului thread care o apeleaza
public static boolean interrupted()
public boolean isInterrupted() - testează dacă thread-ul curent a fost interrupt sau nu; diferenta dintre cele doua
metode este ca prima modifica starea de intrerupere pe cand a doua nu
public void destroy() - distruge un thread fără operaţii de curăţire. Metoda nu este implementată.
public final boolean isAlive() - răspunde dacă obiectul thread a
public final void setPriority(int newPriority) - setează prioritatea thread-ului.
public final int getPriority() - intoarce prioritatea thread-ului curent
public final void setName(String String name)
public final getName() - setează respectiv returnează numele thread-ului
public final ThreadGroup getThreadGroup() - intoarce grupul curent de thread-uri.
public static int activeCount() - intoarce numărul de thread-uri active
public static int enumerate(Thread [] tarray) - intoarce într-un tablou thread-urile member ale grupului curent şi
ale celor din subgrupuri.
public final void join(long millis) throws InterruptedException
public final void join(long millis, int nanos) throws InterruptedException
public final void join()throws InterruptedExcep - aşteaptă ca obiectul thread care le apelează să se termine.
Ultimele două metode limitează timpul maxim de asteptare
public static void dumpStack() - afişează la ieşirea standard stiva curenta de thread-uri
public final void setDaemon(boolean on)
public final boolean isDaemon() - un thread are statut de daemon daca metoda lui contine un ciclu infinit si
daca programatorul doreşte ca acest thread să nu se termine când se termină thread-ul parinte
setDaemon() - apelată imediat înainte de start, conferă această calitate thread-ului.
isDaemon() - răspunde dacă thread-ul respectiv este daemon sau nu.
public String toString() - intoarce reprezentarea textuala a obiectului Thread
public final void wait()throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
public final void wait(long timeout) throws InterruptedException – obiect in asteptare pana la aparitia unui
eveniment
public final void notify()
public final void notifyAll() - sunt duale metodei wait(), ele anunta alte obiecte de apariţia unui eveniment.

Implementarea interfetei Runnable

class MyThread implements Runnable{


// datele subclasei
MyThread(/*parametric*/){
//corpul constructorului
}
public void run(){
//corpul thread-ului
}
}

Crearea şi lansare în execuţie se va face astfel:

Thread thr=new Thread(MyThread);


thr.start();
Interfata Runnable contine doar o singura metoda
public void run() -codul acesteia reprezinta programul de executie a thread-ului asociat ei

Exemplu 1

// clasa care genereaza atâtea thread-uri câte argumente primeste.

class Many extends Thread


{
//fiecare thread scrie 'info' de 'retry' ori
int retry;
String info;

public Many(int retry, String info)


{
this.retry = retry;
this.info = info;
}

public void run () {


for (int n= 0; n<retry; n++)
work();
quit();
}

void work() { System.out.println(info); }

void quit(){ System.out.println("\n"); }

public static void main(String[] args)


{
for (int n = 0; n < args.length; n++)
new Many(args.length,args[n]).start();
}
}

Exemplu 2

// aceeasi clasa de data asta thread-urile avand prioritate diferita

class Many extends Thread


{
//fiecare thread scrie 'info' de 'retry' ori
int retry;
String info;

public Many(int retry, String info)


{
this.retry = retry;
this.info = info;
setPriority(MIN_PRIORITY + (int)(Math.random() * (MAX_PRIORITY -
MIN_PRIORITY)));
}

public void run () {


for (int n= 0; n<retry; n++)
work();
quit();
}

void work() { System.out.println(info); }

void quit(){ System.out.print("Priority: "+getPriority()+'\n'); }

public static void main(String[] args)


{
for (int n = 0; n < args.length; n++)
new Many(args.length,args[n]).start();
}
}

JVM executa un thread sip e cele create de acesta, pana cand apare una din urmatoarele situatii:
• este apelata metoda exit() a clasei Runtimr, iar manager-ul de securitate a permis indeplinirea cu
succes a acestui apel
• toate thread-urile care un sunt daemon s-au terminat, fie prin intoarcere din apelul metodei run(), fie
printr-un apel al metodei stop() din partea altui thread, fie prin trimiterea de intreruperi din partea altui thread
(interrupt()).
• S-a incocat metoda stop() a obiectului threas (deprecated)

Daca se doreste asteptarea terminarii unui thread se poate folosi metoda join() a obiectului thread dupa care se
asteapta. Thread-ul a carui terminare se asteapta un este afectat de acest apel. Apelul this.join(), inseamna ca threas-ul
curent un se va termina niciodata, datorita acestui apel in asteptare. Functia join() apelata pt un thread care un si-a
inceput executia un s-a terminat, returneaza fara sa astepte.

Sincronizarea firelor de executie


Sa consideram urmatoarea situatie:
• Producstorul genereaza numerele întregi de la 1 la 10, fiecare la un interval neregulat cuprins între 0 si 100 de
milisecunde. Pe masura ce le genereaza încearca sa le plaseze într-o zona de memorie (o variabila întreaga) de
unde sa fie citite de catre consumator.
• Consumatorul va prelua, pe rând, numerele generate de catre producator si va afisa valoarea lor pe ecran.
Pentru a fi accesibila ambelor fire de executie, vom încapsula variabila ce va contine numerele generate într-un
obiect descris de clasa Buffer si care va avea doua metode put (pentru punerea unui numar în buffer) si get (pentru
obtinerea numarului din buffer).

Exemplu 3
/* aceasta este varianta nesincronizata a clasei Buffer

class Buffer {
private int number = -1;

public int get() {


return number;
}

public void put(int number) {


this.number = number;
}
}
*/

//aceasta este varianta sincronizata a clasei Buffer


class Buffer {
private int number = -1;
private boolean available = false;
public synchronized int get() {
while (!available) {
try {
wait();
//asteapta producatorul sa puna o valoare
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return number;
}
public synchronized void put(int number) {
while (available) {
try {
wait();
//asteapta consumatorul sa preia valoarea
} catch (InterruptedException e) { }
}
this.number = number;
available = true;
notifyAll();
}
}

class Producator extends Thread {


private Buffer buffer;
public Producator(Buffer b) {
buffer = b;
}
public void run() {
for (int i = 0; i < 10; i++) {
buffer.put(i);
System.out.println("Producatorul a pus:\t" + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}

class Consumator extends Thread {


private Buffer buffer;
public Consumator(Buffer b) {
buffer = b;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = buffer.get();
System.out.println("Consumatorul a primit:\t" + value);
}
}
}

//Clasa principala
public class TestSincronizare1 {
public static void main(String[] args) {
Buffer b = new Buffer();
Producator p1 = new Producator(b);
Consumator c1 = new Consumator(b);
p1.start();
c1.start();
}
}

Un segment de cod ce gestioneaza o resursa comuna mai multor de fire de executie separate si concurente se
numeste sectiune critica. In Java o sectiune critica poate fi un bloc de instructiuni sau o metoda.
Controlul accesului într-o sectiune critica se face prin cuvântul cheie synchronized. Platforma Java
asociaza un monitor fiecarui obiect al unui program ce contine sectiuni critice care necesita sincronizare. Acest monitor
va indica daca resursa critica este accesata de vreun fir de executie sau este libera, cu alte cuvinte "monitorizeaza" o
resursa critica. In cazul în care este accesata, va "pune un lacat" pe aceasta, astfel încât sa împiedice accesul altor fire de
executie la ea. In momentul când resursa este eliberata "lacatul" va fi eliminat pentru a permite accesul altor fire de
executie.
In exemplul tip producator/consumator de mai sus, sectiunile critice sunt metodele put si get iar resursa
citica comuna este obiectul buffer. Consumatorul nu trebuie sa acceseze buffer-ul când producatorul tocmai pune o
valoare în el, iar producatorul nu trebuie sa modifice valoarea din buffer în momentul când aceasta este citita de catre
consumator.
Proiecte Java
1. Realizarea unei aplicaţii de tip Wordpad folosind biblioteca awt. Aplicatia va trebui sa extinda clasa Frame si sa aiba
toate facilitatile facilităţile necesare in editarea unui document.
Cerinte minimale:
• interfaţă grafica
• creare, deschidere, salvare pe disc a fişierelor (extensie .txt şi .doc) => se vor folosi ferestre dialog.
• posibilitate de a schimba marimea caracterelor, culoare şi fontul
• existenţa meniurilor şi a barei de instrumente
• posibilitatea de a folosi Copy, Cut, Paste eventual şi numai folosind tastatura
• posibilitatea imprimarii documentului curent
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: TextArea, Event, awt, swing

2. Realizarea unei aplicaţii de tip IrfanView sau ACDsee. Aplicaţia poate fi construita si standalone si ca applet, după
preferintă.
Cerinte minimale:
• interfaţă grafica
• posibilitate de a specifica folder-ul de pe disk de unde se vor încărca imaginile
• posibilitate de a mari sau micşora imaginea (zoom)
• butoane pentru nevigare în cadrul imaginilor din folderul curent (previous&next)
• posibilitatea imprimării documentului curent
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: Image, Panel, Event, awt, swing

3. Realizarea unei aplicaţii de tip Paint folosind biblioteca awt. Aplicatia va trebui sa extinda clasa Frame si să aiba
toate facilitatile facilităţile necesare creării unor imagini.
Cerinte minimale:
• interfaţă grafica
• posibilitate salvare imagini cu extensia .bmp, .jpg, .gif (se vor folosi ferestre dialog)
• existenţa meniurilor şi a barei de instrumente
• bara de instrumente să includă următoarele elemente funcţionabile (pencil, brush, eraser, fill with color, line,
rectangle, ellipse, text)
• posibilitatea imprimării documentului curent
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: Canvas, Graphics, Event, awt, swing

4. Realizarea unei aplicaţii de tip Agendă telefonică. Aplicaţia poate fi construita si standalone si ca applet, după
preferintă. Înregistrarea pentru o persoană să conţină nume, prenume, ocupaţia, telefon fix-mobil-serviciu, data naşterii,
adresa reşedinţă, adresa servici, şi poză (dacă este disponibilă)

Cerinte minimale:
• interfaţă grafica
• păstrarea înregistrărilor pe disc într-un fişier text sau pentru punctaj în plus într-o bază de date relaţională
• implementarea principalelor operaţiuni: adăugare, ştergere, modificare, căutare
• butoane pentru nevigare în cadrul inregistrărilor (previous&next)
• posibilitatea imprimării înregistrărilor despre o anumită persoană
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: Image, Event, awt

5. Reimplementarea jocului Minesweeper din jocurile sistemelor Windows


Cerinte minimale:
• interfaţă grafica
• copierea jocului într-un mod cât mai fidel
• să existe posibilitatea de a alege cât de mare să fie suprfaţa jocului şi implicit câte mine să fie pe câmpul de joc
• locul unde va fi plasat minele va fi generat aleator
• nu este neaparat ca să fie implementată şi facilitatea de a se ară ta unde pot fi situate minele la apăsarea
concomitentă a celor două butoane ale mouse-ului
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: Image, Event, awt

6. Realizarea unui magazin virtual. . Aplicaţia poate fi construita si standalone si ca applet, după preferintă.
Cerinte minimale:
• interfaţă grafica
• crearea unei clase care să reprezinte căruciorul de cumpărături (cart-ul)
• clasă care să ia datele unui client (eventual dintr-un formular)
• datele reţinute pe disc sau pentru punctaj în plus într-o bază de date relaţională
• posibilitatea imprimării înregistrărilor despre o anumită persoană şi cumpărăturile sale
• plata se va face printr-un mandat poştal
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: sql, awt

7. Scrieti un program care sa simuleze un 'shell' pentru lucrul cu fisiere (Total Commander).
Cerinţe minimale:
• interfaţă grafica
• listarea fisierelor dintr-un director sau directorul curent
• listarea continutului unui fisier
• schimbarea directorului curent
• crearea unui nou director
• stergerea/redenumirea unui fisier/director
• aflarea informatiilor despre un fisier/director
• execuţia unui program
• deschiderea unui fişier folosind programul setat implicit
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: File, Event, sql, awt
8. Scrieti o aplicatie care gestioneaza un mini-dictionar român - englez.
Cerinţe minimale:
• interfaţă grafica
• adaugarea, stergerea, căutarea de definitii
• folositi clasa HashMap pentru reprezentarea dictionarului.
• salvarea dictionarului pe disc (format la alegere => bază de date, htm, txt )
• posibilitatea de a incarca dicţionarul in memorie dar şi a căuta direct pe disc în fişierul unde a fost
memorat
• tratare de excepţii
• alte facilităţi
A se citi în help documentaţia pt clasele şi pachetele: Collection, HashMap, Event, sql, awt

S-ar putea să vă placă și