Omet navegació

Exercicis

Exercici 3_1

En el projecte anomenat Tema3, crea't un paquet anomenat Exercicis on col·locarem tot el relatiu als exercicis d'aquest tema. Copia't dins del projecte el fitxer Rutes.dat que us passarà el professor. En ell tenim dades prèviament guardades que seran unes rutes consistents en una sèrie de punts amb una descripció. Cada punt seran unes coordenades (com en un mapa).

L'estructura de les dades guardades és la següent

  • nom de la ruta (string)
  • desnivell (int)
  • desnivell acumulat (int)
  • número de punts (int)
  • Per cada punt:
    • nom (string)
    • latitud (double)
    • longitud (double)

Observa que la quarta dada és un enter amb el número de punts de la ruta.

Fes una classe executable (amb main) anomenada Llegir_Rutes_Serial que agafe les dades del fitxer (hi ha 2 rutes, però ho heu de fer genèric per a un número indeterminat de rutes) i les traga per pantalla amb aquest aspecte:

Ruta: Pujada a Penyagolosa
Desnivell: 530
Desnivell acumulat: 530
Té 5 punts
Punt 1: Sant Joan (40.251036,-0.354223)
Punt 2: Encreuament (40.25156,-0.352507)
Punt 3: Barranc de la Pegunta (40.247318,-0.351713)
Punt 4: El Corralico (40.231708,-0.348859)
Punt 5: Penyagolosa (40.222632,-0.350339)

Ruta: La Magdalena
Desnivell: 51
Desnivell acumulat: 84
Té 7 punts
Punt 1: Primer Molí (39.99385,-0.032941)
Punt 2: Segon Molí (39.99628,-0.029427)
Punt 3: Caminàs (40.00513,-0.022569)
Punt 4: Riu Sec (40.006765,-0.02237)
Punt 5: Sant Roc (40.017906,-0.02289)
Punt 6: Explanada (40.034048,-0.00633)
Punt 7: La Magdalena (40.034519,-0.005856)

Exercici 3_2

Construeix les següents classes:

Coordenades, que implementarà Serializable (i que és convenient posar-li el número de versió per defecte: private static final long serialVersionUID = 1L;), i que contindrà:

  • latitud (double)
  • longitud (double)

Haurà de tenir un constructor public Coordenades(double latitud, double longitud)

Haurà de tenir també els mètodes public double getLatitud() i public double getLongitud().

Encara que no ens faran falta del tot, crea també els mètodes set, és a dir void setLatitud(double) i setLongitud(double).


PuntGeo, que implementarà Serializable (i que és convenient posar-li el número de versió per defecte: private static final long serialVersionUID = 1L;), i que contindrà:

  • nom (String)
  • coord (Coordenades)

Haurà de tenir dos constructors:

  • public PuntGeo(String nom, Coordenades coord)
  • public PuntGeo(String nom, double latitud, double longitud)

Nota importantíssima

Els dos constructors han d'aconseguir que estiga creat un objecte del tipus Coordenades

Haurà de tenir també els mètodes

  • public String getNom()
  • public Coordenades getCoord
  • public double getLatitud() (per a major comoditat)
  • public double getLongitud()  (per a major comoditat)

Ruta . Aquesta classe us la passarà el professor.

També implementa Serializable i conté:

  • nom (String)
  • llistaDePunts: un ArrayList de PuntGeo
  • desnivell (int)
  • desnivellAcumulat (int)

Observa com té els mètodes get i set per a les propietats normals, i que per a l'ArrayList de punts té els mètodes addPunt (afegirà un nou PuntGeo a la llista) i a banda de getLlistaPunts() que torna tota la llista en un array, també té per a major comoditat getPunt(int), al qual se li passa un número i torna aquest punt. També té getPuntNom(int), getPuntLatitud(int)getPuntLongitud(int) als quals se'ls passa l'índex del punt que es vol i tornarà el nom, latitud o longitud respectivament. També té el mètode length() que ens dóna el número de punts guardats en la llista.

Fes un mètode nou en la classe Ruta anomenat mostraRuta, que mostre el contingut de la ruta amb aquest aspecte:

Ruta: Pujada a Penyagolosa
Desnivell: 530
Desnivell Acumulat: 530
Té 5 punts
Punt 1: Sant Joan (40.251036,-0.354223)
Punt 2: Encreuament (40.25156,-0.352507)
Punt 3: Barranc de la Pegunta (40.247318,-0.351713)
Punt 4: El Corralico (40.231708,-0.348859)
Punt 5: Penyagolosa (40.222632,-0.350339)


