Activitats

Proves unitàries

L’objectiu d’aquest exercici és treballar, en profunditat, les proves unitàries d’un algorisme desenvolupat en Java, validant el seu correcte funcionament.

A continuació, es mostra la classe CostPersonal que conté el mètode CostDelPersonal. Aquest mètode té com a funció el càlcul del cost final de cada treballador en funció dels valors dels paràmetres que els defineixen. Concretament, si el tipus de treballador és director o subdirector, el cost final del treballador serà el corresponent a la seva nòmina. Però, si no és ni director ni subdirector, a la seva nòmina caldrà sumar-hi les hores extres que hagi fet per un valor de 20 unitats.

Donat el codi següent amb la implementació d’aquesta classe i aquest mètode, es demana crear les seves proves unitàries.

  1. package IOC.desenvolupament;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5.  
  6. public class CostPersonal {
  7.  
  8. static float CostDelPersonal(Treballador treballadors[]) {
  9. float costFinal = 0;
  10. Treballador treballador;
  11. for (int i = 0; i < treballadors.length; i++) {
  12. treballador = treballadors[i];
  13. if ( treballador.getTipusTreballador() == Treballador.DIRECTOR || treballador.getTipusTreballador() == Treballador.SUBDIRECTOR) {
  14. costFinal += treballador.getNomina();
  15. }
  16. else
  17. {
  18. costFinal += treballador.getNomina() + (treballador.getHoresExtres() * 20);
  19. }
  20. }
  21. return costFinal;
  22. }
  23. }

Unes possibles proves unitàries podrien ser:

  1. package IOC.provesUnitaries;
  2.  
  3. import static org.junit.Assert.*;
  4. import IOC.desenvolupament.*;
  5.  
  6. import org.junit.Before;
  7. import org.junit.Test;
  8.  
  9. public class test {
  10.  
  11. @Test
  12. public void testDirectius() {
  13. Treballador treballadors[] = new Treballador[3];
  14.  
  15. treballadors[0] = new Treballador("Nom1", "DNI1", Treballador.DIRECTOR, 3000, 0);
  16. treballadors[1] = new Treballador("Nom2", "DNI2", Treballador.SUBDIRECTOR, 2000, 5);
  17. treballadors[2] = new Treballador("Nom3", "DNI3", Treballador.SUBDIRECTOR, 2500, 10);
  18.  
  19. float cost = CostPersonal.costDelPersonal(treballadors);
  20. assertEquals("Error en el càlcul del cost!", 7500, cost, 0);
  21. }
  22.  
  23. @Test
  24. public void testNoDirectius() {
  25. Treballador treballadors[] = new Treballador[3];
  26.  
  27. treballadors[0] = new Treballador("Nom1", "DNI1", Treballador.TREBALLADOR, 1200, 0);
  28. treballadors[1] = new Treballador("Nom2", "DNI2", Treballador.TREBALLADOR, 1300, 5);
  29. treballadors[2] = new Treballador("Nom3", "DNI3", Treballador.TREBALLADOR, 1000, 10);
  30.  
  31. float cost = CostPersonal.costDelPersonal(treballadors);
  32. assertEquals("Error en el càlcul del cost!", 5000, cost, 0);
  33. }
  34.  
  35. @Test
  36. public void testTipusTreballadors() {
  37. Treballador treballadors[] = new Treballador[3];
  38.  
  39. treballadors[0] = new Treballador("Nom1", "DNI1", Treballador.DIRECTOR, 3000, 10);
  40. treballadors[1] = new Treballador("Nom2", "DNI2", Treballador.SUBDIRECTOR, 2000, 10);
  41. treballadors[2] = new Treballador("Nom3", "DNI3", Treballador.TREBALLADOR, 1000, 10);
  42.  
  43. float cost = CostPersonal.costDelPersonal(treballadors);
  44. assertEquals("Error en el càlcul del cost!", 7000, cost, 0);
  45. }
  46.  
  47. @Test
  48. public void testNoTreballadors() {
  49. Treballador treballadors[] = new Treballador[0];
  50. float cost = CostPersonal.costDelPersonal(treballadors);
  51. assertEquals("Error en el càlcul del cost!", 0, cost, 0);
  52. }
  53.  
  54. @Test
  55. public void testNull() {
  56. Treballador treballadors[] = null;
  57. try {
  58. float cost = CostPersonal.costDelPersonal(treballadors);
  59. fail();
  60. } catch (NullPointerException e) {
  61. assertTrue(true);
  62. }
  63. }
  64.  
  65. }

Refacció

L’objectiu d’aquest exercici és treballar el concepte de refacció i la seva aplicació.

A continuació, es mostra la classe CostPersonal, que conté el mètode CostDelPersonal. Aquest mètode té com a funció el càlcul del cost final de cada treballador en funció dels valors dels paràmetres que els defineixen. Concretament, si el tipus del treballador és director o subdirector, el cost final del treballador serà el corresponent a la seva nòmina. Però, si no és ni director ni subdirector, a la seva nòmina caldrà sumar-hi les hores extres que hagi fet per un valor de 20 unitats.

