Conversión de unidades

prev.gif (997 bytes)chapter.gif (1105 bytes)home.gif (1232 bytes)next.gif (998 bytes)

Ejemplos completos

Introducción

Un grupo de botones de radio

Disposición de los controles empleando el gestor GridBagLayout

Respuesta a la pulsación sobre un botón

Verificación de los datos introducidos en controles de edición.

Respuesta a las aciones sobre un grupo de controles botón de radio.

El código fuente


Introducción

El applet que se explica en esta página web, tiene como objetivo convertir cantidades expresadas en unidades empleadas habitualmente en Termodinámica en cantidades expresadas en unidades del Sistema Internacional. Dicho applet se emplea en el capítulo Termodinámica del Curso Interactivo de Física.

Para pasar desde el Sistema Internacional de Unidades al sistema ordinario de unidades empleado en Termodinámica, se introduce la cantidad a convertir en el control de edición situado en la parte superior izquierda del applet. Si se selecciona la unidad de origen pulsando el botón de radio situado en el panel izquierdo, la unidad de destino queda automáticamente seleccionada, salvo en el caso de la energía en la que hay una doble opción, atmósferas por litro (por defecto) o calorías. Finalmente, se pulsa el botón titulado >>>. La cantidad convertida aparece en el control de edición situado en la parte superior derecha del applet.

Para convertir desde el sistema ordinario de unidades empleado en Termodinámica al Sistema Internacional, se procede de modo inverso. Se introduce la cantidad a convertir en el control de edición situado en la parte superior derecha del applet, se elige la unidad de origen pulsando en el botón de radio correspondiente a dicha unidad, la unidad de destino queda automáticamente seleccionada. Finalmente, se pulsa el botón titulado <<<<. La cantidad convertida aparece en el control de edición situado en la parte superior izquierda del applet.

 

Un grupo de botones de radio

Para crear un grupo de botones de radio, se procede del siguiente modo

Se crea un array de objetos Checkbox

  Checkbox chkIzq[]=new Checkbox[4];

Se crea un objeto de la clase CheckboxGroup

  CheckboxGroup chkGrupoIzq=new CheckboxGroup();

En init o bien jbInit se crean cada uno de los botones de radio

for(int i=0; i<4; i++){
	chkIzq[i]=new Checkbox();
}

Se pone una etiqueta a cada uno de los botones de radio

  chkIzq[0].setLabel("Energía (J)");
  chkIzq[1].setLabel("Presión (Pa)");
  chkIzq[2].setLabel("Volumen (m3)");
  chkIzq[3].setLabel("Temperatura (ºK)");

Se asocia cada botón de radio a su grupo

for(int i=0; i<4; i++){
	chkIzq[i].setCheckboxGroup(chkGrupoIzq);
}

Se establece el estado inicial del grupo de botones de radio (recuérdese que sólo uno de los botones de radio de un grupo puede estar activado, checked)

  chkGrupoIzq.setSelectedCheckbox(chkIzq[0]);

 

Disposición de los controles empleando el gestor GirdBagLayout

En el applet se han situado dos controles de edición, dos grupos de botones de radio y dos botones. Para situar estos controles se ha empleado el gestor de diseño GridBagLayout, el más versatil y a la vez más complicado de la AWT.

La disposición de los botones de radio no es simétrica, lo que añade una mayor dificultad al manejo de este gestor de diseño. Los botones correspondientes a la misma clase de unidad deben de estar uno enfrente del otro. Esto ocurre con el volumen, la presión y la temperatura, pero no ocurre con la energía. En el Sistema Internacional de Unidades la energía se expresa en Julios, pero en Termodinámica se expresa en atmósferas por litro y en calorías. El gestor de diseño GridBagLayout nos permite poner un botón de radio en la primera columna enfrente de dos botones de radio en la segunda columna. Las líneas de código que lo hacen posible están marcadas en negrita.

     this.add(Panel2, BorderLayout.CENTER);
//Panel2
     Panel2.setLayout(gbl1);
     gbc1.anchor=GridBagConstraints.CENTER;
     gbc1.insets=new Insets(5,0,10,0);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(labelControl1, gbc1);

     gbc1.anchor=GridBagConstraints.CENTER;
     gbc1.insets=new Insets(0,0,5,0);
     gbc1.gridwidth=1;
     Panel2.add(tIzquierda, gbc1);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(tDerecha, gbc1);

     gbc1.anchor=GridBagConstraints.WEST;
     gbc1.insets=new Insets(0,5,0,5);
     gbc1.gridwidth=1;
     Panel2.add(chkIzq[0], gbc1);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(chkDcha[0], gbc1);

     gbc1.gridx=1;
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     gbl1.setConstraints(chkDcha[1], gbc1);
     Panel2.add(chkDcha[1]);

     gbc1.gridwidth=1;
     gbc1.gridx=GridBagConstraints.RELATIVE; 
     Panel2.add(chkIzq[1], gbc1);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(chkDcha[2], gbc1);

     gbc1.gridwidth=1;
     Panel2.add(chkIzq[2], gbc1);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(chkDcha[3], gbc1);

     gbc1.gridwidth=1;
     Panel2.add(chkIzq[3], gbc1);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(chkDcha[4], gbc1);

     gbc1.anchor=GridBagConstraints.CENTER;
     gbc1.gridwidth=1;
     gbc1.insets=new Insets(10,0,5,0);
     Panel2.add(btnIzquierda, gbc1);
     gbc1.gridwidth=GridBagConstraints.REMAINDER;
     Panel2.add(btnDerecha, gbc1);

 

