|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
[JAVA] Aggiungere interfaccia grafica a un programma...
Ciao a tutti, in Java non ho mai lavorato con la "grafica", quindi magari quello che chiedo è assurdo.
Ho un classico programma che chiede dei dati all'utente tramite System.out.println, riceve in input i dati inseriti dall'utente, li usa per eseguire dei calcoli e stampa i risultati sempre con println sulla consolle. Se volessi modificare il programma in modo che l'utente possa inserire i dati in una finestra (che vorrei personalizzare con dei pulsanti e grafica varia) devo riscrivere tutto da capo o mi basta solo compilare un'interfaccia o estendere qualche classe predefinita che si occupi solo della grafica della finestra e effettui in automatico il reindirizzamento dell'input-output?
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7929
|
Quote:
Esiste un modello di pattern MVC(Model View Controller) che non fà altro che esprimere ciò. Ovvero separare l'interfaccia grafica dalla parte implementativa. Se il tuo programa è stato pensato bene puoi farti un controllore che gestisce la comunicazione tra grafica e software pre-esistente. tutto ciò comporta la realizzazione della parte grafica e delle piccolissime modifiche di quello preesistente ![]()
__________________
My gaming placement |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Sì ed è più facile di quanto possa sembrare. Le interfacce a linea di comando sono casi di comunicazione elementare (sincrona, di solito con una produzione). L'omologo "visuale" è la procedura guidata: una serie di componenti che si attivano in via esclusiva secondo una sequenza prestabilita.
Semplicemente, quando catturi dall'output la stringa "inserire il nome", attivi il componente X e quando l'utente preme il pulsante "successivo" sul pannello che contiene X spari il risultato attraverso System.in. Metti in pausa l'interfaccia aspetti che arrivi la risposta. Puoi usare un Pipe per connettere un flusso di output ad uno di input e viceversa. [PS] Il sì è "sì ti basta scrivere l'interfaccia e aggiungere qualche classe", non "sì MVC". |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7929
|
Quote:
![]() ![]() ![]()
__________________
My gaming placement |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Ho iniziato la risposta con "Sì" quando c'era solo la richiesta di Andrea16v. Con un'altra risposta in mezzo il "sì" poteva sembrare un assenso alla risposta di franksiska. Per non cambiare il testo sotto il naso di chi eventualmente lo stesse leggendo, ho aggiunto una postilla per chiarire che il "sì" non era riferito alla risposta che citava MVC.
Non perchè non vada bene. Non c'era quando ho scritto la risposta, dunque non potevo averla letta, dunque non potevo assentire o dissentire. Che siamo entrati nella stagione degli amori? Facciamo come gli Alci? Ci attacchiamo anche alle virgole pur di prenderci a cornate? ![]() ![]() |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7929
|
Quote:
![]() ![]() ![]() ![]() ![]() ![]() ![]()
__________________
My gaming placement |
|
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
Quote:
Per intenderci un classico form tipo quelli che si usano per registrarsi ad un servizio online, solo molto semplice, es: una classe Persona con una serie di variabili d'istanza che verranno inizializzate tramite questa finestra lasciando inserire all'utente le sue generalità, per poi premere il pulsante "invia". A questo punto, una volta assegnati i valori alle varie var. di istanza, il compito della finestra finisce. Il programma crea un'istanza di oggetto Persona chiamando l'opportuno costruttore e inserisce l'utente in un database, ecc ecc
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Ahhh, pretenzioso!
![]() ![]() In pratica la prendi per il naso. Supponi che la sequenza di interazione dell'interfaccia a linea di comando sia: 1. Inserire nome (attende l'inserimento) 2. Inserire cognome (attende l'inserimento) La finestra prima raccoglie tutti i dati in un colpo solo, poi lancia il programma a linea di comando. Aspetta che questo dica: "Inserire nome" e poi risponde con il valore del campo di testo che contiene il nome. A quel punto il programma chiederà "Inserire cognome" e tu gli rifili il cognome. In pratica fai un bot: gli rifili tutti i dati in un colpo e quello risponde automaticamente alle richieste del precedente programma. "lancia il programma a linea di comando" in senso vago. Diciamo che potresti ottenere una cosa del genere: Codice:
public void quandoLutentePremeAccetta() { ConsoleBOT bot = new ConsoleBOT(ilPacchettoDiDati); bot.scofanatiIFlussiIO(); try { ApplicazioneALineaDiComando.main(eventualiArgomentiRichiesti); } finally { bot.rilasciaIFlussiIO(); } } Ma è solo un'idea. |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7929
|
Quote:
![]() ![]() ![]() ![]() comunque è molto semplice....inizia a lavorarci e ti renderai conto da solo di quanto lo sia ![]()
__________________
My gaming placement |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
Penso di aver capito il concetto che c'è dietro, ma la struttura che hai abozzato per costruire un'implementazione mi risulta totalmente oscura..
Un oggetto ConsoleBOT è una sorta di "buffer intelligente per i flussi IO" ? Penso mi convenga prima fare un po' di pratica mastruzzando qualche programma già fatto, hai mai incocciato strada facendo qualcosa di simile a quello che vorrei fare? Magari provo a piegarlo al mio scopo, almeno non devo costruire anche la grafica da zero.. ![]()
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Bene. Siore e siori, non c'è trucco non c'è inganno, vado a dimostrare l'arcano. Donne incinte, bambini, vecchi, deboli di cuore o di stomaco son pregati di lasciare il tendone. Praticamente restiamo in due
![]() Allora, facciamo finta che il programma da linea di comando sia questo pezzo d'antologia: Codice:
import java.util.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import org.w3c.dom.*; /** Chiede un nome, chiede un cognome e li salva su un file xml*/ public class OProgrammone { public static void main(String[] args) { java.io.PrintStream out = System.out; Scanner in = new Scanner(System.in); out.println("O' Programmone, v. 1.0"); out.println("Inserire un nome"); String nome = in.nextLine(); out.println("Inserire un cognome"); String cognome = in.nextLine(); out.println("O' Programmone genera il file XML..."); try { salva(nome, cognome); out.println("Tutto è andato bene"); } catch(Exception ex) { out.println("Errore nel salvataggio"); } } private static void salva(String nome, String cognome) throws Exception { Document doc = DocumentBuilderFactory.newInstance(). newDocumentBuilder().newDocument(); Node root = doc.createElement("persona"); Node name = doc.createElement("nome"); Node nameValue = doc.createTextNode(nome); Node surname = doc.createElement("cognome"); Node surnameValue = doc.createTextNode(cognome); root.appendChild(name); name.appendChild(nameValue); root.appendChild(surname); surname.appendChild(surnameValue); String fileName = nome + "_" + cognome + ".xml"; java.io.File file = new java.io.File(fileName); DOMSource source = new DOMSource(root); StreamResult result = new StreamResult(file); TransformerFactory.newInstance().newTransformer(). transform(source, result); } } ![]() Bene! Le informazioni collezionate dal programma sono due stringhe, una per il nome e una per il cognome. Ora fingiamo di avere questi dati e di darli a un BOT che li rifili al programma secondo le sue esigenze. Questo è il pacchetto di dati che diamo al BOT: Codice:
public class BOTData { private final String name; private final String surname; public BOTData(String name, String surname) { this.name = name; this.surname = surname; } public String getName() { return name; } public String getSurname() { return surname; } } Codice:
public interface BOTListener { void botComm(String message); } Codice:
import java.io.*; import java.nio.channels.*; import java.util.*; public class BOTProgrammone { private Scanner botIn; private PrintStream botOut; private InputStream systemIn; private PrintStream systemOut; private BOTData data; private BOTListener listener; public BOTProgrammone(BOTData data, BOTListener listener) { this.data = new BOTData(data.getName(), data.getSurname()); this.listener = listener; } public void catturaFlussiStandard() throws IOException { systemIn = System.in; systemOut = System.out; /* Crea il flusso in uscita per scrivere sul flusso in entrata del programma */ Pipe pipeIn = Pipe.open(); InputStream in = Channels.newInputStream(pipeIn.source()); PrintStream out = new PrintStream(Channels.newOutputStream(pipeIn.sink())); System.setOut(out); botIn = new Scanner(in); /* Crea il flusso in entrata per leggere dal flusso in uscita del programma */ Pipe pipeOut = Pipe.open(); in = Channels.newInputStream(pipeOut.source()); out = new PrintStream(Channels.newOutputStream(pipeOut.sink())); System.setIn(in); botOut = out; } public void liberaFlussiStandard() { System.setOut(systemOut); System.setIn(systemIn); } /* Legge una linea dal flusso in entrata (che è stato collegato al flusso in uscita del sistema) */ private String leggiLinea() { return botIn.nextLine(); } /* Scrive una linea sul flusso in uscita (che è stato collegato al flusso in entrata del sistema) */ private void inviaLinea(String v) { botOut.println(v); } /* Da qui in poi il BOT legge e scrive */ public void attiva() { new Thread(runner).start(); } private Runnable runner = new Runnable() { public void run() { String line = leggiLinea();//O' programmone v. 1.0 line = leggiLinea();//Inserire il nome inviaLinea(data.getName());//invia il nome... line = leggiLinea();//Inserire il cognome inviaLinea(data.getSurname());//invia il cognome line = leggiLinea();//legge l'esito...e se ne frega :D listener.botComm("Fine"); } }; } Non resta che l'interfaccia. Se hai dimestichezza con swing i commenti sono superflui. Altrimenti ci vuole tutto il forum per spiegarlo. Io molto pigro, spero nella prima condizione ![]() Codice:
import javax.swing.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; public class InterfacciaSwing implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new InterfacciaSwing()); } private JTextComponent nameField, surnameField; private Window frame; private BOTProgrammone bot; public void run() { JFrame frame = new JFrame("InterfacciaSwing"); frame.setContentPane(creaContenuto()); frame.pack(); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setVisible(true); this.frame = frame; } private Container creaContenuto() { JLabel nameLabel = new JLabel("Nome", JLabel.RIGHT); JLabel surnameLabel = new JLabel("Cognome", JLabel.RIGHT); JTextField nameField = new JTextField(10); JTextField surnameField = new JTextField(10); JButton accept = new JButton("ok"); JButton cancel = new JButton("cancel"); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); buttonPanel.add(cancel); buttonPanel.add(accept); accept.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { accept(); } }); cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { cancel(); } }); GridBagLayout layout = new GridBagLayout(); GridBagConstraints lim = new GridBagConstraints(); lim.insets = new Insets(4, 4, 4, 4); lim.fill = GridBagConstraints.HORIZONTAL; lim.gridx = 0; lim.gridy = 0; layout.setConstraints(nameLabel, lim); lim.gridx = 1; lim.gridy = 0; layout.setConstraints(nameField, lim); lim.gridx = 0; lim.gridy = 1; layout.setConstraints(surnameLabel, lim); lim.gridy = 1; lim.gridx = 1; layout.setConstraints(surnameField, lim); lim.gridx = 0; lim.gridy = 2; lim.gridwidth = 2; layout.setConstraints(buttonPanel, lim); this.nameField = nameField; this.surnameField = surnameField; JPanel container = new JPanel(layout); container.add(nameLabel); container.add(surnameLabel); container.add(nameField); container.add(surnameField); container.add(buttonPanel); return container; } private void accept() { BOTData data = new BOTData(nameField.getText(), surnameField.getText()); bot = new BOTProgrammone(data, botListener); try { bot.catturaFlussiStandard(); bot.attiva(); OProgrammone.main(null); } catch(Exception ex) { ex.printStackTrace(); } } private void cancel() { frame.dispose(); } private void notifyEnd() { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(frame, "Fine programma"); } }); } private BOTListener botListener = new BOTListener() { public void botComm(String message) { if(message.equals("Fine")) { bot.liberaFlussiStandard(); notifyEnd(); } } }; } |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
Da paura!!!
![]() Ho compilato tutto e funziona perfettamente, era quello che mi ci voleva! Per capirlo un po' bene mi ci vorrà del tempo, in quanto non ho dimestichezza con le Swing e con molte altre cose, che voglio imparare in questi giorni, quindi colgo l'occasione.. ![]() Inoltre vorrei provare a cambiare il formato di output da xml a CSV su file .txt, che è quello che usa il mio programma. Ci sono dei vantaggi a usare l'xml?
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Quote:
![]() ![]() Se per CSV intendi valori separati da virgola e il tuo programma usa questo formato direi che è meglio fare qualche esperimento con CSV, giusto per acquisire dimestichezza nel manipolare quel formato. Sai, una cosa tira l'altra, magari oggi fai l'interfaccia e domani ti vien voglia di aggiungere qualcosa che manipoli il prodotto del programma... |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
Sto andando avanti a fare qualche esperimento, sono ancora lontano da capire tutto, comunque grazie al tuo programma posso già usarlo..
![]() Una domanda: per memorizzare in una variabile in automatico la data, senza dover farla inserire dall'utente, esiste qualche metodo? Es. per ogni persona inserita voglio una var. di istanza con il timedate di quando è stata aggiunta alla lista, posso inizializzarla sulla data corrente direttamente dal costruttore predefinito?
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Sì, puoi inserire nel costruttore l'inizializzazione del "tempo" di creazione. Basta un:
Codice:
class Qualcosa { private java.util.Date tempoDiCreazione; public Qualcosa() { tempoDiCreazione = new java.util.Date(); } } |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Mar 2003
Messaggi: 3852
|
Quote:
![]()
__________________
Cerco fotocamera con buono zoom!! CLICCA! ° Moderatore del Forum Ufficiale di ElaborarE (responsabile sezione HI-FI e Car Audio) ° |
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Butta l'occhio a SimpleDateFormat.
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:27.