Donat el codi següent amb la implementació d’aquesta classe prèviament explicada, cal analitzar-lo i dir si es pot refactoritzar. En el cas que es pugui fer, es demana refactoritzar el codi i mostrar el codi resultant.

  1. package IOC.desenvolupament;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5.  
  6. public class CostPersonal {
  7.  
  8. static float CostDelPersonal(Treballador treballadors[]) {
  9. float costFinal = 0;
  10. Treballador treballador;
  11. for (int i = 0; i < treballadors.length; i++) {
  12. treballador = treballadors[i];
  13. if ( treballador.getTipusTreballador() == Treballador.DIRECTOR|| treballador.getTipusTreballador() == Treballador.SUBDIRECTOR) {
  14. costFinal += treballador.getNomina();
  15. }
  16. else
  17. {
  18. costFinal += treballador.getNomina() + (treballador.getHoresExtres() * 20);
  19. }
  20. }
  21. return costFinal;
  22. }
  23. }

A primer cop d’ull pot semblar que el codi estigui ben dissenyat i ben codificat, però si ens hi fixem bé, s’hi podria aplicar el patró de refactorització d’extracció d’un mètode, en concret el que calcula el cost del treballador.

A continuació, es mostra com hauria d’evolucionar el codi en aplicar-hi la refacció.

  1. public class CostPersonal {
  2.  
  3. static float CostTreballador(Treballador treballador){
  4.  
  5. if ( treballador.getTipusTreballador() == Treballador.DIRECTOR || treballador.getTipusTreballador() == Treballador.SUBDIRECTOR ) {
  6. return treballador.getNomina();
  7. }
  8. else {
  9. return treballador.getNomina()+ (treballador.getHoresExtres() * COST_HORA_EXTRA);
  10. }
  11.  
  12. }
  13.  
  14. static float CostDelPersonal(Treballador treballadors[]) {
  15. float costFinal = 0;
  16. Treballador treballador;
  17. for (int i = 0; i < treballadors.length; i++) {
  18. costFinal= costFinal + CostTreballador(treballadors[i]);
  19. }
  20. return costFinal;
  21. }
  22. }

Una altre patró que es podria aplicar és el d’extracció d’una constant, en concret la corresponent al valor 20.

A continuació, es mostra com hauria d’evolucionar el codi en aplicar-hi la refacció.

  1. public class CostPersonal {
  2.  
  3. private static final int COST_HORA_EXTRA = 20;
  4.  
  5. static float CostTreballador(Treballador treballador){
  6.  
  7. if ( treballador.getTipusTreballador() == Treballador.DIRECTOR || treballador.getTipusTreballador() == Treballador.SUBDIRECTOR ) {
  8. return treballador.getNomina();
  9. }
  10. else {
  11. return treballador.getNomina()+ (treballador.getHoresExtres() * COST_HORA_EXTRA);
  12. }
  13.  
  14. }
  15.  
  16. static float CostDelPersonal(Treballador treballadors[]) {
  17. float costFinal = 0;
  18. Treballador treballador;
  19. for (int i = 0; i < treballadors.length; i++) {
  20. costFinal= costFinal + CostTreballador(treballadors[i]);
  21. }
  22. return costFinal;
  23. }
  24. }

Arribats a aquest punt, es podria crear un nou mètode que indiqués el tipus de treballador de què es tracta, és a dir, si forma part de l’equip de direcció o no.

A continuació, es mostra com hauria d’evolucionar el codi en aplicar-hi la refacció.

  1. public class CostPersonal {
  2.  
  3. private static final int COST_HORA_EXTRA = 20;
  4.  
  5. static boolean esDirectiu (Treballador treballador){
  6. if (treballador.getTipusTreballador() == Treballador.DIRECTOR || treballador.getTipusTreballador() == Treballador.SUBDIRECTOR)
  7. return true;
  8. else
  9. return false;
  10. }
  11.  
  12. static float costTreballador(Treballador treballador){
  13.  
  14. if ( esDirectiu(treballador) ) {
  15. return treballador.getNomina();
  16. }
  17. else {
  18. return treballador.getNomina()+ (treballador.getHoresExtres() * COST_HORA_EXTRA);
  19. }
  20.  
  21. }
  22.  
  23. static float costDelPersonal(Treballador treballadors[]) {
  24. float costFinal = 0;
  25. Treballador treballador;
  26. for (int i = 0; i < treballadors.length; i++) {
  27. costFinal= costFinal + costTreballador(treballadors[i]);
  28. }
  29. return costFinal;
  30. }
  31. }

Validació de la refacció

L’objectiu d’aquest exercici és fer un pas més enllà en l’aplicació de la refacció i la seva relació amb les proves unitàries.

Responeu a la qüestió següent: Com es pot validar que el codi al qual s’ha aplicat la refacció continua essent correcte?

Feu servir exemples per a demostrar la vostra resposta.

Aquest exercici és de resposta oberta.

La forma de validar si el codi que s’ha obtingut, una vegada aplicats els patrons de refacció, és correcte i continua fent el que feia abans, serà utilitzant les proves unitàries.

Refacció i Eclipse

L’objectiu de l’exercici consisteix a utilitzar les funcionalitats que ofereix l’IDE Eclipse a l’hora d’efectuar la refacció d’un codi.

El codi que es mostra a continuació calcula el cost d’una matrícula d’uns estudis de cicles formatius per a un determinat alumne.

El codi fa ús de dues classes:

  • Assignatura, que té la informació de l’assignatura.
  • Matrícula, que té la informació de l’alumne, així com les assignatures de les quals s’ha matriculat en el curs acadèmic.

