Argomenti da command line

di il
8 risposte

Argomenti da command line

Salve a tutti.
E' il mio primo post su questo Form e quindi ditemi anche se non rispetto qualche regola.
Vi espongo un problema che non riesco a risolvere. Uso Netbeans per sviluppare in Java e per lo più realizzo applicazoni con un Form e vari componenti swing.
Ora avrei bisogno di poter passare degli argomenti ad una applicazione, cosa che ho fatto altre volte ma per programmi che non hanno componenti swing.
Il nuovo programma dovrebbe essere lanciato da un altro programma (il quale subito dopo dovrà chiudersi) e mi occorre fargli giungere due informazioni che mi farebbe comodo inserire nel comando di avvio.
Mi sarebbe utile quindi qualche suggerimento magari anche da realizzare con Netbeans.
Grazie.

8 Risposte

  • Re: Argomenti da command line

    frafel ha scritto:


    Il nuovo programma dovrebbe essere lanciato da un altro programma (il quale subito dopo dovrà chiudersi) e mi occorre fargli giungere due informazioni che mi farebbe comodo inserire nel comando di avvio.
    E quindi il dubbio/domanda quale è? Sai sicuramente che il main di una applicazione standalone riceve lo String[] args con gli argomenti ...
  • Re: Argomenti da command line

    Si. Ovviamente so che in una applicazione standalone gli argomenti
    della linea di comando sono ricevuti dal main in un array di stringhe.

    Ma, forse tutto dipende dal fatto che sono condizionato dall'uso di
    NetBeans che vorrei usare come sempre.

    Quando scrivo una applicazione standalone NetBeans mi crea qualcosa
    del genere:

    public static void main(String[] args) {
    // TODO code application logic here

    }


    Io aggiungo al package una classe (con nome ad esempio elab) e inserisco
    nel Main di cui sopra lo statement:

    elab myprogr = new elab(args);

    e nella classe elab (che è tutto il mio programma) preparo un costruttore
    del tipo:

    public elab(String[] theargs) {

    }


    ho disponibile così gli argomenti della riga di comando in theargs[]

    Quando invece scrivo (sempre con NetBeans) un programma con un Form
    e con tanti componenti swing, non faccio creare il Main che altrimenti
    non farebbe partire la classe del Form e mi limito ad aggiungere un
    componente Form e NetBeans mi fornisce il seguente codice:

    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */
    package org.ffellico.test;

    /**
    *
    * @author ffellico
    */
    public class argframe3 extends javax.swing.JFrame {

    /**
    * Creates new form argframe3
    */
    public argframe3() {
    initComponents();
    }

    /**
    * This method is called from within the constructor to initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is always
    * regenerated by the Form Editor.
    */
    @SuppressWarnings("unchecked")

    ////// GENERATED CODE (qui c'è codice generato che non ci interessa)

    /**
    * @param args the command line arguments
    */

    public static void main(String args[]) {
    /* Set the Nimbus look and feel */

    ////// GENERATED CODE (qui c'è codice generato che non ci interessa)

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
    new argframe3().setVisible(true);
    }
    });
    }

    // Variables declaration - do not modify
    // End of variables declaration
    }

    Poi quando avvio il programma in test devo solo indicare che il Main è
    in argframe3 (in questo caso)

    Tutta l'elaborazione del mio rpogramma in questo caso viene scritta
    dopo initcomponents(); ma lì non riesco ad avere disponibile args[]
    e finora non sono riuscito a trovare un modo per porre quelle informazioni
    in una variabile accessibile dal mio codice.

    Spero di essere riuscito a chiarire perchè sono in difficoltà e mi scuso per
    la lungaggine

    Grazie e saluti
  • Re: Argomenti da command line

    public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    
    ////// GENERATED CODE (qui c'è codice generato che non ci interessa)
    //E INVECE TI DOVREBBE INTERESSARE!!!!
    
    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
    argframe3 a=new argframe3();
    a.elab(args);
    a.setVisible(true);
    }
    });
    }
    // Variables declaration - do not modify 
    // End of variables declaration 
    }
    Prova a modificare il codice così.
    Ovvieamente il metodo elab(String[] args) lo devi scrivere tu nella classe argframe3

    oppure se elab è una classe che ha come costruttore elab(String[] args)
    invece di a.elab()

    devi scrivere new elab(args);

    Comunque per convenzione i nomi delle classi devono essere scritte con la prima lettera Maiuscola
  • Re: Argomenti da command line

    Eccomi di nuovo.

    Sono tornato da poco e mi sono subito messo al lavoro.

    Devo dire prima di tutto che avevo pensato anch'hio di fare come mi suggerisci, ma
    poi avevo desistito perchè sullo statement che tu hai scritto come segue:

    a.elab(args);

    veniva segnalato l'errore:

    local variable for args is accessed from within inner call; need to be declared final

    Dopo il tuo suggerimento ho comunque ripreso quella strada e dopo aver studiato un pò,
    ho modificata la riga:

    public static void main(String args[]) {

    in

    public static void main(final String args[]) {

    l'errore è subito scomparso e ho quindi proseguito secondo il tuo suggerimento.

    Fatto sta che però mi sono accorto che poichè lo statement

    a.elab(args);

    deve essere NECESSARIAMENTE scritto DOPO lo statement

    argframe3 a = new argframe3(args);

    il passaggio degli argomenti arriva troppo tardi.

    Infatti, come avevo detto prima, io per abitudine ho SEMPRE scritto tutto il codice
    dei miei programmi, o meglio ciò che deve essere eseguito all'avvio del programma
    prima che venga esaminato qualunque evento, dopo lo statement

    initComponents();

    Ma poichè, come ho detto, questo codice viene eseguito alla costruzione dell'istanza
    argframe2, l'arrivo degli argomenti non è ancora avvenuto quando viene eseguito il
    mio codice.

    Ripeto ancora una volta che il mio modo di programmare in Java è influenzato dal
    fatto che utilizzo una piattaforma di sviluppo che ha le sue regole e che finisce per
    costringere il progframmatore ad adeguarvisi.

    Dunque tornando a Netbeans (che penso tu conosca, ma non so se usi) devo dire che
    normalmente, se non si usa la grafica, esso quando crea il codice iniziale di un
    qualunque programma, prepara una classe con un Main dal quale si può creare
    la classe che deve fare l'elaborazione e alla quale si possono passare ovviamente
    gli argomenti args.

    Quando però si aggiunge un Form al programma, mi sembra di capire che Netbeans
    si renda conto che il programmatore vuole usare la grafica (infatti certamente
    utilizzerà nel form anche tanti conponenti swing) e allora decide di creare un Main
    anche dentro la classe della Form (estensione della classe JForm). A questo
    punto ci si trova ad avere DUE Main, uno nella classe della Form e un secondo
    nella classe iniziale del programma; se gli si chiede di non creare la main class
    (come faccio io quando scrivo un programma con la grafica) Netbeans crea solo
    la classe della form con all'interno il Main.

    Bene in questa ultima situazione, como ti ho detto prima non si riesce in alcun
    modo a far avere disponibili (per tempo) gli argomenti passati dal Main al
    costruttore della Form (e quindi nel mio caso anche al mio codice che segue
    le istruzioni del costruttore).

    Detto questo e sperando di non averti troppo annoiato, ho provato con un ultimo
    sistema che ha avuto anche successo, ma che mi ha richiesto di modificare un
    pò del codice generato (cosa che non faccio mai con piacere).

    Ho fatto creare a Netbeans un programma SENZA ABOLIRE IL MAIN e vi ho subito
    aggiunto una Form con nome Argframe6. Ho ottenuto una classe iniziale con un
    Main così come riporto qui di seguito:

    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */
    package provaprargs6;

    /**
    *
    * @author ffellico
    */
    public class Provaprargs6 {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
    // TODO code application logic here
    }

    }


    e dopo: // TODO code application logic here, ho aggiunto:

    System.out.println("ciao");
    new Argframe6(args).setVisible(true);


    sono stato costretto però a modificare la riga del costruttore della Form generato
    da Netbeans da:

    public Argframe6() {

    a

    public Argframe6(String args[]) {


    Ora a te il commento. Ti sembra una soluzione che oltre a funzionare non è una
    bruttura? oppure pensi che si potrebbe fare di meglio?

    In tutto questo non posso che ringraziarti per la pazienza e per avermi quanto
    meno messo sulla strada della soluzione.

    Sono tanti anni che programmo e come penso capiti anche a te e a chiunque altro
    lo fa con passione, non si finsce mai di apprezzare questa materia.

    Tanto piacere di aver fatto la tua conoscenza e se ne hai voglia dai un'occhiata
    al mio sito http://www.ffellico.co dove potrai anche sapere qualche cosa di più
    sulla mia età e sul mio passato. Un caro saluto.
  • Re: Argomenti da command line

    Non ti deve interessare se altre classi hanno un metodo main.
    A te ti deve interessare solo il main della classe dalla quale vuoi far partire il programma, gli altri main nelle altre classi puoi anche cancellarli.

    Nel main della classe principale (quella su cui clicchi run) devi istanziare la JFrame con il costruttore che riceve il vettore di String args.
    Il fatto che Netbeans ti generi la classe con il costruttore di default non significa che non lo puoi modificare o aggiungerne uno con dei parametri.

    poi se non vuoi che il costruttore riceva dei parametri potresti adottare questa soluzione:

    1) lasci il costruttore completamente vuoto, volendo potresti anche eliminarlo.
    2) ti crei un metodo init(String[] args) che contiene tutto quello che prima era scritto nel costruttore, solo che inoltre hai a disposizione il vettore degli argomenti.
    3) nel main della classe principale puoi scrivere:
    Finestra f=new Finestra() //la classe che estende JFrame
    f.init(args);
    NB: In quest'ultimo caso la finestra viene create quando istanzi l'oggetto Finestra, ma viene visualizzata solo dopo che il metodo init viene eseguito (all'interno imposterai setVisible(true).

    Nel caso in cui nel metodo init non vuoi scrivere visible(true), questo puoi farlo sempre nel main dopo f.init(args) scrivendo f.setVisible(true).
  • Re: Argomenti da command line

    Ok su tutto.
    Il mo problema è stato risolto, ovviamente anche con il tuo aiuto, ma questa conversazione ora si è spostata, cosa che in fondo ho gradito.

    Inoltre è servita anche a consentirmi di approfondire il comportamento della piattaforma che utilizzo (NetBeans).

    Non ho mai avuto dubbi sul fatto che l'uso di una piattaforma sia un valido aiuto al lavoro di programmazione, ma continuo ad avere anche la conferma che essa, vista da un'altra angolazione, rende anche più difficile lo sviluppo. Infatti è come se si sviluppasse IN DUE dove oltre tutto il partner (nel mio caso Netbeans) non parla e non sente, e l'unico modo di capire quello che ha in mente e le sue scelte è di osservare i suoi comportamenti; non è possibile o è poco possibile costringerlo a "ragionare diversamente" e quindi bisogna adattare il proprio codice rispettando le sue scelte.

    E' questo il motivo per cui sono sempre restio a modificare anche leggermente il SUO CODICE.

    Mi rendo conto che volendo potrei anche riscrivere un parte delle istruzioni che ha generato, ma in questo modo potrei mettere in pericolo le modifiche successive al programma che non mancano mai.

    A titolo di esempio, se io riscrivessi l'intero costruttore (sia pure copiando quello generato), non appena dovessi aggiungere al programma un nuovo componente, Netbeans (che non saprebbe niente del mio intervento) modificherebbe subito IL SUO CODICE che io non uso e quindi il suo aiuto diventerebbe inutile.

    Insomma, come vedi, il lavoro IN DUE (dove l'altro è muto e sordo) è un po' scomodo e richiede una maggiore attenzione nelle scelte.

    Bene. Ora penso che ci siamo detti tutto. Ti ringrazio ancora per ora, anche perché non sarà difficile che mi vedrai ancora sul Forum con qualche altro "problema da risolvere".

    Saluti. Franco
  • Re: Argomenti da command line

    Piacere di esserti stato utile.

    Non condivido però il discorso che fai sul fatto di essere restii a modificare il codice generato dall'IDE. A volte questo tipo di codice serve solo a velocizzare alcune operazioni che altrimenti dovrebbero essere scritte a mano dal programmatore.

    E' buona norma leggere il codice autogenerato e laddove risulti ridondante o superfluo è compito del programmatore cercare di modificarlo.

    Quando programmi, il codice devi comprenderlo e saperlo gestire tu.
  • Re: Argomenti da command line

    Beh! Io sono certamente d'accordo su quello che dici circa il fatto che occorre capire il codice generato, tanto è vero che ti ho detto prima che visto che "il generatore non parla", bisogna interpretare in altro modo quello che fa; e questo si può fare solo studiando il suo codice. Ed io lo faccio naturalmente, ma compatibilmente con il tempo necessario e secondo bisogno.

    Ed è appunto per questo che ritengo importante NON MODIFICARLO, perché altrimenti correrei il rischio di rovinare il suo lavoro.

    La tua proposta ad esempio di copiare tutto il suo metodo initComponent() in un metodo mio
    (ovviamente con un nome diverso) nel quale aggiungere anche del mio codice, funzionerebbe certamente; ma come ti ho già detto, alla prima anche semplice modifica di una proprietà di un widget (magari solo la modifica di un suo colore) lui rigenererebbe tutto il SUO codice provvedendo a settare il nuovo colore del widget, ma la modifica non avrebbe alcun effetto perché quel codice non sarebbe richiamato più, visto che invece io farei richiamare una copia che rimarrebbe quella vecchia (a meno naturalmente di non ricopiare nuovamente la nuova generazione).

    NetBeans comunque (se si usa il suo Editor) provvede a proteggere le parti che rigenera costantemente e per sua sicurezza consente la lettura di tutto il codice, ma NON CONSENTE alcuna modifica su quelle parti; ciò non toglie che l'intera sostituzione dell'initComponents() sarebbe possibile, ma come ho detto prima, risulterebbe quanto meno controproducente.

    Ovviamente tu puoi rimanere della tua opinione; ma intendevo chiarirti bene il motivo della mia ritrosia, ed evitare di essere considerato uno stupido.

    Saluti.
Devi accedere o registrarti per scrivere nel forum
8 risposte