Per últim en una última classe PassarRutesSerialObj (executable, és a dir amb main) agafa el fitxer Rutes.dat , guarda la informació en un objecte Ruta, visualitza la seua informació amb mostraRuta i per últim guarda la informació de l'objecte en un fitxer anomenat Rutes.obj

Exercici 3_3

Fer una classe anomenada PassarRutesObjXML (amb main) que passe el fitxer Rutes.obj a un fitxer XML anomenat Rutes.xml amb aquest aspecte. Els punts suspensius indiquen que hi ha més d'un punt eb cada ruta, i que hi ha més d'una ruta

<rutes>
<ruta>
<nom>Pujada a Penyagolosa</nom>
<desnivell>530</desnivell>
<desnivellAcumulat>530</desnivellAcumulat>
<punts>
<punt num="1">
<nom>Sant Joan</nom>
<latitud>...</latitud>
<longitud>...</longitud>
</punt>
...
</punts>
</ruta>
...
</rutes>

Exercici 3_4

Fer una aplicació gràfica que llegirà el fitxer Rutes.xml per a que apareguen els noms de les rutes en un JComboBox. Quan se seleccione una, ha d'aparèixer la llista de punts (nom, latitud i longitud) en un JTextArea. L'aspecte podria ser el següent:

Hi ha dos mètodes per a saber quin és l'element seleccionat del JComboBox:

  • getSelectedItem() torna un String amb l'element seleccionat
  • getSelectedIndex() torna un enter amb el número d'ordre de l'element seleccionat (0 per al primer; 1 per al segon; ...)

Observeu com en aquest cas ens convé getSelectedIndex(), ja que el número d'ordre de l'element seleccionat serà el mateix que el número d'ordre de la ruta que busquem en el NodeList doc.getElementsByTagName("ruta")

L'esquelet del programa seria aquest (si voleu el podeu fer directament vosaltres amb WindowBuilder):

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

import org.w3c.dom.Document;


public class Vis_Rutes_XML_Pantalla extends JFrame implements ActionListener{
    
    JComboBox combo;
    JTextArea area = new JTextArea();
    Document doc;
    
    public void iniciar(){
        // sentències per a omplir doc
        
        
        this.setBounds(100, 100, 450, 300);
        this.setLayout(new BorderLayout());
        
        JPanel panell1 = new JPanel(new FlowLayout());
        JPanel panell2 = new JPanel(new BorderLayout());
        this.add(panell1,BorderLayout.NORTH);
        this.add(panell2,BorderLayout.CENTER);
        
        ArrayList<String> llista_rutes = new ArrayList<String>();
        // sentències per a omplir l'ArrayList amb el nom de les rutes
        
        
        combo = new JComboBox(llista_rutes.toArray());
        
        panell1.add(combo);
        
        panell2.add(new JLabel("LLista de punts de la ruta:"),BorderLayout.NORTH);
        panell2.add(area,BorderLayout.CENTER);
        
        this.setVisible(true);
        combo.addActionListener(this);
        
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == combo){
            //accions quan s'ha seleccionat un element del combobox, i que han de consistir en omplir el JTextArea
        
            
        }
    }
}

I el programa principal que crida a aquest JFrame:

public class Vis_Rutes_XML {

    public static void main(String[] args) {
        Vis_Rutes_XML_Pantalla finestra = new Vis_Rutes_XML_Pantalla();
        finestra.iniciar();
    }
}

Exercici 3_5

Fer una classe anomenada PassarRutesObjJSON (amb main) que passe el fitxer Rutes.obj a un fitxer JSON Rutes.json amb aquest aspecte:

{ "rutes" :
[
{"nom":"Pujada a Penyagolosa" ,
 "desnivell":530 ,
 "desnivellAcumulat":530 ,
 "punts":
        [  {"num":1" ,
"nom":"Sant Joan" ,
"latitud": ... ,
"longitud": ...
  } ,
...
]
 } ,
 ...
]
}

Exercici 3_6

Replicar l'exercici 3_4, però ara llegint del fitxer Rutes.json, en compte de Rutes.obj

Fer una aplicació gràfica que llegirà el fitxer Rutes.json i que aparega el nom de les rutes en un JComboBox. Quan se seleccione una, ha d'aparèixer la llista de punts (nom, latitud i longitud) en un JTextArea. L'aspecte podria ser el següent:

Hi ha dos mètodes per a saber quin és l'element seleccionat del JComboBox:

  • getSelectedItem() torna un String amb l'element seleccionat
  • getSelectedIndex() torna un enter amb el número d'ordre de l'element seleccionat (0 per al primer; 1 per al segon; ...)

