Download - Medii vizuale
-
7/27/2019 Medii vizuale
1/50
Lectia 1 Its more fun to compute
Obiective: Cum demaram un proiect Visual Studio.NET
Integrarea catorva componente intr-o aplicatie vizuala
Completarea codului
Mediul integrat Visual Studio .NET ofera o larga gama de ustensile ce permit crearea rapida de
aplicatii. In aceasta lectie ne propunem sa prezentam pasii ce trebuie urmati in crearea unei aplicatii
utilizand Visual Studio.NET.
Imediat dupa lansarea Visual Studio.NET, putem demara crearea unui proiect (figura 1) si selectiona
limbajul ales pentru implementarea aplicatiei (figurile 2,3,4).
Figura 1- Deschiderea unui nou proiect Figura 2 Alegem Visual Basic...
Figura 3 ...Visual C#... Figura 4 sau Visual J#?
Avand in vedere ca Java este unul dintre limbajele cele mai raspandite in mediul academic, vom
alege, si noi, sa implementam proiectele cursului de fata tot in Java, incurajand insa studentii sa
incerce, macar prin analogie, crearea acelorasi proiecte si in limbajele Visual Basic si Visual C#.
-
7/27/2019 Medii vizuale
2/50
Odata confirmat limbajul ales spre implementare, VS.NET afiseaza o interfata grafica (figura 5) in
care programatorul nu trebuie decat sa depuna forme si controale vizuale pentru a realiza
implementarea aplicatiei.
Figura 5 Contextul vizual al aplicatiei... Figura 6 - ... si interfata cu tot ce trebuie.
Pentru aceasta prima lectie ne propunem sa implementam, nu binecunoscutul Hello world!, ci un
mic motor de calcul pentru determinarea lui n! (reamind ca =
=ni
in,1
! , pentru orice *Nn iar
pentru 0=n , 1!=n prin conventie).
Pentru a asigura interactivitatea aplicatiei cu utilizatorul, aceasta va trebui sa ceara, printr-un
dialog vizual cu utilizatorul, o valoare numerica pozitiva, urmand ca apoi sa afiseze valoareacalculata.
Deci vom avea nevoie de un text explicativ (Label), un loc (TextBox) in care sa specificamvaloarea lui n, un instrument (Button) care sa declanseze calculele si un al doilea loc (TextBox)in care afisam rezultatul calculelor.
Plasarea tuturor acestor elemente in cadrul vizual oferit de VS.NET (Form1) este lasat la liberaalegere a programatorului; o solutie posibila este cea din figura 6. Proprietatile tuturor elementelor
plasate in cadrul vizual pot fi inspectate/modificate prin intermediul ferestrei Properties(dreaptajos). Lista si semnificatia acestor componente este:
label1(Label) textul explicativ,
textBox1(TextBox) locul in care specificam numarul n, button1(Button) instrumentul care declanseaza calculele, si textBox2(TextBox) locul in care specificam rezultatele calculelor
Pe masura ce avansam cu completarea cadrului vizual Form1, VS.NET genereaza si actualizeaza un
fisier corespunzator, avand denumirea form1.jsl (sau form1.vb in cazul utilizarii Visual
Basic, respectiv form1.csin cazul utilizarii Visual C#).
-
7/27/2019 Medii vizuale
3/50
packageWindowsApplication3;
importSystem.Drawing.*;importSystem.Collections.*;
importSystem.ComponentModel.*;importSystem.Windows.Forms.*;importSystem.Data.*;
/*** Summary description for Form1.*/
publicclassForm1 extendsSystem.Windows.Forms.Form{
privateSystem.Windows.Forms.Label label1;privateSystem.Windows.Forms.TextBox textBox1;
privateSystem.Windows.Forms.Button button1;privateSystem.Windows.Forms.TextBox textBox2;
/*** Required designer variable.*/
privateSystem.ComponentModel.Container components = null;
publicForm1(){
//
// Required for Windows Form Designer support//InitializeComponent();
//// TODO: Add any constructor code after InitializeComponent call//
}
/*** Clean up any resources being used.
*/protectedvoidDispose(booleandisposing){
if(disposing){
if(components != null){
components.Dispose();
-
7/27/2019 Medii vizuale
4/50
}}super.Dispose(disposing);
}
#regionWindows Form Designer generated code/**
* Required method for Designer support - do not modify* the contents of this method with the code editor.*/
privatevoid InitializeComponent(){
this.label1 = newSystem.Windows.Forms.Label();this.textBox1 = newSystem.Windows.Forms.TextBox();this.button1 = newSystem.Windows.Forms.Button();this.textBox2 = newSystem.Windows.Forms.TextBox();
this.SuspendLayout();//// label1//this.label1.set_Location(newSystem.Drawing.Point(32, 16));this.label1.set_Name("label1");this.label1.set_Size(newSystem.Drawing.Size(128, 24));this.label1.set_TabIndex(0);this.label1.set_Text("Introduceti un numar:");
//// textBox1
//this.textBox1.set_Location(newSystem.Drawing.Point(152, 16));this.textBox1.set_Name("textBox1");this.textBox1.set_TabIndex(1);this.textBox1.set_Text("textBox1");
//// button1//this.button1.set_Location(newSystem.Drawing.Point(32, 56));this.button1.set_Name("button1");this.button1.set_Size(newSystem.Drawing.Size(224, 23));
this.button1.set_TabIndex(2);this.button1.set_Text("Calculeaza");//// textBox2//this.textBox2.set_Location(newSystem.Drawing.Point(32, 104));this.textBox2.set_Name("textBox2");this.textBox2.set_Size(newSystem.Drawing.Size(224, 20));
-
7/27/2019 Medii vizuale
5/50
this.textBox2.set_TabIndex(3);this.textBox2.set_Text("textBox2");
//// Form1//
this.set_AutoScaleBaseSize(newSystem.Drawing.Size(5, 13));this.set_ClientSize(newSystem.Drawing.Size(292, 273));this.get_Controls().Add(this.textBox2);this.get_Controls().Add(this.button1);this.get_Controls().Add(this.textBox1);this.get_Controls().Add(this.label1);this.set_Name("Form1");this.set_Text("I\'ts more fun to compute");this.ResumeLayout(false);
}
#endregion
/*** The main entry point for the application.*/
/** @attribute System.STAThread() */publicstaticvoidmain(String[] args){
Application.Run(newForm1());}
}
Rularea aplicatiei astfel obtinute conduce la afisarea contextului vizual Form1. Acesta permiteactionarea si interactiunea utilizatorului cu componentele formei fara insa a produce rezultatulscontat; calculul lui n! (figura 7).
Figura 7 Aplicatia ... o carcasa fara continut Figura 8 Aplicatia ... un mic motor de n!
-
7/27/2019 Medii vizuale
6/50
Este si normal sa fie asa deoarece in afara de functiunile vizuale implicit asigurate de catrecomponentele introduse, noi, ca programatori, nu am adaugat nici o semantica relativa la
contextul problemei.
De aceea, pentru a remedia situatia va trebui sa completam functional contextul vizual obtinut. In
acest sens:
introducem doi identificatori in cadrul contextului vizual:o numarretinand numarul introdus de catre utilizator si respectivo factorialpentru a retine rezultatul calculelor.
privateintnumar, factorial;
analizam intrarea utilizatorului prin tratarea evenimentului TextChanged asociat luitextBox1, si incarcam valoarea obtinuta in numar:
privatevoidtextBox1_TextChanged (Object sender, System.EventArgs e){
Integer in=Integer.valueOf(textBox1.get_Text());numar=in.intValue();
}
Pentru a accesa aceasta zona de cod putem fie sa efectuam dublu-click pe componenta in
cauza (in cazul nostru pe textBox1), fie sa selectionam aceasta componenta si sainspectam/utilizam fereastra Propertiesasociata.
declansam calculul factorialului, prin tratarea evenimentului Clickasociat butonului button1in cadrul caruia, in plus, actualizam textBox2cu valoarea nou obtinuta:
privatevoidbutton1_Click (Object sender, System.EventArgs e){
factorial=1;for(inti=1;i
-
7/27/2019 Medii vizuale
7/50
/**
* Summary description for Form1.*/
publicclassForm1 extendsSystem.Windows.Forms.Form
{privateSystem.Windows.Forms.Label label1;privateSystem.Windows.Forms.TextBox textBox1;privateSystem.Windows.Forms.Button button1;privateSystem.Windows.Forms.TextBox textBox2;
privateintnumar, factorial;
/*** Required designer variable.*/
privateSystem.ComponentModel.Container components = null;
publicForm1(){
//// Required for Windows Form Designer support//InitializeComponent();
//// TODO: Add any constructor code after InitializeComponent call
//}
/*** Clean up any resources being used.*/
protectedvoidDispose(booleandisposing){
if(disposing){
if(components != null)
{ components.Dispose();}
}super.Dispose(disposing);
}
#regionWindows Form Designer generated code
-
7/27/2019 Medii vizuale
8/50
/*** Required method for Designer support - do not modify* the contents of this method with the code editor.*/
privatevoid InitializeComponent()
{this.label1 = newSystem.Windows.Forms.Label();this.textBox1 = newSystem.Windows.Forms.TextBox();this.button1 = newSystem.Windows.Forms.Button();this.textBox2 = newSystem.Windows.Forms.TextBox();this.SuspendLayout();
//// label1//this.label1.set_Location(newSystem.Drawing.Point(32, 16));this.label1.set_Name("label1");
this.label1.set_Size(newSystem.Drawing.Size(128, 24));this.label1.set_TabIndex(0);this.label1.set_Text("Introduceti un numar:");
//// textBox1//this.textBox1.set_Location(newSystem.Drawing.Point(152, 16));this.textBox1.set_Name("textBox1");this.textBox1.set_TabIndex(1);this.textBox1.set_Text("textBox1");this.textBox1.add_TextChanged(
new System.EventHandler(this.textBox1_TextChanged));//// button1//this.button1.set_Location(newSystem.Drawing.Point(32, 56));this.button1.set_Name("button1");this.button1.set_Size(newSystem.Drawing.Size(224, 23));this.button1.set_TabIndex(2);this.button1.set_Text("Calculeaza");this.button1.add_Click( newSystem.EventHandler(this.button1_Click) );
//// textBox2//this.textBox2.set_Location(newSystem.Drawing.Point(32, 104));this.textBox2.set_Name("textBox2");this.textBox2.set_Size(newSystem.Drawing.Size(224, 20));this.textBox2.set_TabIndex(3);this.textBox2.set_Text("textBox2");
-
7/27/2019 Medii vizuale
9/50
//// Form1//this.set_AutoScaleBaseSize(newSystem.Drawing.Size(5, 13));this.set_ClientSize(newSystem.Drawing.Size(292, 273));
this.get_Controls().Add(this.textBox2);this.get_Controls().Add(this.button1);this.get_Controls().Add(this.textBox1);this.get_Controls().Add(this.label1);this.set_Name("Form1");this.set_Text("I\'ts more fun to compute");this.ResumeLayout(false);
}#endregion
/*** The main entry point for the application.*/
/** @attribute System.STAThread() */publicstaticvoidmain(String[] args){
Application.Run(newForm1());}
privatevoidbutton1_Click (Object sender, System.EventArgs e){
factorial=1;for(inti=1;i
-
7/27/2019 Medii vizuale
10/50
Lectia 2 Control the controls
Obiective: Utilizarea controalelor
Accesarea proprietatilor controalelor
Top 12 al celor mai utilizate controale
Utilizarea controalelorAsa cum am vazut in lectia anterioara, pentru utilizarea oricarui control Visual J# (si acest lucrueste valabil pentru oricare din limbajele .NET) este suficienta selectarea controlului vizat sideplasarea (prin drag & drop) a acestuia in forma vizuala. Este foarte probabil ca odata aceasta
operatie terminata veti fi nevoiti sa operati la mici ajustari vizuale, de genul dimensiune si pozitie
exacta a controlului.
Toate controalele sunt sensibile, direct sau indirect, la actiunile utilizatorului exprimate prin mouse(click, double-click) dar nu numai. Visual Studio .NETgenereaza automat cod (in fine, contextulcodului, de tratare a evenimentelor produse de utilizator) urmand ca programatorul sa completeze
acest cod cu cod propriu aplicatiei.
Accesarea proprietatilorProprietatile controalelor pot fi accesate fie prin intermediul browser-ului de proprietati fie direct
prin utilizarea metodelor de acces (_get) sau modificare (_set) a controlului.
Figura 8 Un Button selectat si cateva din proprietatile sale afisate (dreapta jos).
In figura 8 se observa selectat obiectul button1 iar in fereastra de proprietati sunt vizibile proprietatile sale. De
exemplu, textul butonului poate fi modificat printr-o linie de cod de genul :
this.button1.set_Text("Calculeaza");
-
7/27/2019 Medii vizuale
11/50
Top 10 al celor mai utilizate controale
Control .NET Class Java Swing
Form System.Windows.Forms.Form JFrame
Label System.Windows.Forms.Label JLabel
Button System.Windows.Forms.Button JButton
TextBox System.Windows.Forms.TextBox JTextArea
CheckBox System.Windows.Forms.CheckBox JCheckBox
ComboBox System.Windows.Forms.ComboBox JComboBox
RadioButton System.Windows.Forms.RadioButton JRadioButton
GroupBox System.Windows.Forms.GroupBox
PictureBox System.Windows.Forms.PictureBox ImageIcon
Panel System.Windows.Forms.Panel JPanel
ListBox System.Windows.Forms.ListBox JList
Figura 9 O interfata plina ... doar de controale.
-
7/27/2019 Medii vizuale
12/50
Label
Labelintroduce un text in cadrul vizual, text ce nu poate fi accesat pentru modificare/deplasare intimpul rularii aplicatiei.
Un astfel de text este caracterizat prin: Font numele fontului, dimensiune, ingrosat, italic.
Text textul efectiv al controlului.
TextAlign alinierea textului, implicit la stanga
Image controlul poate afisa, pe langa text, si o imagine (ca fundal al textului).
Button
Butoanele ocupa primul loc in clasamentul controalelor accesibile prin Mouse.
Afisand un text pe control, Buttonmosteneste caracteristicile controlului Label, dar, spre deosebire
de acesta, centreaza textul pe control si, mai important, este accesibil utilizatorului in timpul rulariiaplicatiei. In acest sens, Buttoneste sensibil evenimentelor provenite de la Mouse, cel mai utilizatfiind evenimentul Click.
TextBox
Utilizand un control TextBoxpermitem utilizatorului introducerea de date (de la tastatura) in cadrulvizual al aplicatiei. Uzual, informatia introdusa intr-un TextBoxeste utilizata fie in urma exprimariiacestei intentii de catre utilizator prin intermediul unui Button (Calculeaza in exemplul nostru), fie
datorita tratarii de catre controlul TextBox a evenimentului TextChanged, emis de indata cecontinutul controlului este modificat.
Proprietatile cele mai frecvent accesate ale TextBox vizeaza, bineinteles continutul textual (Text) al
controlului, si anume:
MaxLength specifica lungimea maxima a textului continut de control, cu o lungime maxima
admisibila de 32767 caractere,
Multiline specificarea faptului ca textul se poate intinde pe mai multe linii si implicit permiterea
redimensionarii pe verticala a controlului, PasswordChar campul seteaza caracterul afisat in momentul introducerii textului controlului
(asemeni afisajului utilizat pentru parola utilizatorilor).
CheckBox si RadioButtonIn vederea realizarii unei selectii inclusive sau exclusive, prin bifare, a unei optiuni in cadrul vizual,
se uilizeaza doua controale, CheckBox (pentru selectie inclusiva, indicata prin simbolul v) siRadioButton(pentru selectie exclusiva, indicata prin simbolul ).
Aparitia/disparitia simbolurilor in casutele corespunzatoare se realizeaza prin selectia (repetata) a
aceluiasi control, iar starea actuala a controlului poate fi setata/citita prin intermediul proprietatii
Checked.
-
7/27/2019 Medii vizuale
13/50
GroupBoxGroupBox permite, dupa cum spune si numele, gruparea mai multor butoane (de regulaRadioButton) intr-un singur context vizual (si retinerea tuturor butoanelor intr-o lista proprie,independenta de restul contextelor vizuale).
PanelPanelconstituie un context vizual ce poate gazdui (grupa vizual) o serie de alte controale permitandin acelasi timp o proiectare mai usoara a interfatelor complexe. La fel ca celelalte controale vizuale,
poate fi redimensionat si deplasat. El insa nu gestioneaza componentele plasate in interiorul sau asa
cum o face GroupBox.
ListBox si ComboBox
ListBox (respectiv ComboBox) afiseaza un numar constant (respectiv variabil) de linii deinformatii pe ecran, permitand selectia multipla (respectiv o singura selectie). Obtinerea elementului
selectat se poate face prin apelul metodei getSelectedValues( ) si care produce un sir de String
(respectiv getSelectedValue()).
PictureBoxImaginile pot fi adaugate intr-un context vizual utilizand un control PictureBox atat in scopuridecorative cat si ca element de interactiune. Fisierul de resursa a imaginii, specificat in proprietatea
Image, poate fi un BMP, JPEG sau GIF.
Aceasta imagine poate, si este deseori, redimensionata (direct prin accesul la imagine prin Mouse
sau indirect ca rezultat al redimensionarii contextului vizual). In urma acestei redimensionari,
imaginea este plasata in coltul din stanga-sus al controlului PictureBoxfara nici un fel de ajustare aimaginii si indiferent de dimensiunile controlului, daca proprietatea SizeMode este setata la
Normal. Daca proprietatea SizeModeeste setata la StretchImage, imaginea este ajustata in asa felincat sa ocupe intreg spatiul rezervat controlului, iar daca SizeModeeste AutoSize, dimensiuneacontrolului este ajustata la dimensiunea reala a imaginii sursa. In plus, daca dorim centra imaginea
in control, putem face acest lucru prin utilizarea valorii CenterImage pentru proprietateaSizeMode.
TimerControlul Timer este un exemplu, usor de inteles, de control ce nu are o reprezentare vizuala. Prin
plasarea controlului in contextul vizual al aplicatiei, mediul Visual Studio va afisa un ecran similar
celui din figura 10, devenind astfel vizibil accesul la controlul Timer si la proprietatile acestuia.
Timer are drept scop executia unui cod la intervale de timp regulate. El poate fi activat saudezactivat, prin proprietatea Enabled, putandu-i-se stabili frecventa la care intra in actiune, prin
proprietatea Interval, aceasta fiind exprimata in milisecunde. Accesul la codul corespondent
controlului se face, ca in cazul oricarui alt controler, prin dublu click.
-
7/27/2019 Medii vizuale
14/50
Figura 10 Controlul Timer si fereastra de proprietati asociata.
Aceasta actiune ne conduce in metoda Tick asociata controlului. In exemplul urmator, metoda vaselecta/deselecta un alt control existent deja in contextul vizual al aplicatiei, un obiect de tip
RadioButton, radioButton2.
privatevoidtimer1_Tick (Object sender, System.EventArgs e){
radioButton2.set_Checked(!radioButton2.get_Checked());}
Acelasi obiect timer1 il vom utiliza pentru generarea diferitelor forme geometrice in exemplulurmator.
Elemente de grafica 2D
Pentru a avea acces la facilitatile grafice 2D va trebui sa importam biblioteca
System.Drawing.Drawing2D. Invocand metafora atelierului de creatie, doua concepte suntesentiale in crearea contextului grafic: panza si zona.
Panza (acel Canvasdin Java) este introdusa de aceasta data prin Path, si consta in suprafata pecare se vor realiza reprezentarile figurilor, liniilor, fara insa a avea o reprezentare vizuala pe ecran.
Pe aceasta panza, putem delimita regiunea in care putem desena efectiv, prin Region.
In exemplu de mai jos este utilizat spatiul unui Panel, panel1, ca zona de desenare a diferitelorforme geometrice (figura 11).
-
7/27/2019 Medii vizuale
15/50
Figura 11 Diferite forme geometrice desenate in panel1in diferite momente de timpcontrolate de timer1.
packageWindowsApplication5;
importSystem.Drawing.*;importSystem.Drawing.Drawing2D.*;importSystem.Collections.*;importSystem.ComponentModel.*;importSystem.Windows.Forms.*;
-
7/27/2019 Medii vizuale
16/50
importSystem.Data.*;
/*** Summary description for Form1.*/
publicclassForm1 extendsSystem.Windows.Forms.Form{
privateintcount;privateSystem.Windows.Forms.Label label1;privateSystem.Windows.Forms.TextBox textBox1;privateSystem.Windows.Forms.Button button1;privateSystem.Windows.Forms.CheckBox checkBox1;privateSystem.Windows.Forms.RadioButton radioButton1;privateSystem.Windows.Forms.GroupBox groupBox1;privateSystem.Windows.Forms.RadioButton radioButton2;privateSystem.Windows.Forms.RadioButton radioButton3;
privateSystem.Windows.Forms.ListBox listBox1;privateSystem.Windows.Forms.ComboBox comboBox1;privateSystem.Windows.Forms.PictureBox pictureBox1;privateSystem.Windows.Forms.Panel panel1;privateSystem.Windows.Forms.Label label2;privateSystem.Windows.Forms.Label label3;privateSystem.Windows.Forms.Label label4;privateSystem.Windows.Forms.Timer timer1;privateSystem.ComponentModel.IContainer components;
publicForm1()
{ //// Required for Windows Form Designer support//InitializeComponent();
//// TODO: Add any constructor code after InitializeComponent call//GraphicsPath gPath = newGraphicsPath();gPath.AddRectangle(newSystem.Drawing.Rectangle(new
System.Drawing.Point(0,0),newSystem.Drawing.Size(panel1.get_ClientSize().get_Width(),panel1.get_ClientSize().get_Height())));
//gPath.AddEllipse(0,0,this.get_ClientSize() .get_Width(),this.get_ClientSize().get_Height());
//this.set_Region(new Region(gPath));panel1.set_Region(newRegion(gPath));
-
7/27/2019 Medii vizuale
17/50
count=0;}
/*** Clean up any resources being used.
*/protectedvoidDispose(booleandisposing){
if(disposing){
if(components != null){
components.Dispose();}
}super.Dispose(disposing);
}
#regionWindows Form Designer generated code/**
* Required method for Designer support - do not modify* the contents of this method with the code editor.*/
privatevoid InitializeComponent(){
this.components = newSystem.ComponentModel.Container();System.Resources.ResourceManager resources = new
System.Resources.ResourceManager(Form1.class.ToType());this.label1 = newSystem.Windows.Forms.Label();this.textBox1 = newSystem.Windows.Forms.TextBox();this.button1 = newSystem.Windows.Forms.Button();this.checkBox1 = newSystem.Windows.Forms.CheckBox();this.radioButton1 = newSystem.Windows.Forms.RadioButton();this.groupBox1 = newSystem.Windows.Forms.GroupBox();this.radioButton3 = newSystem.Windows.Forms.RadioButton();this.radioButton2 = newSystem.Windows.Forms.RadioButton();this.listBox1 = newSystem.Windows.Forms.ListBox();this.comboBox1 = newSystem.Windows.Forms.ComboBox();
this.pictureBox1 = newSystem.Windows.Forms.PictureBox();this.panel1 = newSystem.Windows.Forms.Panel();this.label2 = newSystem.Windows.Forms.Label();this.label3 = newSystem.Windows.Forms.Label();this.label4 = newSystem.Windows.Forms.Label();this.timer1 = newSystem.Windows.Forms.Timer(this.components);this.groupBox1.SuspendLayout();this.panel1.SuspendLayout();
-
7/27/2019 Medii vizuale
18/50
this.SuspendLayout();//// label1//this.label1.set_Location(newSystem.Drawing.Point(16, 24));
this.label1.set_Name("label1");this.label1.set_TabIndex(0);this.label1.set_Text("Demo Label");
//// textBox1//this.textBox1.set_Location(newSystem.Drawing.Point(96, 24));this.textBox1.set_Name("textBox1");this.textBox1.set_TabIndex(1);this.textBox1.set_Text("Demo TextBox");
//
// button1//this.button1.set_Location(newSystem.Drawing.Point(248, 24));this.button1.set_Name("button1");this.button1.set_Size(newSystem.Drawing.Size(80, 24));this.button1.set_TabIndex(2);this.button1.set_Text("Demo Button");
//// checkBox1//this.checkBox1.set_Location(newSystem.Drawing.Point(24, 72));
this.checkBox1.set_Name("checkBox1");this.checkBox1.set_Size(newSystem.Drawing.Size(128, 24));this.checkBox1.set_TabIndex(3);this.checkBox1.set_Text("Demo CheckBox");
//// radioButton1//this.radioButton1.set_Location(newSystem.Drawing.Point(152, 72));this.radioButton1.set_Name("radioButton1");this.radioButton1.set_TabIndex(4);this.radioButton1.set_Text("radioButton1");
//// groupBox1//this.groupBox1.get_Controls().Add(this.radioButton3);this.groupBox1.get_Controls().Add(this.radioButton2);this.groupBox1.set_Location(newSystem.Drawing.Point(16, 104));this.groupBox1.set_Name("groupBox1");this.groupBox1.set_Size(newSystem.Drawing.Size(104, 88));
-
7/27/2019 Medii vizuale
19/50
this.groupBox1.set_TabIndex(5);this.groupBox1.set_TabStop(false);this.groupBox1.set_Text("groupBox1");
//// radioButton3
//this.radioButton3.set_Location(newSystem.Drawing.Point(8, 48));this.radioButton3.set_Name("radioButton3");this.radioButton3.set_Size(newSystem.Drawing.Size(88, 32));this.radioButton3.set_TabIndex(1);this.radioButton3.set_Text("radioButton3");
//// radioButton2//this.radioButton2.set_Location(newSystem.Drawing.Point(8, 24));this.radioButton2.set_Name("radioButton2");
this.radioButton2.set_Size(newSystem.Drawing.Size(88, 24));this.radioButton2.set_TabIndex(0);this.radioButton2.set_Text("radioButton2");
//// listBox1//this.listBox1.set_Location(newSystem.Drawing.Point(208, 120));this.listBox1.set_Name("listBox1");this.listBox1.set_Size(newSystem.Drawing.Size(120, 69));this.listBox1.set_TabIndex(6);
//
// comboBox1//this.comboBox1.set_Location(newSystem.Drawing.Point(208, 192));this.comboBox1.set_Name("comboBox1");this.comboBox1.set_Size(newSystem.Drawing.Size(121, 21));this.comboBox1.set_TabIndex(7);this.comboBox1.set_Text("comboBox1");
//// pictureBox1//
this.pictureBox1.set_Image(((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))));this.pictureBox1.set_Location(newSystem.Drawing.Point(16, 248));this.pictureBox1.set_Name("pictureBox1");this.pictureBox1.set_Size(newSystem.Drawing.Size(136, 100));
this.pictureBox1.set_SizeMode(System.Windows.Forms.PictureBoxSizeMode.StretchImage);
-
7/27/2019 Medii vizuale
20/50
this.pictureBox1.set_TabIndex(8);this.pictureBox1.set_TabStop(false);
//// panel1//
this.panel1.set_BorderStyle(System.Windows.Forms.BorderStyle.FixedSingle);this.panel1.get_Controls().Add(this.label2);this.panel1.set_Location(newSystem.Drawing.Point(168, 224));this.panel1.set_Name("panel1");this.panel1.set_Size(newSystem.Drawing.Size(160, 128));this.panel1.set_TabIndex(9);this.panel1.add_Paint( new
System.Windows.Forms.PaintEventHandler( this.panel1_Paint) );//// label2
//this.label2.set_Location(newSystem.Drawing.Point(8, 8));this.label2.set_Name("label2");this.label2.set_TabIndex(0);this.label2.set_Text("This is a Panel");
//// label3//this.label3.set_Location(newSystem.Drawing.Point(16, 216));this.label3.set_Name("label3");this.label3.set_Size(newSystem.Drawing.Size(112, 23));
this.label3.set_TabIndex(10);this.label3.set_Text("ImageControl Demo");//// label4//this.label4.set_Location(newSystem.Drawing.Point(208, 96));this.label4.set_Name("label4");this.label4.set_Size(newSystem.Drawing.Size(100, 16));this.label4.set_TabIndex(11);this.label4.set_Text("ListBox");
//
// timer1//this.timer1.set_Enabled(true);this.timer1.add_Tick( newSystem.EventHandler(this.timer1_Tick) );
//// Form1//this.set_AutoScaleBaseSize(newSystem.Drawing.Size(5, 13));
-
7/27/2019 Medii vizuale
21/50
this.set_ClientSize(newSystem.Drawing.Size(344, 365));this.get_Controls().Add(this.label4);this.get_Controls().Add(this.label3);this.get_Controls().Add(this.panel1);this.get_Controls().Add(this.pictureBox1);
this.get_Controls().Add(this.comboBox1);this.get_Controls().Add(this.listBox1);this.get_Controls().Add(this.groupBox1);this.get_Controls().Add(this.radioButton1);this.get_Controls().Add(this.checkBox1);this.get_Controls().Add(this.button1);this.get_Controls().Add(this.textBox1);this.get_Controls().Add(this.label1);this.set_Name("Form1");this.set_Text("Controls Demo");this.groupBox1.ResumeLayout(false);
this.panel1.ResumeLayout(false);this.ResumeLayout(false);
}#endregion
/*** The main entry point for the application.*/
/** @attribute System.STAThread() */publicstaticvoidmain(String[] args)
{ Application.Run(newForm1());}
privatevoidtimer1_Tick (Object sender, System.EventArgs e){
radioButton2.set_Checked(!radioButton2.get_Checked());panel1.Refresh();
}
privatevoidpanel1_Paint (Object sender, System.Windows.Forms.PaintEventArgse){
count++;count%=4;
LinearGradientBrush myBrush;switch(count)
-
7/27/2019 Medii vizuale
22/50
{case0: {
myBrush = newLinearGradientBrush(newPoint (0,0),newPoint(300,300),
Color.get_Black(),Color.get_White());
Point[] pts={newPoint(0,0),newPoint(30,90),newPoint(120,80)};
e.get_Graphics().DrawPolygon(newPen(myBrush,1),pts);} break;case1: {
myBrush = newLinearGradientBrush(newPoint(0,0),newPoint(300,300),Color.get_Blue(),
Color.get_White());e.get_Graphics().DrawArc(newPen(myBrush,1),newRectangle(newPoint(0,0),new
Size(panel1.get_ClientSize().get_Width()-1,panel1.get_ClientSize().get_Height()-1)),0, 360);
} break;case2: {
myBrush = newLinearGradientBrush(newPoint (0,0),newPoint(300,300),
Color.get_Black(),Color.get_White());Point[] pts={newPoint(0,0),newPoint(30,90),new
Point(120,80)};e.get_Graphics().DrawLines(newPen(myBrush,1),pts);
} break;default: {
myBrush = newLinearGradientBrush(newPoint (0,0),newPoint(300,300),Color.get_Black(),
Color.get_Red());e.get_Graphics().FillRegion(myBrush, panel1.get_Region());}
}}
}
-
7/27/2019 Medii vizuale
23/50
-
7/27/2019 Medii vizuale
24/50
Lectia 3 Obiecte si clase
Obiective: Obiecte
Clase (Constructori, Modificatori de acces, Metode)
In mod obisnuit, orice program pe care l-ati conceput sau il veti concepe este compus din doua parti
distincte: datele(de intrare si/sau iesire) si operatiilece actioneaza asupra acestora. Este evident ca
veti specifica modul in care se va realiza reprezentarea datelor, prin intermediul tipurilor de date, si
modalitatile de actionare asupra datelor, prin intermediul functiilor. Pana in prezent, aceste doua
elemente, care sunt inseparabile si vitale in aceeasi masura unui program, au fost tratate separat.
In cele ce urmeaza vom vedea cum putem obtine o tratare unitara a acestora.
Clasele: implementarea unor tipuri abstracte de date
O caracteristica importanta a unui puternic limbaj de programare este aceea de a oferi
programatorului posibilitatea de a-si construi tipuri de date diferite de cele standard, acestea
numindu-le user defined, deci tipuri utilizator. Limbajul Javaposeda aceasta caracteristica si si-omanifesta prin intermediul cuvantului cheie class.
Astfel, am largit universul datelor, prin introducerea de noi tipuri de date, dar universul paralel, cel
al operatiilor asupra datelor a ramas acelasi, acestea actionand tot asupra unor date de tip implicit.
Pe de alta parte, deseori intereseaza mai mult efectul decat modul si elementele care au dus la
producerea acestuia. Astfel, tipurile de date utilizator nu ofera siguranta elementelor componente,acestea fiind deseori expuse unor operatii care pot produce efecte colaterale.
Introducerea tipurilor abstracte de date ofera acea siguranta structurala si unitate a exprimarii, deci a
operatiilor. Odata intrati in lumea tipurilor abstracte de date, obtinem egalitatea dintre cele doua
elemente, datele si operatiile. Cuvantul cheie classeste cel care ne deschide poarta spre lumea OOP(Object Oriented Programming), cu ajutorul acestuia putand defini tipuri abstracte de date.
O clasa reuneste datele si operatiile in cadrul aceluiasi tip de data. In plus, exista posibilitatea
protejarii elementelor componente, atat date cat si functii, nu in vederea necunoasterii acestora de
catre utilizatorii ulteriori ci impotriva distrugerii lor accidentale (caracteristica cunoscuta sub
denumirea de incapsulare).
Astfel, putem scrie:Clasa = Date + Operatii.
Pentru a aduce un argument in plus in favoarea claselor sa tinem cont ca in programarea standard,
modulata sau nu, programul este cel care sumeaza datele si operatiile si nicidecum un tip de data. Si
atunci, ce inseamna un program atunci cand vorbim despre programarea orientata spre obiecte? In
-
7/27/2019 Medii vizuale
25/50
mod sigur, mult mai mult decat o simpla sumare. Va lasam pe voi sa gasiti raspunsul la aceasta
intrebare.
Un exemplu de tip abstract de data implementat sub forma unei clase
Sa exemplificam cele mai sus prezentate pe cazul numerelor circulare. Prin numar circularintelegem un numar al carui domeniu de valori este circular, deci ajuns la valoarea maxima,
urmatoarea valoare ce o va lua va fi cea minima, urmand sa parcurga, din nou, intreg domeniul de
valori. Ca exemple de numere circulare nu amintim decat unghiurile, avand domeniul de valori
intervalul [0o,360
o].
Observam ca, odata cu mentionarea numarului ca fiind circular se va specifica si intervalul in care
acesta poate lua valori. Abordand aceasta problema prin intermediul claselor, vom defini un nou tip
de data care va reuni atat datele, variabile de instantiere, cat si functiile, ca metode membre ale
clasei..
public class CircularNum {private int num,upper,lower;
public CircularNum() {num=lower=upper=0;
}
public void setLimits(int l,int u) {lower=l; upper=u;
}
public int setVal(int v) {int range=upper-lower+1;
while (v>upper) v-=range;while (v
-
7/27/2019 Medii vizuale
26/50
angle.setLimits(0,359);angle.setVal(570);System.out.println(""+angle);
x_coord.setLimits(0,79);x_coord.setVal(-15);System.out.println("Coordonata x este: "+x_coord.getVal());
}}
Metode
Faptul ca o functie apartine unei clase, deci este functie membra a acelei clase, este specificat prin
plasarea implementarii functiei in cadrul declaratiei clasei respective. O astfel de functie o vom
numi metoda a clasei.
Modificand semnatura metodei si mai precis, lista parametrilor acesteia, este posibila obtinerea mai
multor implementari ale aceleeasi metode in cadrul unei clase, fara a exista pericolul ambiguitatii.
De exemplu metoda setValar putea avea doua variante:
public class CircularNum {public int setVal(int v) {
int range=upper-lower+1;
while (v>upper) v-=range;while (v
-
7/27/2019 Medii vizuale
27/50
public int setVal(int num) {int range=upper-lower+1;
while (num>upper) num-=range;while (num
-
7/27/2019 Medii vizuale
28/50
ConstructoriConstructorii nu numai ca atribuie valori initiale elementelor membre dar pot efectua diferite
operatii cum ar fi alocare dinamica de memorie, deschideri de fisiere si enumerarea ar putea
continua. Un constructor este un tip special de metoda membra avand acelasi nume cu numele clasei
a carei membra este.
public class CircularNum {public CircularNum() {
num=lower=upper=0;}
}
In cadrul constructorului pot fi apelate alte functii, membre sau nu.
Apelul contructorilor se va produce in locul declararii unui obiect. In cazul nostru, putem declara ovariabila de tip CircularNumprin
CircularNum angle = new CircularNum();
Momentul in care este apelat un constructor trebuie cautat in cadrul executiei programului, mai
precis in momentul declararii obiectului respectiv. Constructorii garanteaza initializarea corecta a
obiectului inaintea utilizarii sale efective. In cazul nostru, mai intai se stabileste domeniul unui
numar circular si abia apoi i se atribuie o valoare.
Ca orice alta metoda, constructorul poate fi redefinit prin utilizarea a diferite semnaturi. Iata cateva
alte variante posibile ale constructorului clasei CircularNum, impreuna cu apelurile corespunztoare:
public class CircularNum {public CircularNum() {
num=lower=upper=0;}
public CircularNum(int l, int u) {
if (l
-
7/27/2019 Medii vizuale
29/50
public CircularNum(int num, int l, int u) {
this(l,u);setVal(num);
}
}
Prima varianta de constructor este constructorul implicit, iar cea de a treia varianta utilizeaza apelul
celei de a doua (cu doi parametri) impreuna cu apelul unei metode membre, setVal(). Apelulconstructorilor este:
CircularNum ob1=new CircularNum(),ob2=new CircularNum(0,360),ob3=new CircularNum(30,0,360);
-
7/27/2019 Medii vizuale
30/50
Lectia 4 Ierarhii de clase
Obiective: Compunere si mostenire
Ierarhii de clase
Reutilizarea codului
Nu de putine ori, scriind programe in maniera clasica, eram pusi in situatia de a rescrie, readapta,
proceduri scrise anterior, deseori oprindu-ne asupra metodelor utilizate in cadrul acestora. Era clar
ca, acea etapa a procesului de implementare dura mai mult timp decat ar fi fost necesar. In plus,
exista riscul aparitiei de erori, din diferite motive.
Solutia in aceasta directie ne este oferita tot de programarea orientata spre obiecte, oferindu-ne douamodalitati de a reutiliza codul:
prin compunere: deci includerea de obiecte in cadrul altor obiecte,
prin mostenire: deci prin crearea unor obiecte completand colectia de obiecte existente.
Compunerea
Prin includerea unui obiect in cadrul altuia, acesta din urma va avea drept elemente membre, toate
elementele membre ale obiectului inclus. Este o situatie asemanatoare cu includerea de structuri in
cadrul structurilor.
Accesul catre elementele membre ale obiectului inclus se va realiza, evident, prin intermediul
acestuia.
class Point2D {protected float x,y;
public Point2D() {x=y=0;
}
public Point2D(float x,float y) {set(x,y);
}
public void set(float x, float y) {this.x=x;this.y=y;
}
-
7/27/2019 Medii vizuale
31/50
public float getX() {
return x;}
public float getY() {return y;
}
public String toString() {return ""+x+" , "+y;
}}
public class CircleByComposition {protected Point2D center;
protected float radius;
public CircleByComposition () {center=new Point2D();radius=0;
}
public void setRadius(float r) {radius=r;
}
public void setCenter(Point2D p) {center=p;}
public float getRadius() {return radius;
}
public Point2D getCenter() {return center;
}
public String toString() {return "Circle with center at "+center+" and radius of "+radius;
}
public static void main(String[] s) {CircleByComposition c = new CircleByComposition ();c.setRadius(10);
-
7/27/2019 Medii vizuale
32/50
c.getCenter().set(15, 7);
System.out.println(""+c);}
}
Mostenirea
O varianta mult imbunatatita de reutilizare a codului, este aceea de a mosteni proprietatile unor
obiecte construite anterior, in vederea obtinerii de noi obiecte.
Mostenirea se caracterizeaza prin trecerea atributelor de la o clasa, de baza, la alta, derivata, asa
cum clasa insectelor este clasa de baza atat pentru clasa albinelor cat si cea a tantarilor.
Deci clasele derivate poseda toate caracteristicile clasei de baza. In plus, derivatiile pot fi imbogatite
structural si/sau functional. Pe de alta parte, incercand o reprezentare a claselor, observam oierarhizare, o asezare pe nivele, asemanatoare arborilor. Spunem asemanatoare datorita faptului ca
exista posibilitatea ca o clasa derivata, deci un FIU, sa aiba mai multe clase de baza, mai multi
TATI, ordinea importantei nivelelor ramanand insa aceeasi.
Functie de necesitati, derivarea claselor va fi un proces cu durata variabila. In acest sens, se prefera
conceperea unor clase de baza simple in locul unora dezvoltate, cea din urma varianta ducand
deseori la mosteniri incomode, de prisos.
Avantaje ale mostenirii
Chiar daca, la un prim contact cu acest concept, ar parea ca mostenirea este asemanatoare cuprocesul de includere a obiectelor in obiecte, exista cateva elemente caracteristice mostenirii si care
nu sunt regasite in cazul compunerii:
codul poate fi comun mai multor clase,
clasele pot fi extinse, deseori fara a se recompila clasele originale,
functiile utilizand obiecte din clasa de baza pot utiliza in mod automat si obiecte derivate ale
acelei clase.
class Point2D {protected float x,y;
public Point2D() {x=y=0;
}
public Point2D(float x,float y) {set(x,y);
}
-
7/27/2019 Medii vizuale
33/50
public void set(float x, float y) {
this.x=x;this.y=y;
}
public String toString() {return ""+x+" , "+y;
}
public float getX() {return x;
}
public float getY() {return y;
}}
public class CircleByExtension extends Point2D {protected float radius;
public CircleByExtension() {radius=0;
}
public void setRadius(float r) {
radius=r;}
public void setCenter(_Point2D p) {x=p.getX();y=p.getY();
}
public float getRadius() {return radius;
}
public _Point2D getCenter() {return new _Point2D(x,y);
}
public String toString() {return "CircleByExtension with center at "+x+" , "+y+" and radius of "+radius;
}
-
7/27/2019 Medii vizuale
34/50
public static void main(String[] s) {
CircleByExtension c = new CircleByExtension();c.setRadius(10);
c.setCenter(new _Point2D(15, 7));
System.out.println(""+c);}
}
Astfel, elementele membre ale clasei de baza devin elemente membre si ale clasei derivate, obiectul
intermediar disparand. Clasele derivate sunt tratate ca subclase ale claselor de baza. Pornind de la
acest aspect, obiectele derivate pot fi atribuite obiectelor de baza
Point2D p;CircleByExtension c;p=c;
fara a fi necesara o conversie de tip. In astfel de atribuiri, se vor copia numai membrii clasei de baza,
adica:
p.x=c.x;p.y=c.y;
In plus, nu putem efectua atribuiri de acest tip unor obiecte ce nu sunt legate prin relatia de
mostenire.
Polimorfismul
Deseori, motivul pentru care derivam o clasa nu este acela de a o imbunatati din punct de vedere
structural ci de a redefini, respectiv rescrie, functionalitatea acesteia.
Atunci cand functiile unei clase de baza sunt rescrise intr-una derivata spunem ca aceste clase sunt
polimorfe. Aceasta denumire trebuie sa ne sugereze faptul ca vom avea o singura denumire si mai
multe actiuni, altfel spus,o singura interfata, metode multiple.
Sa vedem acum cum arata obiectele polimorfe. Pentru aceasta, sa ne uitam la functia membra
toString() a claselor Point2D si CircleByExtension, functie ce va avea ca efect returnareainformatiilor asupra starea obiectului corespunzator. Cum CircleByExtensionprovine din Point2D,CircleByExtension si Point2D sunt obiecte din aceeasi categorie, altfel spus, sunt polimorfe.Pentru a obtine obiecte polimorfe, va trebui sa construim o ierarhie de clase si apoi sa redefinim
functiile apartinand clasei de baza in clasele derivate.
-
7/27/2019 Medii vizuale
35/50
Astfel, daca modificam contextul functiei main()din exemplul anterior cu:
public static void main(String[] s) {CircleByExtension c = new CircleByExtension();c.setRadius(10);
c.setCenter(new _Point2D(15, 7));
Point2D p;
p = new Point2D(2,3);System.out.println("p as Point"+p); // apel toString() ptr p ca Point2D
p=c;System.out.println("p as Circle"+p); // apel toString ptr p ca CircleByExtension
}observam cele doua apeluri ale metodei toString()asociate obiectului p, identice ca formulare dar
diferite ca efect, datorita tipului obiectului la momentul rularii aplicatiei.
-
7/27/2019 Medii vizuale
36/50
Lectia 5 Clase abstracte si interfete
Obiective: Clase abstracte
Interfete
Clase abstracte
In cele mai multe situatii, clasa de baza a unei ierarhii va trebui sa fie foarte generala, elementele
specifice ramanand a fi atasate derivarilor acesteia. De fapt, generalitatea clasei de baza poate atinge
un astfel de grad incat, aceasta clasa nici sa nu intervina in crearea obiectelor. Astfel de clase se
numesc clase abstracte.
Atunci cand in cadrul unei clase, cel putin o metoda ramane la stadiul de semnatura (fara a i se da siimplementarea), acea metoda se numeste abstracta, iar clasa, devine, implicit, clasa abstracta. In
aceasta situatie, clasa nu va putea servi "decat" ca punct de intrare intr-o ierarhie de clase,
instantierea obiectelor din clasa respectiva fiind imposibila.
Abstractizarea trebuie inteleasa in adevaratul sens al cuvantului deoarece nu este permisa definirea
de obiecte din astfel de clase. Trebuie construite mai intai clase derivate din acestea, in cadrul carora
se vor redefini metodele abstracte. In cazul in care raman metode neimplementate, clasele derivate
in aceasta situatie raman abstracte. Cu alte cuvinte, o clasa abstracta poate fi extinsa de o alta clasa,
abstracta sau nu.
abstract class Figure {double x,y;
public Figure(double x,double y) {this.x=x;this.y=y;
}
public String toString() {return "x "+x+" y "+y;
}
abstract double area();}
class Circle extends Figure {double radius;
public Circle(double x,double y,double r) {
-
7/27/2019 Medii vizuale
37/50
super(x,y);radius=r;
}
public String toString() {
return super.toString()+" radius "+radius+" area "+area();}
public double area() {return Math.PI*radius*radius;
}}
class Rectangle extends Figure {double dx,dy;
public Rectangle(double x,double y,double dx,double dy) {super(x,y);this.dx=dx;this.dy=dy;
}
public String toString() {return super.toString()+" dx "+dx+" dy "+dy+" area "+area();
}
public double area() {
return dx*dy;}}
public class testAbstracts {public static void main(String[] s) {
Figure f=new Circle(1,2,4);System.out.println(""+f);
Circle c=new Circle(1,1,3);System.out.println(""+c);
Rectangle r=new Rectangle(1,2,5,10);System.out.println(""+r);
}}
Constructorii nu pot fi metode abstracte.
-
7/27/2019 Medii vizuale
38/50
Definind o clasa abstracta, reusim sa stabilim un protocol de comunicare cu utilizatorul. Protocolul,
unic fiind, va fi atasat unui set de metode, caracteristic claselor derivate, altfel spus interfata este
unica, iar metodele multiple.
Interfete
Ca o solutie pentru obtinerea mostenirii multiple, Java ofera instrumentul de lucru al interfetelor. O
interfata consta intr-o colectie de constante si semnaturi de metode care urmeaza a fi implementate
in clasele care utilizeaza interfata. Aceste metode sunt implicit publice. Obiectele de tip interfata pot
fi utilizate atat ca argumente ale metodelor dar si ca rezultat al acestora. Cu ajutorul ierarhiilor pot fi
obtinute ierarhii de interfete.
abstract class Location {double x,y,z;
public Location(double x,double y,double z) {
this.x=x;this.y=y;this.z=z;
}
abstract public String toString();}
interface _2D {double area();
}
interface _3D {double volume();
}
abstract class Object2D extends Location implements _2D {
Object2D(double x,double y) {super(x,y,0);
}public String toString() {
return "x "+x+" y "+y+" z "+z +" area "+area();}}
abstract class Object3D extends Location implements _2D,_3D {Object3D(double x,double y,double z) {
super(x,y,z);}
-
7/27/2019 Medii vizuale
39/50
public String toString() {
return "x "+x+" y "+y+" z "+z+" area "+area()+" volume "+volume();}
}
class Circle extends Object2D {double radius;
public Circle(double x,double y,double radius) {super(x,y);this.radius=radius;
}
public double area() {return Math.PI*radius*radius;
}}
class Sphere extends Object3D {double radius;
public Sphere(double x,double y,double z,double radius) {super(x,y,z);this.radius=radius;
}
public String toString() {return "x "+x+" y "+y+" z "+z+" radius "+radius+" area "+area()+" volume"+volume();
}
public double area() {return 4*Math.PI*radius*radius;
}
public double volume() {return 4.*Math.PI*radius*radius*radius/3.;
}}
public class testInterfaces1 {public static void main(String[] s) {
_2D f=new Circle(1.,2.,4.);System.out.println(""+f);
-
7/27/2019 Medii vizuale
40/50
f=new Sphere(1.,1.,3.,4.);System.out.println(""+f);
}}
Evident ca puteam deriva clasa Object3D din clasa Object2D, lasand-o sa implementeze doarinterfata _3D dar, intr-o astfel de implementare, nu mai era la fel de clar ce metode raman deimplementat la nivelul clasei Object3D.
Mai trebuie observata si utilizarea interfetei_2Dca tip al obiectului f(din cadrul main).
-
7/27/2019 Medii vizuale
41/50
Lectia 6 Tratarea erorilor prin exceptii
Obiective: Detectarea si prinderea unei exceptii, Blocul try-catch,
Exceptii standard in Java,
Construirea propriilor exceptii.
Ce este o exceptie?
O exceptie este, de fapt, un eveniment care nu permite executia normala a metodei sau domeniului
de scop in cadrul caruia acesta apare. Aparitia acestui eveniment poate fi identificata prin testarea
explicita a unor conditii (exceptionale) sau poate fi semnalata chiar de interpretorul Java. Este
importanta distinctia dintre conditiile exceptionale si problemele normale care pot apare in contextul
aplicatiei curente. O conditie exceptionala nu permite continuarea procesarii deoarece informatianecesara contextului curent lipseste; tot ceea ce se poate face este trecerea la contextul (metoda,
domeniu,) urmator.
Ce se intampla atunci cand este lansata o exceptie?
Se creaza un obiect de tip Exception (prin new). Calea de executie in cadrul careia exceptia a aparut (si deci cea pe care nu o putem continua)
este intrerupta
Din contextul curent generator de exceptie este lansat obiectul de tip Exception (prin throw) Mecanismul de tratare a exceptiei cauta un loc in program de unde poate continua o executie
normala a acestuia. Iar acesta este locul in care se trateaza exceptia (prin try-catch).
Lansarea exceptiilor:
throw Expresie;
Tratarea exceptiilor se realizeaza prin:
try {... // instructiuni prin a caror executie poate apare exceptia} catch (Argument) {
// instructiuni de tratare a exceptiei}
sau
try {... // instructiuni prin a caror executie poate apare exceptia} catch (Argument) { }
-
7/27/2019 Medii vizuale
42/50
catch (Argument) { }
sau
try{} finally { // instructiuni de tratare a exceptiei}
sau
try{} catch (Argument) { // instructiuni de tratare a exceptiei
} finally {}
Exceptiile standard in Javasunt urmatoarele (toate derivand din clasa Exception):
RuntimeException IllegalMonitorStateException ProtocolExceptionArithmeticException NullPointerException SocketExceptionIndexOutOfBoundsException SecurityException UnknownHostException
ArrayIndexOutOfBoundsException EmptyStackException UnknownServiceExceptionStringIndexOutOfBoundsException NoSuchElementException ClassNotFoundException
ArrayStoreException IOException CloneNotSupportedExceptionClassCastException EOFException IllegalAccesException
IllegalArgumentException FileNotFoundException NoSuchMethodException
IllegalThreadStateException InterruptedIOException AWTExceptionNumberFormatException UTFDataFormatException InstantiationException
NegativeArraySizeException MalformedURLException InterruptedException
Construirea propriilor exceptii
Prin extinderea clasei Exceptionputem defini exceptii adaptate aplicatiei curente. Exemplul de maijos este edificator in acest sens.
class MyException extends Exception {MyException(String s) {
super(s) ;}
}
class Example {static void trigger() throws MyException {
throw new MyException (Dont worry be happy!);}
-
7/27/2019 Medii vizuale
43/50
}
public static void main(String[] s) {System.out.println(Food is expensive!);try {
trigger();} catch (MyException e) {
// System.out.println(Positive attitude:);System.out.println(e);
} finally {System.out.println(It can be worst!);
}}
Executia exemplului anterior va produce iesirea urmatoare la terminal:
Food is expensive!Dont worry, be happy!It can be worst!
Secventa specificata prin finallyeste executata indiferent daca exceptia a aparut sau nu.
-
7/27/2019 Medii vizuale
44/50
Lectia 7 Sistemul I/O
Obiective: Tipuri de intrari si iesiri
Lucrul cu fisiere,
Fluxuri de date,
Analiza lexicala.
Serializarea obiectelor
Tipuri de intrariIntrarile in Java sunt obtinute prin intermediul ierarhiei de clase ce are drept clasa de bazaInputStream, aceasta ierarhie tratand intrari provenind de la siruri de byte(ByteArrayInputStream), de la String (StringBufferInputStream), din fisiere (FileInputStream),
din mecanismul pipe (PipedInputStream), dintr-o secventa de fluxuri colectate toate intr-unulsingur (SequenceInputStream), sau alte surse (FilterInputStream, ObjectInputStream,DataInputStream, BufferedInputStream).
Tipuri de iesiriIesirile Javapot fi realizate pornindu-se de la clasa de baza OutputStream, printr-un sir de byte(ByteArrayOutputStream), printr-un fisier (FileOutputStream), un pipe (PipeOutputStream),sau altele (PrintStream, ObjectOutputStream, FilterOutputStream, DataOutputStream).
Un exemplu binecunoscut in randul programatorilor C/C++ il constituie programul care afiseaza peterminal, deci la iesirea standard, ceea ce se tasteaza, deci intrarea standard (programul echo).
Varianta Javaa acestui program ilustreaza uzul dispozitivelor standard, System.insi System.out,in cele ce urmeaza.
import java.io.*;
public class Echo {public static void main(String[] s) {
DataInputStream in = new DataInputStream(new BufferedInputStream(System.in)
);String myinput;
try {while((myinput = in.readLine()).length() != 0)
System.out.println(myinput);} catch(Exception e) {
e.printStackTrace();}
}
-
7/27/2019 Medii vizuale
45/50
}
Observati ca intrarea, retinuta in myinput, nu este recuperata, si deci disponibila afisarii, decat dupaapasarea lui Enter.
Lucrul cu fisiereUtilizarea fisierelor apare in mod frecvent in 3 situatii; ca flux de intrare, ca flux de iesire sau cadirector. Vor trata pe rand toate aceste ipostaze. Pentru ilustrarea utilizarii unui fisier ca flux de
intrare, respectiv de iesire, sa consideram exemplul urmator care implementeaza o clasa (CopyFile)ce are drept scop copierea fisierului precizat ca prim argument in fisierul avand numele cel de al
doilea argument al liniei de comanda (fara sa numaram si cuvantuljavasi CopyFile).
import java.io.*;
public class CopyFile {public static void main(String[] s) {
if (s.length!=2) System.out.println("Ask the teacher...or find out yourself!");elsetry{
FileInputStream in = new FileInputStream(s[0]);FileOutputStream out = new FileOutputStream(s[1]);int readed=in.read();
while (readed>-1) {out.write(readed);readed=in.read();
}
in.close();out.close();} catch (Exception e) {
e.printStackTrace();} finally {
System.out.println("See you next time!");}
}}
Tot despre fisiere vorbim si atunci cand dorim sa inspectam continutul directoarelor.
import java.io.*;
class PDFFilter implements FilenameFilter {public boolean accept(File dir, String fileName) {
return fileName.endsWith(".pdf")||fileName.endsWith(".PDF");}
}
-
7/27/2019 Medii vizuale
46/50
public class DirectoryList {
public static void main(String[] s) {String workingDirectory=".";
if (s.length==1) workingDirectory=s[0];
// File list WITHOUT filter
File directoryFile =new File(workingDirectory);String directoryListWithoutFilter[]=directoryFile.list();System.out.println(workingDirectory+" contains the following NON-FILTERED
files:");for (int i=0;i
-
7/27/2019 Medii vizuale
47/50
try {
while((myinput = in.readLine()).length() != 0)analyze(myinput);
} catch(Exception e) {
e.printStackTrace();}
}
static void analyze(String s) {System.out.println("Your answer is : " + s);st = new StringTokenizer(s);while (st.hasMoreTokens()) {
String token = st.nextToken();boolean correctFruit=false;for (int i=0;i
-
7/27/2019 Medii vizuale
48/50
}
static void analyze(Reader in) {try {
st = new StreamTokenizer(in);
int type = st.nextToken();
while (type!=StreamTokenizer.TT_EOF) {if (type==StreamTokenizer.TT_WORD) {
boolean correctFruit=false;for (int i=0;i
-
7/27/2019 Medii vizuale
49/50
this.x=x;this.y=y;
}
public String toString() {
return "Object: "+name+" has "+x+" , "+y + " coordinates.";}
public void setX(int x) {oldx=this.x;this.x=x;
}
public void setY(int y) {oldy=this.y;this.y=y;
}
public void setName(String name) {this.name=name;
}
public int getX() {return x;
}
public int getY() {
return y;}
public String getName() {return name;
}
public static void main(String[] s) {if (s.length!=1) System.out.println("Use SAVE to produce an object or \n use
LOAD to load an produced object!");else {
try { if (s[0].toUpperCase().equals("SAVE")) {int randX=(int)(Math.random()*100);int randY=(int)(Math.random()*100);String randName=new String("GO_"+randX+"_"+randY);GraphicalObject myObject = new GraphicalObject(
randName, randX,randY);FileOutputStream out = new FileOutputStream(
-
7/27/2019 Medii vizuale
50/50
"briefcase.job");ObjectOutputStream objout = new ObjectOutputStream(
out);objout.writeObject(myObject);System.out.println("Object "+myObject+ " saved!");
objout.close();out.close();
} else if (s[0].toUpperCase().equals("LOAD")) {FileInputStream in = new FileInputStream(
"briefcase.job");ObjectInputStream objin = new ObjectInputStream(in);GraphicalObject myObject =
(GraphicalObject)objin.readObject();System.out.println("Object "+myObject+ " loaded!");objin.close();in.close();
} else System.out.println("Ask the teacher ... or find outyourself!");} catch (IOException e) { e.printStackTrace(); }catch (ClassNotFoundException ce) { ce.printStackTrace(); }
}}
}Observati ca exista atribute ale obiectelor GraphicalObjectcare nu sunt serializabile (utilizandu-sein declaratia acestora cuvantul transient).