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);
}
}
Fa poco ma lo fa male. Stampa una stringa di benvenuto, chiede un nome, chiede un cognome e sputa un file xml. Un programma reale sarà più complicato ma abbiate pietà
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;
}
}
Dopo profonde meditazioni ho dedotto che la bozza aveva il bozzo. La faccio breve, il BOT deve essere asincrono. Per poter comunicare con l'interfaccia utente, il BOT ha bisogno di tutto un lavoro che noi ci giriamo dall'altra parte e facciamo così:
Codice:
public interface BOTListener {
void botComm(String message);
}
Ottimo! Ora tocca al BOT. Che deve fare due cose. La prima è far diventare System.in un "out" e System.out un "in". Questo è facile: il programma scrive su System.out e il BOT deve leggere da System.out, per sapere cosa voglia il programma. Per il magheggio basta un Pipe. Di magheggi dobbiamo farne due, una per System.in e una per System.out.
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");
}
};
}
E' un po' sbrigativo ma è un esempio.
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();
}
}
};
}
Ecco, l'idea era questa. Poi vedi se ti sconfiffera.