Observeu com en aquest cas, igual que en l'exercici 3_4, ens convé getSelectedIndex(), ja que el número d'ordre de l'element seleccionat serà el mateix que el número d'ordre de la ruta que busquem en el JsonArray rutes (que és una propietat on us convé posar les rutes en el moment d'inicialitzar, i així tenir-les a mà en tot el programa)

L'esquelet del programa seria aquest (si voleu el podeu fer directament vosaltres amb WindowBuilder):

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

import com.github.cliftonlabs.json_simple.JsonArray;
import com.github.cliftonlabs.json_simple.JsonObject;


public class Vis_Rutes_JSON_Pantalla extends JFrame implements ActionListener{
    
    JComboBox combo;
    JTextArea area = new JTextArea();
    
    JsonObject arrel;
    JsonArray rutes;
    
    public void iniciar() throws FileNotFoundException, IOException {
        // sentències per a omplir arrel i rutes
        
        
        this.setBounds(100, 100, 450, 300);
        this.setLayout(new BorderLayout());
        
        JPanel panell1 = new JPanel(new FlowLayout());
        JPanel panell2 = new JPanel(new BorderLayout());
        this.add(panell1,BorderLayout.NORTH);
        this.add(panell2,BorderLayout.CENTER);
        
        ArrayList<String> llista_rutes = new ArrayList<String>();
        // sentències per a omplir l'ArrayList amb el nom de les rutes

        
        combo = new JComboBox(llista_rutes.toArray());
        
        panell1.add(combo);
        
        panell2.add(new JLabel("LLista de punts de la ruta:"),BorderLayout.NORTH);
        panell2.add(area,BorderLayout.CENTER);
        
        this.setVisible(true);
        combo.addActionListener(this);
        
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == combo){
            //accions quan s'ha seleccionat un element del combobox, i que han de consistir en omplir el JTextArea

        
        }
    }
}

I el programa principal quedaria així

import java.io.FileNotFoundException;
import java.io.IOException;

public class Vis_Rutes_JSON {

    public static void main(String[] args) throws FileNotFoundException, IOException {
        Vis_Rutes_JSON_Pantalla finestra = new Vis_Rutes_JSON_Pantalla();
        finestra.iniciar();
    }
}

Exercici 3_7 (voluntari)

Per a practicar un poquet més, anem a fer un altre exercici per a construir un fitxer JSON.

Feu la classe amb main PassarCotxesXMLJSON, que haurà de passar el fitxer cotxes.xml al fitxer cotxes.json. Aquest és el fitxer cotxes.xml:

<oferta>
  <vehiculo>
    <marca>ford</marca>
    <modelo color="gris">focus</modelo>
    <motor combustible="gasolina">duratorc 1.4</motor>
    <matricula>1234AAA</matricula>
    <kilometros>12500</kilometros>
    <precio_inicial>12000</precio_inicial>
    <precio_oferta>10000</precio_oferta>
    <extra valor="250">pintura metalizada</extra>
    <extra valor="300">llantas</extra>
    <foto>11325.jpg</foto>
    <foto>11326.jpg</foto>
  </vehiculo>
  <vehiculo>
    <marca>ford</marca>
    <modelo color="gris">focus</modelo>
    <motor combustible="diesel">duratorc 2.0</motor>
    <matricula>1235AAA</matricula>
    <kilometros>125000</kilometros>
    <precio_inicial>10000</precio_inicial>
    <precio_oferta>9000</precio_oferta>
    <extra valor="250">pintura metalizada</extra>
    <extra valor="200">spoiler trasero</extra>
    <extra valor="500">climatizador</extra>
    <foto>11327.jpg</foto>
    <foto>11328.jpg</foto>
  </vehiculo>
</oferta>

I aquest ha de ser l'aspecte de cotxes.json:

{
  "oferta": {
    "vehiculo": [
      {
        "marca": "ford",
        "modelo": {
          "color": "gris",
          "nombre_modelo": "focus"
        },
        "motor": {
          "combustible": "gasolina",
          "nombre_motor": "duratorc 1.4"
        },
        "matricula": "1234AAA",
        "kilometros": "12500",
        "precio_inicial": "12000",
        "precio_oferta": "10000",
        "extra": [
          {
            "valor": "250",
            "nombre_extra": "pintura metalizada"
          },
          {
            "valor": "300",
            "nombre_extra": "llantas"
          }
        ],
        "foto": [
          "11325.jpg",
          "11326.jpg"
        ]
      },
      {
        "marca": "ford",
        "modelo": {
          "color": "gris",
          "nombre_modelo": "focus"
        },
        "motor": {
          "combustible": "diesel",
          "nombre_motor": "duratorc 2.0"
        },
        "matricula": "1235AAA",
        "kilometros": "125000",
        "precio_inicial": "10000",
        "precio_oferta": "9000",
        "extra": [
          {
            "valor": "250",
            "nombre_extra": "pintura metalizada"
          },
          {
            "valor": "200",
            "nombre_extra": "spoiler trasero"
          },
          {
            "valor": "500",
            "nombre_extra": "climatizador"
          }
        ],
        "foto": [
          "11327.jpg",
          "11328.jpg"
        ]
      }
    ]
  }
}

