View Full Version : [Java] convertitore che non converte
premetto, non conosco java.
per forza di cose però mi vedo costretto a scrivere un programma. :muro:
ecco quello che sono riuscito a mettere insieme fino ad ora.
il problema principale è che non ho idea di come gestire la parte relativa alla conversione.
se qualcuno potesse aiutarmi a completarlo gliene sarei davvero grato.
sottolineo che sono alla ricerca della massima semplicità, niente di troppo "avanzato".
Un up per un amico che aiuterei volentieri se potessi :)
Apix_1024
11-02-2007, 00:05
up per due compaesani in mezzo a tutti questi utenti!!! :D :D
Puoi creare una classe tipo:
public class ConvertitoreUnità {
private final double FATTORE_DI_CONVERSIONE;
public ConvertitoreUnità(double fattoreDiConversione) {
FATTORE_DI_CONVERSIONE = fattoreDiConversione;
}
public double converti(double valore) {
return valore * FATTORE_DI_CONVERSIONE;
}
public double inverti(double valore) {
return valore / FATTORE_DI_CONVERSIONE;
}
}
Poi crei tre convertitori: pascalPascal, pascalBar, pascalMMHG. Li associ nella mappa a tre chiavi, "Pascal", "Bar" e "MMHG". Facciamo finta che questi siano i valore contenuti nel modello delle JComboBox. Dato il valore "i" del campo di testo in formato numerico, applichi prima l'inversa per ottenere la conversione ad una misura comune (Pascal):
Convertitore c = mappaConvertitore.get(startC.getSelectedValue());
double valoreIntermedio = c.inverit(i);
Poi prendi il convertitore associato al valore corrente della seconda JComboBox:
Convertitore c = mappaConvertitore.get(endC.getSelectedValue());
e applichi la conversione da Pascal a quello che deve essere:
double valoreConvertito = c.converti(valoreIntermedio);
Probabilmente è meglio se usi dei BigDecimal, così eviti valori strambi.
scusa la mia ingoranza ma...
1 - cosa intendi per mappa?
2 - la classe dove la devo inserire? in una altro file, nello stesso file (ma dove!?)
3 - in che senso creare tre convertitori?
ovviamente grazie per la risposta.
Per creare tre convertitori intendo:
ConvertitoreUnità pascalPascal = new ConvertitoreUnità(1);
ConvertitoreUnità pascalBar = new ConvertitoreUnità(0.0001);
ConvertitoreUnità pascalMMHG = new ConvertitoreUnità(0.0075);
Per mappa l'omonima struttura dati. Ad esempio:
Map<String, ConvertitoreUnità> mappaConvertitoriPressione =
new HashMap<String, ConvertitoreUnità>();
Dichiara questa mappa come campo private della classe "convertitore"
Nella mappa metti i tre riferimenti ai converititori di pressione suddetti. Per la chiave puoi usare gli stessi valori che userai per le caselle combinate (JComboBox della pressione). Ad esempio:
mappaConvertitoriPressione.put("Pascal (Pa)", pascalPascal);
mappaConvertitoriPressione.put("Bar", pascalBar);
mappaConvertitoriPressione.put("Millimetri di mercurio (mmHg)", pascalMMHG);
Metti la creazione dei tre converitori e la loro associazione nella mappa dei convertitori di pressione nel costruttore di "convertitore".
Nel metodo actionPerformed, nel blocco if che corrisponde alla richiesta di conversione della pressione (if(source == convert)) devi:
1. determinare se è richiesta una conversione della pressione.
Puoi farlo guardando se il modello delle caselle combinate è quello della pressione
2. Ottenere il convertitore corrispondente al valore immesso nella prima casella combinata:
ConvertitoreUnità conv = mappaConvertitoriUnità.get((String)startc.getSelectedItem());
3. invertire il valore numerico presente nel campo di testo dove l'utente scrive
String textValue = valuet.getText();
double value = Double.parseDouble(textValue);
value = conv.inverti(value);
3. Ottenere il convertitore corrispondente al valore immesso nella seconda casella combinata
conv = mappaConvertitoriUnità.get((String)endc.getSelectedItem());
4. convertire il valore numerico precedente:
value = conv.converti(value);
A questo punto value sarà il valore convertito dalla prima unità di misura alla seconda (teoricamente :D).
La classe ConvertitoreUnità la scrivi un file sorgente a sè stante, nella stessa cartella di "convertitore.java".
ci lavoro un po' e vediamo cosa viene fuori.
grazie ancora per la disponibilità.
Dichiara questa mappa come campo private della classe "convertitore"
dubbi su questo punto.
nel senso che non so come fare la dichiarazione.
abbi pazienza...;)
Nessun problema.
"campo" sta per variabile immediatamente dichiarata nel corpo della classe. Il corpo di una classe è quella parte del file sorgente che inizia subito dopo la prima parentesi graffa e termina subito prima della corrispondente parentesi graffia di chiusura. Ad esempio:
public class convertitore {//qui inizia il corpo
//qui è sempre corpo della classe
public convertitore() {//qui inizia il corpo del costruttore
/*qui finisce il corpo del costruttore*/}
//qui siamo ancora nel corpo della classe
/*qui finisce il corpo della classe*/}
Tutto quello che è scritto nella classe sta nel suo corpo, compreso il corpo del costruttore dunque tutto quanto è dichiarato nel corpo della classe. Non tutto è immediatamente dichiarato nel corpo. Ad esempio in:
public class convertitore {
private int campo = 10;
public convertitore() {
int variabileLocale = 25;
}
}
le dichiarazioni di variabile "int campo" e "int variabileLocale" sono entrambe contenute nel corpo della classe convertitore ma il contenimento della dichiarazione di variabile "variabileLocale" è mediato dal corpo del costruttore mentre il contenimento della dichiarazione di variabile "campo" è immediato cioè tra la dichiarazione di questa variabile e il corpo della classe non c'è un corpo intermedio.
L'immediatezza del contenimento di una dichiarazione di variabile rispetto al corpo della classe in cui è dichiarata è ciò che distingue un campo da una variabile locale.
Così quando dico "dichiara questa mappa come campo privato della classe convertitore" (più propriamente avrei dovuto dire come campo privato delle istanze della classe convertitore) intendo scrivi la dichiarazione di variabile:
private Map<String, ConvertitoreUnità> mappaConvertitoriUnità = eccetera
in modo che sia immediatamente contenuta nel corpo della classe convertitore. Convenzionalmente, come hai già fatto, le dichiarazioni di campo sono scritte subito dopo la parentesi di apertura del corpo della classe in cui intervengono.
non riesco bene ad afferrare la funzione della nuova classe ConvertitoreUnita.
a questa classe viene delegato il compito di svolgere la conversione?
però non capisco che cosa devo metterci dentro.
purtroppo mi manca la logica stessa del java... :(
A scanso di equivoci, non hai un problema con il linguaggio. Nè hai un problema con la prospettiva orientata agli oggetti. Hai un problema... con me :D.
Non voglio trascinarti in un dibattito per cui la faccio breve. Ogni programma orientato agli oggetti è la traduzione della soluzione "umana" di un problema. La ragione per cui ConvertitoreUnità ti pare un alieno nel sistema è che la sua necessità sorge perchè io ho risolto il problema della conversione in un certo modo e la rappresentazione di questa mia soluzione richiede, appunto, che esista questo tipo di oggetti.
Essendo la mia soluzione, e non la tua, e non avendo discusso di come ho risolto il problema, mi pare assolutamente normale che ConvertitoreUnità ti sembri utile quanto una terza natica (che poeta, eh!? :D).
ConvertitoreUnità fa esattamente quello che hai notato: converte un valore da un'unità di misura ad un'altra e viceversa.
L'idea è che se ho tre unità di misura e ne scelgo una (pascal) come unità che tutti quanti i convertitori conoscono (cioè tutti sanno convertire da X a Pascal e da Pascal a X) allora anzichè avere bisogno di NxN convertitori che trasformano un valore da X a Y mi bastano N convertitori da X a Pascal. La conversione tra due unità di misura X e Y viene fatta applicando il convertitore da X a Pascal e poi applicando il convertitore da Pascal a X.
Se ogni converitore è in grado di cambiare l'unità di misura da X a Pascal e da Pascal a X (inverti e converti nella classe che ho proposto) e supponendo che per ogni ConvertitoreUnità:
1. "converti(valore)" trasformi un valore da Pascal alla specifica unità di misura del concreto ConverititoreUnità (Pascal, Bar, MMHg)
2. "inverti(valore)" trasformi un valore espresso nella specifica unità di misura del concreto ConvertitoreUnità (Pascal, Bar, MMHg) in Pascal
allora il problema converti un valore di pressione da un'unità di misura X ad un'unità di misura Y si risolve in:
1. prendo il convertitore che sa come trasformare i Pascal in X e viceversa
2. gli chiedo di convertire il valore espresso in X in Pascal (inverti)
3. prendo il convertitore che sa come trasformare i Pascal in Y e viceversa
4. gli chiedo di convertire il valore espresso in Pascal in Y
L'altro pezzo del problema è la classe che tu hai chiamato convertitore e che io vedo come l'oggetto che si occupa di raccogliere i dati ed eseguire la conversione. E' lui che la esegue: i vari ConvertitoreUnità hanno una capacità astratta di convertire ma concretamente non cambiano un bel niente. E' "convertitore" che passa da un valore ad un altro usando uno dei vari ConvertitoreUnità. E questo è quello che fa.
"convertitore" piglia un valore numerico V e due unità di misura X e Y. Deve trasformare il valore dalla prima (X) alla seconda (Y) unità di misura. Per farlo:
1. prende il convertitore corrispondente all'unità di misura X
2. gli passa il valore V chiedendogli di convertirlo in Pascal e ottenendo il valore VPa
3. prende il convertitore corrispondente all'unità di misura Y
4. gli passa il valore VPa chiedendogli di convertirlo in Y ottenendo Vy
5. presenta all'utente Vy
Il problema è, ribadisco, di condivisione della rappresentazione del problema risolto.
a cosa possono essere dovuti questi errori?
G:\Documenti\programma esame borromei\convertitore.java:44: ';' expected
private mappa Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita> ();
^
G:\Documenti\programma esame borromei\convertitore.java:44: <identifier> expected
private mappa Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita> ();
^
G:\Documenti\programma esame borromei\convertitore.java:44: '(' expected
private mappa Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita> ();
^
G:\Documenti\programma esame borromei\convertitore.java:44: <identifier> expected
private mappa Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita> ();
tra private e Map<String, ... c'è una parola di troppo. Non:
private mappa Map<String, eccetera
ma
private Map<String, eccetera
Perdonatemi..
up per due compaesani in mezzo a tutti questi utenti!!! :D :D
Eilà, conosco solo un fidentino che possiede un opteron e in effetti è un pazzo :D
Ciao Ariz :)
permane questo...G:\Documenti\programma esame borromei\convertitore.java:44: <identifier> expected
private Map<String, ConvertitoreUnita>
ho scritto così:private Map<String, ConvertitoreUnita>
{
mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita>();
}
Le parentesi graffe non ci vanno.
private Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita>();
se tolgo le parentesi persistono questi errori:G:\Documenti\programma esame borromei\convertitore.java:44: cannot find symbol
symbol : class Map
location: class convertitore
private Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita>();
^
G:\Documenti\programma esame borromei\convertitore.java:44: cannot find symbol
symbol : class HashMap
location: class convertitore
private Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita>();altra cosa...
quando dici di creare e associare i convertitori nella mappa intendi fare questo?private Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita>();
{
ConvertitoreUnita pascalPascal = new ConvertitoreUnita(1);
ConvertitoreUnita pascalBar = new ConvertitoreUnita(0.0001);
ConvertitoreUnita pascalMMHG = new ConvertitoreUnita(0.0075);
}
All'inizio del file sorgente, dopo la dichiarazione di package (se c'è, nel nostro caso non c'è) scrivi, in una linea a sè:
import java.util.*;
Questa dichiarazione farà sì che il compilatore, che ora ti dice che non riesce a capire cosa significhi "Map" riesca a risolvere quel nome riferendolo a java.util.Map.
Nell'ultima porzione di codice che hai incollato crei i tre convertitori. Manca l'associazione tra ognugno di quei converitori ed una chiave (una String) di identificazione nella mappa.
private Map<String, ConvertitoreUnita> mappaConvertitoriPressione = new HashMap<String, ConvertitoreUnita>();
{
ConvertitoreUnita pascalPascal = new ConvertitoreUnita(1);
ConvertitoreUnita pascalBar = new ConvertitoreUnita(0.0001);
ConvertitoreUnita pascalMMHG = new ConvertitoreUnita(0.0075);
mappaConvertitoriPressione.put("Pascal (Pa)", pascalPascal);
mappaConvertitoriPressione.put("Bar (ba)", pascalBar);
mappaConvertitoriPressione.put("Millimetri di mercurio (mmHg)", pascalMMHG);
}
come non detto, avevo messo l'associazione dove non andava fatto.
adesso funziona tutto alla grande.
non so come ringraziarti.
ovviamente però ho alcune altre domandine da farti, non volermene ;)
in pratica quando vado ad inserire un valore che non sia numerico appare il messaggio d'errore.
il messaggio però rimane anche quando, successivamente, viene inserito un valore corretto; hai un'idea di come potrei fare per farlo scomparire?
Devi affinare il campo di testo che usi per inserire il valore numerico in modo tale da impedire la ricezione di valori non trasformabili in numeri.
Puoi usare un JFormattedTextField. Dove ora dichiari:
valuet = new JTextField();
cambi in:
valuet = new JTextField(new Float(0));
JFormattedTextField opera una convalida un po' primitiva dal punto di vista dell'interazione ma dovrebbe risolvere il problema "voglio che valuet.getText() restituisca una stringa che sia sempre trasformabile in float".
un commentino ultra sintetico a questa rigaConvertitoreUnita conv = mappaConvertitoriPressione.get((String)startc.getSelectedItem());
Sempre nel caso della pressione, nella casella combinata startc hai una serie di stringhe che corrispondono alle chiavi dei convertitori di pressione nella mappa. La chiave è il valore che usi per recuperare qualcosa che immagazzini nella mappa (con mappa.put(chiave, valore)).
Nella casella combinata hai le stringhe:
"Pascal (Pa)"
"Millimetri di mercurio (mmHg)"
"Bar (ba)"
Avendo usato le stesse stringhe per i convertitori di pressione nella mappa:
mappaConvertitoriPressione.put("Pascal (Pa)", pascalPascal);
mappaConvertitoriPressione.put("Bar (ba)", pascalBar);
mappaConvertitoriPressione.put("Millimetri di mercurio (mmHg)", pascalMMHG);
ecco che, nel caso della pressione, ogni possibile valore corrente nella casella combinata ti consente di ricavare dalla mappa il ConvertitorePressione corrispondente.
String chiave = (String)startc.getSelectedValue();
ConvertitoreUnità c = mappaConvertitoriPressione.get(chiave);
condensato in:
ConvertitoreUnità c = mappaConvertitoriPressione.get((String)starc.getSelectedValue());
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.