Respuesta a la pulsación sobre un botón

El complilador JBuider nos genera automáticamente, el nombre de la función respuesta a la acción del usuario sobre un botón.

btnDerecha.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        btnDerecha_actionPerformed(e);
      }
    });
//.........

El código de la función respuesta btnDerecha_actionPerformed, realiza las siguientes tareas:

     double dcha=Double.valueOf(tDerecha.getText()).doubleValue();
     Checkbox seleccionado=chkGrupoDcha.getSelectedCheckbox();
     double izq;
     if(i==4){
          izq=dcha+factorDchaIzq[i];
     }else{
          izq=dcha*factorDchaIzq[i];
     }
     tIzquierda.setText(String.valueOf(izq));
  void btnDerecha_actionPerformed(ActionEvent e) {
     double dcha=Double.valueOf(tDerecha.getText()).doubleValue();
     Checkbox seleccionado=chkGrupoDcha.getSelectedCheckbox();
     int i=0;
     for(i=0; i<5; i++){
          if (seleccionado.equals(chkDcha[i])){
               break;
          }
     }
     double izq;
     if(i==4){
          izq=dcha+factorDchaIzq[i];
     }else{
          izq=dcha*factorDchaIzq[i];
     }
     tIzquierda.setText(String.valueOf(izq));
  }

 

Verificación de los datos introducidos en controles de edición

Para verificar que se introduce un número en el control de edición se siguen los mismos pasos que se explicaron en la página titulada verificación de la información que introduce el usuario en un control de edición

Definimos una clase que implementa el interface FocusListener y redefinimos la  función miembro focusLost en la que estamos interesados.

class ValidaDouble extends FocusAdapter{
     public void focusLost(FocusEvent ev){
          TextField tEntrada=(TextField)(ev.getSource());
          try{
               Double.valueOf(tEntrada.getText()).doubleValue();
          }catch(NumberFormatException e){
               tEntrada.requestFocus();
               tEntrada.selectAll();
          }
     }
}

El objeto ev de la clase FocusEvent guarda toda la información relativa al suceso, y en particular, la fuente o el control que lo ha generado, dicha información se extrae mediante la función getSource.

Una vez que sabemos el control de edición tEntrada que ha generado el suceso, se obtiene el texto, un objeto de la clase String, que se ha introducido en dicho control mediante la función getText. Posteriormente, se convierte el texto (los caracteres) en un número en doble precisión mediante la función doubleValue.

Si el proceso de conversión falla, por que se han introducido caracteres que no son números, o una coma en vez de un punto, se produce un excepción del tipo NumberFormatException. En este caso, el control de edición vuelve a tomar el foco requestFocus, y se selecciona todos los caracteres introducidos para que puedan ser borrados de una vez pulsando la tecla Retroceso.

	       tEntrada.requestFocus();
               tEntrada.selectAll();

Asociamos el control de edición tIzquierda con el objeto valDouble de la clase ValidaDouble que gestiona los sucesos que se producen en dicho control de edición.

    ValidaDouble valDouble=new ValidaDouble();
    tIzquierda.addFocusListener(valDouble);

 

Respuesta a las aciones sobre un grupo de controles botón de radio

Para responder a las acciones sobre un control Checkbox se ha de implementar el interface ItemListener. La clase que implementa este interface redefine la función itemStateChange. La información acerca del suceso viene encapsulada en el objeto ev de la clase ItemEvent, véase la respuesta a las acciones del usuario sobre un grupo de botones de radio. En particular, la función miembro getSource, extrae de ev el control Checkbox que ha sido activado.

public class ListenerIzq implements ItemListener{
     public void itemStateChanged(ItemEvent ev){
          Checkbox seleccionado=(Checkbox)ev.getSource();
          int i=0;
          for(i=0; i<4; i++){
               if (seleccionado.equals(chkIzq[i])){
                    break;
               }
          }
          chkDcha[i+1].setState(true);
     }
  }

Una vez que conocemos qué magnitud de la izquierda que ha sido seleccionada, itemStateChanged activa el botón de radio correspondiente a la misma magnitud en la parte derecha del applet.

Tendremos que asociar ahora los controles Checkbox de la parte izquierda del applet con el objeto la clase ListenerIzq que maneja las acciones del usuario sobre dichos controles.

for(int i=0; i<4; i++){
	chkIzq[i].addItemListener(listenerIzq);
}

Todo lo que se ha descrito para los botones de radio situados en la parte izquierda del applet se repite con pequeñas modificaciones para los botones de radio situados en la parte derecha del applet.

 

El código fuente

disco.gif (1035 bytes)ConversionApplet.java