Exercici 3.8 (voluntari)

Visualitzar en un programa gràfic l'estat actual de Bicicas, agafant-lo directament de la pàgina http://gestiona.bicicas.es/apps/apps.php.

  • En el mètode agafarBicicas() farem les instruccions per agafar-lo directament d'Internet, utilitzant un URL, el qual:
  • Inicialitzarem amb la pàgina que busquem
  • Obrim la connexió amb el mètode openConnection()
  • Després obtindrem el contingut amb el mètode getInputStream(), que com el seu nom indica serà un InputStream
  • En el mètode mostrarEstacions() introduirem les instruccions per a visualitzar les estacions, utilitzant un JList (el que està a la part de l'esquerra), que s'ha de construir a partir d'un DefaultListModel. Per anar col·locant els diferents elements del JList, els haurem d'anar afagint al DefaultListModel, i aniran apareixent en el JList. Intentarem mostrar el número d'estació, nom i número de bicicletes (posicions ocupades) i el total de posicions.
  • El mètode visualitzaEstacio() s'activa quan seleccionem un element del JList, i en ell mostrarem les propietats de l'estació seleccionada en el TextArea que està a la part de la dreta.

Aquest seria l'aspecte:

Aquest és l'esquelet del programa:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JLabel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.github.cliftonlabs.json_simple.JsonArray;
import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.JsonObject;
import com.github.cliftonlabs.json_simple.Jsoner;


public class Pantalla_Vis_Bicicas_Json_JList extends JFrame implements ListSelectionListener {

    private static final long serialVersionUID = 1L;
    DefaultListModel listModel = new DefaultListModel();
    JList list = new JList(listModel); 
    JTextArea area = new JTextArea(5,15);
    
    JsonObject arrel;
    JsonArray estacions;
   
    public void iniciar() throws JsonException, IOException {
        this.setBounds(100, 100, 450, 300);
        this.setLayout(new BorderLayout());

        JPanel panell1 = new JPanel(new GridLayout(1,2));
        JPanel panell2 = new JPanel(new FlowLayout());
        this.add(panell1,BorderLayout.CENTER);
        this.add(panell2,BorderLayout.NORTH);
        list.setForeground(Color.blue);
        JScrollPane scroll1 = new JScrollPane(list);
        panell1.add(scroll1);
        JScrollPane scroll2 = new JScrollPane(area);
        panell1.add(scroll2);
        
        JLabel et1 = new JLabel("Llistat actual de BICICAS");
        panell2.add(et1);
        

        agafarBicicas(); 
        
        mostrarEstacions();

        setVisible(true);
        
        list.addListSelectionListener(this);
    }

    
    @Override
    public void valueChanged(ListSelectionEvent e){
        JList l = (JList) e.getSource();
        if (l.getSelectedIndex()>=0){
            visualitzaEstacio(l.getSelectedValue().toString());
        }
    }

    private void agafarBicicas() throws JsonException, IOException {
    	// Instruccions per a llegir de la pàgina de Bicicas i col·locar en arrel
    	URL bicicas = new URL("http://gestiona.bicicas.es/apps/apps.php");
        JsonArray arrel = (JsonArray) Jsoner.deserialize(new InputStreamReader(bicicas.openConnection().getInputStream()));
        // Instruccions per a col·locar les estacions en estacions (JsonArray)
        
    }

    private void mostrarEstacions() {
        // Instruccions per a introduir en el JList les estacions
        // La manera d'anar introduint informació en el JList és a través del DefaultListModel:
        // listModel.addElement("Linia que es vol introduir ")
    	
    }
    
    private void visualitzaEstacio(String estacio){
        // Instruccions per a mostrar les característiques en el area, el JTextArea de la dreta
       
    }
}

I aquest seria el programa principal:

import java.io.FileNotFoundException;
import java.io.IOException;

import org.json.simple.parser.ParseException;

public class Vis_Bicicas_Json_JList {

    public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
        Vis_Rutes_JSON_Pantalla finestra = new Vis_Rutes_JSON_Pantalla();
        finestra.iniciar();
    }
}