Per tal de no dedicar temps addicional a altres accions no relacionades amb l’exercici, la informació de les assignatures i els alumnes es troba registrada temporalment en una col·lecció, no essent necessari configurar la connexió a una base de dades.

Es demana aplicar els patrons de refacció que es puguin aplicar sobre aquest codi, utilitzant l’IDE Eclipse.

  1. package ioc.desenvolupament;
  2.  
  3. public class Assignatura {
  4.  
  5. public long id = 0;
  6. private String nom = "";
  7. private int hores = 0;
  8. public int credits = 0;
  9. private boolean disponible = false;
  10.  
  11. public Assignatura(long id, String nom, int hores, int credits, boolean disponible) {
  12. this.id = id;
  13. this.nom = nom;
  14. this.hores = hores;
  15. this.credits = credits;
  16. this.disponible = disponible;
  17. }
  18. }
  1. package ioc.desenvolupament;
  2.  
  3. import java.util.Collection;
  4. import java.util.ArrayList;
  5. import java.util.Iterator;
  6.  
  7. public class Matricula {
  8.  
  9. public long id = 0;
  10. private String nom = "";
  11. private String cognoms = "";
  12. private String dni = "";
  13. private int curs = 0;
  14. private Collection assignatures;
  15.  
  16. public Matricula(){}
  17.  
  18. public Matricula(long id, String nom, String cognoms, String dni, int curs, Collection assignatures) {
  19. this.id = id;
  20. this.nom = nom;
  21. this.cognoms = cognoms;
  22. this.dni = dni;
  23. this.curs = curs;
  24. this.assignatures = assignatures;
  25. }
  26.  
  27. public float costMatricula(){
  28.  
  29. float cost = 0;
  30. int credits = 0;
  31.  
  32. for (Iterator iter = assignatures.iterator(); iter.hasNext();) {
  33. Assignatura element = (Assignatura) iter.next();
  34. credits = credits + element.credits;
  35. }
  36.  
  37. cost = credits * 15;
  38. return cost;
  39. }
  40. }
  1. package ioc.test;
  2.  
  3. import ioc.desenvolupament.*;
  4. import ioc.simulacio.dades.*;
  5.  
  6. import java.util.Arrays;
  7.  
  8. public class Test {
  9.  
  10. public static void main(String[] args) {
  11.  
  12. MatriculaDB matriculaDB = new MatriculaDB();
  13. Matricula matricula = matriculaDB.getMatricula(2);
  14. System.out.print("Cost de la matricula " + matricula.costMatricula());
  15. }
  16. }

Una possible solució del codi refactoritzat és el que es mostra a continuació.

El codi corresponent a l’assignatura:

  1. package ioc.desenvolupament;
  2.  
  3. public class Assignatura {
  4.  
  5. //Declaració de variables locals
  6. private long id = 0;
  7. private String nom = "";
  8. private int hores = 0;
  9. private int credits = 0;
  10. private boolean disponible = false;
  11.  
  12. public Assignatura(long id, String nom, int hores, int credits, boolean disponible) {
  13. this.id = id;
  14. this.nom = nom;
  15. this.hores = hores;
  16. this.credits = credits;
  17. this.disponible = disponible;
  18. }
  19.  
  20. public long getId() {
  21. return id;
  22. }
  23.  
  24. public void setId(long id) {
  25. this.id = id;
  26. }
  27.  
  28. public String getNom() {
  29. return nom;
  30. }
  31.  
  32. public void setNom(String nom) {
  33. this.nom = nom;
  34. }
  35.  
  36. public int getHores() {
  37. return hores;
  38. }
  39.  
  40. public void setHores(int hores) {
  41. this.credits = hores;
  42. }
  43.  
  44. public int getCredits() {
  45. return credits;
  46. }
  47.  
  48. public void setCredits(int credits) {
  49. this.credits = credits;
  50. }
  51.  
  52. public boolean getDisponible() {
  53. return disponible;
  54. }
  55.  
  56. public void setDisponible(boolean disponible) {
  57. this.disponible = disponible;
  58. }
  59. }

El codi corresponent a l’estudiant (desfragmentant la classe matrícula en dues: matrícula i estudiant):

  1. package ioc.desenvolupament;
  2.  
  3. public class Estudiant {
  4.  
  5. private long id = 0;
  6. private String nom = "";
  7. private String cognoms = "";
  8. private String dni = "";
  9.  
  10. public Estudiant(){}
  11.  
  12. public Estudiant(long id, String nom, String cognoms, String dni) {
  13. this.id = id;
  14. this.nom = nom;
  15. this.cognoms = cognoms;
  16. this.dni = dni;
  17. }
  18.  
  19. public long getId() {
  20. return id;
  21. }
  22.  
  23. public void setId(long id) {
  24. this.id = id;
  25. }
  26.  
  27. public String getNom() {
  28. return nom;
  29. }
  30.  
  31. public void setNom(String nom) {
  32. this.nom = nom;
  33. }
  34.  
  35. public String getCognoms() {
  36. return cognoms;
  37. }
  38.  
  39. public void setCognoms(String cognoms) {
  40. this.cognoms = cognoms;
  41. }
  42.  
  43. public String getDNI() {
  44. return dni;
  45. }
  46.  
  47. public void setDNI(String dni) {
  48. this.dni = dni;
  49. }
  50. }

El codi corresponent a la matrícula:

  1. package ioc.desenvolupament;
  2.  
  3. import java.util.Collection;
  4. import java.util.ArrayList;
  5. import java.util.Iterator;
  6.  
  7. public class Matricula {
  8.  
  9. //Declaració de constants
  10. private static final int COST_CREDIT = 15;
  11.  
  12. //Declaració de variables locals
  13. private long id = 0;
  14. private int curs = 0;
  15. private Estudiant estudiant;
  16. private Collection assignatures;
  17.  
  18. public Matricula(long id, int curs, Estudiant estudiant, Collection assignatures) {
  19. this.id = id;
  20. this.curs = curs;
  21. this.estudiant = estudiant;
  22. this.assignatures = assignatures;
  23. }
  24.  
  25. public long getId() {
  26. return id;
  27. }
  28.  
  29. public void setId(long id) {
  30. this.id = id;
  31. }
  32.  
  33. public int getCurs() {
  34. return curs;
  35. }
  36.  
  37. public void setCurs(int curs) {
  38. this.curs = curs;
  39. }
  40.  
  41. public Estudiant getEstudiant() {
  42. return estudiant;
  43. }
  44.  
  45. public void setEstudiant(Estudiant estudiant) {
  46. this.estudiant = estudiant;
  47. }
  48.  
  49. public Collection getAssignatures() {
  50. return assignatures;
  51. }
  52.  
  53. public void setAssignatures(Collection assignatures) {
  54. this.assignatures = assignatures;
  55. }
  56.  
  57. public float costMatricula(){
  58.  
  59. float cost = 0;
  60. int credits = 0;
  61.  
  62. for (Iterator iter = assignatures.iterator(); iter.hasNext();) {
  63. Assignatura element = (Assignatura) iter.next();
  64. credits = credits + element.getCredits();
  65. }
  66.  
  67. cost = credits * COST_CREDIT;
  68. return cost;
  69. }
  70.  
  71. }

Documentació i Eclipse

L’objectiu de l’exercici consisteix a utilitzar les funcionalitats que ofereix l’IDE Eclipse a l’hora de generar documentació de forma automàtica a partir d’un codi donat.

El codi que es mostra a continuació simula el funcionament d’una calculadora amb les seves funcions habituals.

Es demana:

  • Modifica el codi de la calculadora perquè automàticament l’IDE d’Eclipse creï la documentació del codi.
  • Genera el codi font.
  1. import java.awt.BorderLayout;
  2.  
  3. public class Calculadora {
  4.  
  5. // Constants
  6. final int MAX_DIGITS = 5;
  7. final int MODE_ENTRADA = 0;
  8. final int MODE_RESULTAT = 1;
  9.  
  10. //Variables
  11. int mode;
  12. int valor1;
  13. int valor2;
  14. String operacio;
  15. boolean inicialitza_resultat;
  16.  
  17. private static Text text_resultat;
  18.  
  19. public Calculadora(boolean gui) {
  20.  
  21. //Inicialització de les variables.
  22. inicialitza();
  23.  
  24. if (gui==true) dibuixaCalculadora();
  25.  
  26. }
  27.  
  28. private void dibuixaCalculadora() {
  29.  
  30. Display display = Display.getDefault();
  31. Shell shlCalculadora = new Shell();
  32. shlCalculadora.setSize(259, 250);
  33. shlCalculadora.setText("Calculadora");
  34.  
  35. //-------------------------------------------------
  36. //Números
  37. //-------------------------------------------------
  38.  
  39. //butò amb el número 0
  40. Button button_0 = new Button(shlCalculadora, SWT.NONE);
  41. button_0.addSelectionListener(new SelectionAdapter() {
  42. @Override
  43. public void widgetSelected(SelectionEvent e) {
  44. afageixNouDigit(0);
  45. }
  46. });
  47. button_0.setText("0");
  48. button_0.setBounds(23, 163, 40, 33);
  49.  
  50. //butò amb el número 1
  51. Button button_1 = new Button(shlCalculadora, SWT.NONE);
  52. button_1.addSelectionListener(new SelectionAdapter() {
  53. @Override
  54. public void widgetSelected(SelectionEvent e) {
  55. afageixNouDigit(1);
  56. }
  57. });
  58. button_1.setText("1");
  59. button_1.setBounds(23, 124, 40, 33);
  60.  
  61. //butò amb el número 2
  62. Button button_2 = new Button(shlCalculadora, SWT.NONE);
  63. button_2.addSelectionListener(new SelectionAdapter() {
  64. @Override
  65. public void widgetSelected(SelectionEvent e) {
  66. afageixNouDigit(2);
  67. }
  68. });
  69. button_2.setText("2");
  70. button_2.setBounds(69, 124, 40, 33);
  71.  
  72. //butò amb el número 3
  73. Button button_3 = new Button(shlCalculadora, SWT.NONE);
  74. button_3.addSelectionListener(new SelectionAdapter() {
  75. @Override
  76. public void widgetSelected(SelectionEvent e) {
  77. afageixNouDigit(3);
  78. }
  79. });
  80. button_3.setText("3");
  81. button_3.setBounds(115, 124, 40, 33);
  82.  
  83. //butò amb el número 4
  84. Button button_4 = new Button(shlCalculadora, SWT.NONE);
  85. button_4.addSelectionListener(new SelectionAdapter() {
  86. @Override
  87. public void widgetSelected(SelectionEvent e) {
  88. afageixNouDigit(4);
  89. }
  90. });
  91. button_4.setText("4");
  92. button_4.setBounds(23, 85, 40, 33);
  93.  
  94. //butò amb el número 5
  95. Button button_5 = new Button(shlCalculadora, SWT.NONE);
  96. button_5.addSelectionListener(new SelectionAdapter() {
  97. @Override
  98. public void widgetSelected(SelectionEvent e) {
  99. afageixNouDigit(5);
  100. }
  101. });
  102. button_5.setText("5");
  103. button_5.setBounds(69, 85, 40, 33);
  104.  
  105. //butò amb el número 6
  106. Button button_6 = new Button(shlCalculadora, SWT.NONE);
  107. button_6.addSelectionListener(new SelectionAdapter() {
  108. @Override
  109. public void widgetSelected(SelectionEvent e) {
  110. afageixNouDigit(6);
  111. }
  112. });
  113. button_6.setText("6");
  114. button_6.setBounds(115, 85, 40, 33);
  115.  
  116. //butò amb el número 7
  117. Button button_7 = new Button(shlCalculadora, SWT.NONE);
  118. button_7.addSelectionListener(new SelectionAdapter() {
  119. @Override
  120. public void widgetSelected(SelectionEvent e) {
  121. afageixNouDigit(7);
  122. }
  123. });
  124. button_7.setText("7");
  125. button_7.setBounds(23, 46, 40, 33);
  126.  
  127. //butò amb el número 8
  128. Button button_8 = new Button(shlCalculadora, SWT.NONE);
  129. button_8.addSelectionListener(new SelectionAdapter() {
  130. @Override
  131. public void widgetSelected(SelectionEvent e) {
  132. afageixNouDigit(8);
  133. }
  134. });
  135. button_8.setBounds(69, 46, 40, 33);
  136. button_8.setText("8");
  137.  
  138. //butò amb el número 9
  139. Button button_9 = new Button(shlCalculadora, SWT.NONE);
  140. button_9.addSelectionListener(new SelectionAdapter() {
  141. @Override
  142. public void widgetSelected(SelectionEvent e) {
  143. afageixNouDigit(9);
  144. }
  145. });
  146. button_9.setText("9");
  147. button_9.setBounds(115, 46, 40, 33);
  148.  
  149. //-------------------------------------------------
  150. //Operacions
  151. //-------------------------------------------------
  152.  
  153. //butò amb l'operació de divisió
  154. Button button_12 = new Button(shlCalculadora, SWT.NONE);
  155. button_12.addSelectionListener(new SelectionAdapter() {
  156. @Override
  157. public void widgetSelected(SelectionEvent e) {
  158. executarOperador("/");
  159. }
  160. });
  161. button_12.setText("/");
  162. button_12.setBounds(178, 46, 40, 33);
  163.  
  164. //butò amb l'operació de multiplicació
  165. Button button_13 = new Button(shlCalculadora, SWT.NONE);
  166. button_13.addSelectionListener(new SelectionAdapter() {
  167. @Override
  168. public void widgetSelected(SelectionEvent e) {
  169. executarOperador("*");
  170. }
  171. });
  172. button_13.setText("*");
  173. button_13.setBounds(178, 85, 40, 33);
  174.  
  175. //butò amb l'operació de suma
  176. Button button_14 = new Button(shlCalculadora, SWT.NONE);
  177. button_14.addSelectionListener(new SelectionAdapter() {
  178. @Override
  179. public void widgetSelected(SelectionEvent e) {
  180. executarOperador("+");
  181. }
  182. });
  183. button_14.setText("+");
  184. button_14.setBounds(178, 124, 40, 33);
  185.  
  186. //butò amb l'operació de resta
  187. Button button_15 = new Button(shlCalculadora, SWT.NONE);
  188. button_15.addSelectionListener(new SelectionAdapter() {
  189. @Override
  190. public void widgetSelected(SelectionEvent e) {
  191. executarOperador("-");
  192. }
  193. });
  194. button_15.setText("-");
  195. button_15.setBounds(178, 163, 40, 33);
  196.  
  197. //butò amb l'operació de igual
  198. Button button_11 = new Button(shlCalculadora, SWT.NONE);
  199. button_11.addSelectionListener(new SelectionAdapter() {
  200. @Override
  201. public void widgetSelected(SelectionEvent e) {
  202. executarIgual();
  203. }
  204. });
  205. button_11.setText("=");
  206. button_11.setBounds(69, 163, 86, 33);
  207.  
  208. //Text on es visualitza el resultat
  209. text_resultat = new Text(shlCalculadora, SWT.BORDER);
  210. text_resultat.setText("0");
  211. text_resultat.setBounds(22, 19, 196, 21);
  212.  
  213. shlCalculadora.open();
  214. shlCalculadora.layout();
  215. while (!shlCalculadora.isDisposed()) {
  216. if (!display.readAndDispatch()) {
  217. display.sleep();
  218. }
  219. }
  220. }
  221.  
  222. public void inicialitza() {
  223. operacio = "null";
  224. valor1 = 0;
  225. valor2 = 0;
  226. mode = MODE_ENTRADA;
  227. inicialitza_resultat = true;
  228. }
  229.  
  230. public String getResultatString (){
  231. return text_resultat.getText();
  232. }
  233.  
  234. public void setResultatString(String s){
  235. text_resultat.setText(s);
  236. }
  237.  
  238. public int getResultatInt() {
  239. String resultat = text_resultat.getText();
  240. return Integer.parseInt(resultat);
  241. }
  242.  
  243. public void afageixNouDigit(int digit){
  244. if (inicialitza_resultat)
  245. setResultatString("");
  246.  
  247. String inputString = getResultatString();
  248.  
  249. if (inputString.indexOf("0") == 0){
  250. inputString = inputString.substring(1);
  251. }
  252.  
  253. if ((!inputString.equals("0") || digit > 0) && inputString.length() < MAX_DIGITS){
  254. setResultatString(inputString + digit);
  255. }
  256.  
  257. mode = MODE_ENTRADA;
  258. inicialitza_resultat = false;
  259. }
  260.  
  261. public void executarOperador(String new_operacio) {
  262.  
  263. int resultat;
  264.  
  265. if (operacio.equals("null"))
  266. {
  267. resultat = getResultatInt();
  268. valor1 = resultat;
  269. }
  270.  
  271. else
  272. {
  273. valor2 = getResultatInt();
  274. resultat = executarOperacio();
  275. mostraResultat(resultat);
  276. valor1 = resultat;
  277. }
  278.  
  279. inicialitza_resultat = true;
  280. operacio = new_operacio;
  281. }
  282.  
  283. public void executarIgual(){
  284. int resultat = 0;
  285.  
  286. valor2 = getResultatInt();
  287. resultat = executarOperacio();
  288. mostraResultat(resultat);
  289.  
  290. operacio = "null";
  291. }
  292.  
  293. public int executarOperacio() {
  294. int resultat = 0;
  295.  
  296. if (operacio.equals("/"))
  297. {
  298.  
  299. if (valor2 == 0)
  300. {
  301. JOptionPane.showMessageDialog(null, "No es pot dividir per cero", "Error", JOptionPane.ERROR_MESSAGE);
  302. operacio = "null";
  303. valor1 = 0;
  304. mode = MODE_ENTRADA;
  305. inicialitza_resultat = true;
  306. }
  307. else
  308. resultat = valor1 / valor2;
  309. }
  310.  
  311. if (operacio.equals("*"))
  312. resultat = valor1 * valor2;
  313.  
  314. if (operacio.equals("-"))
  315. resultat = valor1 - valor2;
  316.  
  317. if (operacio.equals("+"))
  318. resultat = valor1 + valor2;
  319.  
  320. return resultat;
  321. }
  322.  
  323. public void mostraResultat(int resultat){
  324. setResultatString(Integer.toString(resultat));
  325. valor1 = resultat;
  326. mode = MODE_RESULTAT;
  327. inicialitza_resultat = true;
  328. }
  329.  
  330. public static void main(String args[]) {
  331. Calculadora calculadora = new Calculadora(true);
  332. }
  333.  
  334. }

Una possibilitat seria:

  1. import java.awt.BorderLayout;
  2.  
  3. /**
  4. * Classe que simula una calculadora
  5. * @author IOC
  6. * @version 2012
  7. */
  8. public class Calculadora {
  9.  
  10. // Constants
  11. final int MAX_DIGITS = 5;
  12. final int MODE_ENTRADA = 0;
  13. final int MODE_RESULTAT = 1;
  14.  
  15. //Variables
  16. int mode;
  17. int valor1;
  18. int valor2;
  19. String operacio;
  20. boolean inicialitza_resultat;
  21.  
  22. private static Text text_resultat;
  23.  
  24. /**
  25. * Constructor.
  26. */
  27. public Calculadora(boolean gui) {
  28.  
  29. //Inicialització de les variables.
  30. inicialitza();
  31.  
  32. if (gui==true) dibuixaCalculadora();
  33.  
  34. }
  35.  
  36. /**
  37. * Creació dels constrols necessaris per la visualització de la calculadora
  38. */
  39. private void dibuixaCalculadora() {
  40.  
  41. Display display = Display.getDefault();
  42. Shell shlCalculadora = new Shell();
  43. shlCalculadora.setSize(259, 250);
  44. shlCalculadora.setText("Calculadora");
  45.  
  46. //-------------------------------------------------
  47. //Números
  48. //-------------------------------------------------
  49.  
  50. //butò amb el número 0
  51. Button button_0 = new Button(shlCalculadora, SWT.NONE);
  52. button_0.addSelectionListener(new SelectionAdapter() {
  53. @Override
  54. public void widgetSelected(SelectionEvent e) {
  55. afageixNouDigit(0);
  56. }
  57. });
  58. button_0.setText("0");
  59. button_0.setBounds(23, 163, 40, 33);
  60.  
  61. //butò amb el número 1
  62. Button button_1 = new Button(shlCalculadora, SWT.NONE);
  63. button_1.addSelectionListener(new SelectionAdapter() {
  64. @Override
  65. public void widgetSelected(SelectionEvent e) {
  66. afageixNouDigit(1);
  67. }
  68. });
  69. button_1.setText("1");
  70. button_1.setBounds(23, 124, 40, 33);
  71.  
  72. //butò amb el número 2
  73. Button button_2 = new Button(shlCalculadora, SWT.NONE);
  74. button_2.addSelectionListener(new SelectionAdapter() {
  75. @Override
  76. public void widgetSelected(SelectionEvent e) {
  77. afageixNouDigit(2);
  78. }
  79. });
  80. button_2.setText("2");
  81. button_2.setBounds(69, 124, 40, 33);
  82.  
  83. //butò amb el número 3
  84. Button button_3 = new Button(shlCalculadora, SWT.NONE);
  85. button_3.addSelectionListener(new SelectionAdapter() {
  86. @Override
  87. public void widgetSelected(SelectionEvent e) {
  88. afageixNouDigit(3);
  89. }
  90. });
  91. button_3.setText("3");
  92. button_3.setBounds(115, 124, 40, 33);
  93.  
  94. //butò amb el número 4
  95. Button button_4 = new Button(shlCalculadora, SWT.NONE);
  96. button_4.addSelectionListener(new SelectionAdapter() {
  97. @Override
  98. public void widgetSelected(SelectionEvent e) {
  99. afageixNouDigit(4);
  100. }
  101. });
  102. button_4.setText("4");
  103. button_4.setBounds(23, 85, 40, 33);
  104.  
  105. //butò amb el número 5
  106. Button button_5 = new Button(shlCalculadora, SWT.NONE);
  107. button_5.addSelectionListener(new SelectionAdapter() {
  108. @Override
  109. public void widgetSelected(SelectionEvent e) {
  110. afageixNouDigit(5);
  111. }
  112. });
  113. button_5.setText("5");
  114. button_5.setBounds(69, 85, 40, 33);
  115.  
  116. //butò amb el número 6
  117. Button button_6 = new Button(shlCalculadora, SWT.NONE);
  118. button_6.addSelectionListener(new SelectionAdapter() {
  119. @Override
  120. public void widgetSelected(SelectionEvent e) {
  121. afageixNouDigit(6);
  122. }
  123. });
  124. button_6.setText("6");
  125. button_6.setBounds(115, 85, 40, 33);
  126.  
  127. //butò amb el número 7
  128. Button button_7 = new Button(shlCalculadora, SWT.NONE);
  129. button_7.addSelectionListener(new SelectionAdapter() {
  130. @Override
  131. public void widgetSelected(SelectionEvent e) {
  132. afageixNouDigit(7);
  133. }
  134. });
  135. button_7.setText("7");
  136. button_7.setBounds(23, 46, 40, 33);
  137.  
  138. //butò amb el número 8
  139. Button button_8 = new Button(shlCalculadora, SWT.NONE);
  140. button_8.addSelectionListener(new SelectionAdapter() {
  141. @Override
  142. public void widgetSelected(SelectionEvent e) {
  143. afageixNouDigit(8);
  144. }
  145. });
  146. button_8.setBounds(69, 46, 40, 33);
  147. button_8.setText("8");
  148.  
  149. //butò amb el número 9
  150. Button button_9 = new Button(shlCalculadora, SWT.NONE);
  151. button_9.addSelectionListener(new SelectionAdapter() {
  152. @Override
  153. public void widgetSelected(SelectionEvent e) {
  154. afageixNouDigit(9);
  155. }
  156. });
  157. button_9.setText("9");
  158. button_9.setBounds(115, 46, 40, 33);
  159.  
  160. //-------------------------------------------------
  161. //Operacions
  162. //-------------------------------------------------
  163.  
  164. //butò amb l'operació de divisió
  165. Button button_12 = new Button(shlCalculadora, SWT.NONE);
  166. button_12.addSelectionListener(new SelectionAdapter() {
  167. @Override
  168. public void widgetSelected(SelectionEvent e) {
  169. executarOperador("/");
  170. }
  171. });
  172. button_12.setText("/");
  173. button_12.setBounds(178, 46, 40, 33);
  174.  
  175. //butò amb l'operació de multiplicació
  176. Button button_13 = new Button(shlCalculadora, SWT.NONE);
  177. button_13.addSelectionListener(new SelectionAdapter() {
  178. @Override
  179. public void widgetSelected(SelectionEvent e) {
  180. executarOperador("*");
  181. }
  182. });
  183. button_13.setText("*");
  184. button_13.setBounds(178, 85, 40, 33);
  185.  
  186. //butò amb l'operació de suma
  187. Button button_14 = new Button(shlCalculadora, SWT.NONE);
  188. button_14.addSelectionListener(new SelectionAdapter() {
  189. @Override
  190. public void widgetSelected(SelectionEvent e) {
  191. executarOperador("+");
  192. }
  193. });
  194. button_14.setText("+");
  195. button_14.setBounds(178, 124, 40, 33);
  196.  
  197. //butò amb l'operació de resta
  198. Button button_15 = new Button(shlCalculadora, SWT.NONE);
  199. button_15.addSelectionListener(new SelectionAdapter() {
  200. @Override
  201. public void widgetSelected(SelectionEvent e) {
  202. executarOperador("-");
  203. }
  204. });
  205. button_15.setText("-");
  206. button_15.setBounds(178, 163, 40, 33);
  207.  
  208. //butò amb l'operació de igual
  209. Button button_11 = new Button(shlCalculadora, SWT.NONE);
  210. button_11.addSelectionListener(new SelectionAdapter() {
  211. @Override
  212. public void widgetSelected(SelectionEvent e) {
  213. executarIgual();
  214. }
  215. });
  216. button_11.setText("=");
  217. button_11.setBounds(69, 163, 86, 33);
  218.  
  219. //Text on es visualitza el resultat
  220. text_resultat = new Text(shlCalculadora, SWT.BORDER);
  221. text_resultat.setText("0");
  222. text_resultat.setBounds(22, 19, 196, 21);
  223.  
  224. shlCalculadora.open();
  225. shlCalculadora.layout();
  226. while (!shlCalculadora.isDisposed()) {
  227. if (!display.readAndDispatch()) {
  228. display.sleep();
  229. }
  230. }
  231. }
  232.  
  233. /**
  234. * Inicialització de les variables de la calculadora
  235. */
  236. public void inicialitza() {
  237. operacio = "null";
  238. valor1 = 0;
  239. valor2 = 0;
  240. mode = MODE_ENTRADA;
  241. inicialitza_resultat = true;
  242. }
  243.  
  244. /**
  245. * Retorna el valor del camp text_resultat com un valor de text
  246. * @return text_resultat
  247. */
  248. public String getResultatString (){
  249. return text_resultat.getText();
  250. }
  251.  
  252. /**
  253. * Assigna un valor al camp text_resultat
  254. * @param s nou valor del camp
  255. */
  256. public void setResultatString(String s){
  257. text_resultat.setText(s);
  258. }
  259.  
  260. /**
  261. * Retorna el valor del camp text_resultat com un valor numèric
  262. * @return resultat
  263. */
  264. public int getResultatInt() {
  265. String resultat = text_resultat.getText();
  266. return Integer.parseInt(resultat);
  267. }
  268.  
  269. /**
  270. * Afageix un nou dígit al camp text_resultat.
  271. * Permetent realitzar operacions amb nombres de més d'un dígit.
  272. * @param digit
  273. */
  274. public void afageixNouDigit(int digit){
  275. if (inicialitza_resultat)
  276. setResultatString("");
  277.  
  278. String inputString = getResultatString();
  279.  
  280. if (inputString.indexOf("0") == 0){
  281. inputString = inputString.substring(1);
  282. }
  283.  
  284. if ((!inputString.equals("0") || digit > 0) && inputString.length() < MAX_DIGITS){
  285. setResultatString(inputString + digit);
  286. }
  287.  
  288. mode = MODE_ENTRADA;
  289. inicialitza_resultat = false;
  290. }
  291.  
  292. /**
  293. * Únicament en el cas de poder executar l'operació, s'han assignat els dos operands
  294. * és quan el sistema realitza la crida d'execució.
  295. * @param operacio que pot contenir els valors: +, -, /, *
  296. */
  297. public void executarOperador(String new_operacio) {
  298.  
  299. int resultat;
  300.  
  301. if (operacio.equals("null"))
  302. {
  303. resultat = getResultatInt();
  304. valor1 = resultat;
  305. }
  306.  
  307. else
  308. {
  309. valor2 = getResultatInt();
  310. resultat = executarOperacio();
  311. mostraResultat(resultat);
  312. valor1 = resultat;
  313. }
  314.  
  315. inicialitza_resultat = true;
  316. operacio = new_operacio;
  317. }
  318.  
  319. /**
  320. * Al finalitzar el càlcul s'executa la darrera operació especificada
  321. * i es visualitza el resultat
  322. */
  323. public void executarIgual(){
  324. int resultat = 0;
  325.  
  326. valor2 = getResultatInt();
  327. resultat = executarOperacio();
  328. mostraResultat(resultat);
  329.  
  330. operacio = "null";
  331. }
  332.  
  333. /**
  334. * Execució de la operació que pot ser una suma, resta, divisió o multiplicació.
  335. * Es controla l'error de dividir per zero.
  336. */
  337. public int executarOperacio() {
  338. int resultat = 0;
  339.  
  340. if (operacio.equals("/"))
  341. {
  342.  
  343. if (valor2 == 0)
  344. {
  345. JOptionPane.showMessageDialog(null, "No es pot dividir per cero", "Error", JOptionPane.ERROR_MESSAGE);
  346. operacio = "null";
  347. valor1 = 0;
  348. mode = MODE_ENTRADA;
  349. inicialitza_resultat = true;
  350. }
  351. else
  352. resultat = valor1 / valor2;
  353. }
  354.  
  355. if (operacio.equals("*"))
  356. resultat = valor1 * valor2;
  357.  
  358. if (operacio.equals("-"))
  359. resultat = valor1 - valor2;
  360.  
  361. if (operacio.equals("+"))
  362. resultat = valor1 + valor2;
  363.  
  364. return resultat;
  365. }
  366.  
  367. /**
  368. * Mostra el resultat de les oeperacions realitzades.
  369. * @param resultat
  370. */
  371. public void mostraResultat(int resultat){
  372. setResultatString(Integer.toString(resultat));
  373. valor1 = resultat;
  374. mode = MODE_RESULTAT;
  375. inicialitza_resultat = true;
  376. }
  377.  
  378. /**
  379. * Inici en l'execució de la calculadora.
  380. * @param args[]
  381. */
  382. public static void main(String args[]) {
  383. Calculadora calculadora = new Calculadora(true);
  384. }
  385.  
  386. }

La documentació generada seria la que es mostra a continuació:

Anar a la pàgina següent:
Exercicis