Newsgroup: it.comp.java
Titolo: da package a jframe

 
Dal codice dentro un package avrei bisogno di far riferimento da un 
JtextField in un jframe per assegnargli una stringa, come faccio?
 
In pratica nel package ho una classe che rileva una combinazione di 
tasti a cui dovrebbe seguire l'assegnazione di una stringa al jTextField:
 
if(evt.getKeyCode() == KeyEvent.VK_T){
          JOptionPane.showMessageDialog(null,"premuto CTRL+T");
 
  }
 
 
-- 
Gulp®
(forse mi sono perso qualcosa :))


Anche questa volta la qualita' della chiarezza non e' stata il tuo forte.
Se vuoi semplicemente sapere in quale campo e' stato eseguita la 
combinazione di tasti, e' sufficiente:
evt.getComponent();
che ritorna l'istanza del campo che ha generato l'evento. Che in genere 
equivale a evt.getSource(), ma potrebbe non esserlo.
Poi se vuoi sapere se era un JTextField basta il test:
JTextField.class.isAssignableFrom(evt.getComponent().getClass());
che ritorna true se il component e' un'istanza di un JTextField o suo 
derivato, che grosso modo equivale al risultato dell'operatore 
instanceof con qualche differenza. In ogni caso il cast 
(JTextField)component funzionera' senza rischio di ClassCastException.
 

 Anche questa volta la qualita' della chiarezza non e' stata il tuo forte.
 
:)
 
Sei un grande! ....anche per la dose d'intuito eh?  :)
 
Ecco risolto:
 
  if(evt.getKeyCode() == KeyEvent.VK_T){
                         if 
(JTextField.class.isAssignableFrom(evt.getComponent().getClass())){
                             JTextField textField = (JTextField) 
evt.getComponent() ;
                             textField.setText("Torino");


Ora però vorrei fare un ulteriore passaggio.
Ho inserito nella classe del frame this.addKeyListener(new KeyTab());
Vorrei con
 
if(evt.getKeyCode() == KeyEvent.VK_M){
	Frame f=(Frame) evt.getSource();
   	f.dispose();
e aprire il menu MENU.java
 
Ma mi da ClassCastException: javax.swing.JTextField cannot be cast to 
java.awt.Frame
 
Tieni presente che il controllo selezionato alla pressione di CTRL+M è 
un jTextField



Non ha mica tutti i torti a incazzarsi.
Comunque, io per capire quale sia l'ancestor piu' remoto del tuo 
JTextField utilizzerei il metodo statico 
SwingUtilities.getAncestorOfClass(Class<?> c, Component comp)
ovvero, nel tuo caso:
Frame f=SwingUtilities.getAncestorOfClass(Frame.class, evt.getSource());
 
Nella classe SwingUtilities ci sono un sacco di metodi interessanti, 
tutti statici, che fanno comodoin molte situazioni. Te la segnalo.
 

 Frame f=SwingUtilities.getAncestorOfClass(Frame.class, evt.getSource());
 
evt.getSource()
da come eccezione: incompatible types object cannot be converted to 
component



Prova con evt.getComponent();

Il 17/10/15 06:41, Dr.UgoGagliardelli ha scritto:

Nemmeno con getComponenet ne vuol sapere.


Riassumendo, al momento sono messo così
if((evt.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) 
{
  if(evt.getKeyCode() == KeyEvent.VK_M){
     //Frame f=SwingUtilities.getAncestorOfClass(Frame.class, 
evt.getComponent()); //da errore di type
    Frame f=(Frame) evt.getSource(); //l'ascoltatore di jtextField 
disturba anche se ho messo  this.addKeyListener(new KeyTab());
    f.dispose();
   //dovrei poi acquisire frame di MENU.java per aprire il menu
                     }
//i seguenti funzionano entrambi
                     if(evt.getKeyCode() == KeyEvent.VK_D){
                         if 
(JTextField.class.isAssignableFrom(evt.getComponent().getClass())){
                             JTextField textField = (JTextField) 
evt.getComponent() ;
                             String oggi=Uty.Today(true);
                             textField.setText(oggi);
                      }
                         }
if(evt.getKeyCode() == KeyEvent.VK_T){
    if(JTextField.class.isAssignableFrom(evt.getComponent().getClass())){
                             JTextField textField = (JTextField) 
evt.getComponent() ;
                             textField.setText("Torino");
                      }
}
 
 



Che cos'e' this.addKeyListener(new KeyTab());?
Nel senso, cos'e' this e cos'e KeyTab.
Se il test:
  JTextField.class.isAssignableFrom(evt.getComponent().getClass())
e' vero, allora deve funzionare anche:
SwingUtilities.getAncestorOfClass(Frame.class, evt.getComponent());
sempre che stiamo parlando dello stesso evt, e che effettivamente il 
contenitore di evt.getComponent() sia effettivamente un'istanza di Frame.
puoi usare anche:
SwingUtilities.getWindowAncestor(evt.getComponent())
che pero' si ferma al primo contenitore sottoclasse di java.awt.Window, 
quindi anche Frame o ogni altro contenitore che derivato, magari 
chiamato ricorsivamente se nella tua discendenza di componenti avessi 
piu' di una Window (che pure e' un java.awt.Component).
Mi sembra che nel tuo progetto abbia mescolato componenti awt e swing, 
la qual cosa potrebbe portare una certa confusione.
 

Il 20/10/15 09:01, Dr.UgoGagliardelli ha scritto:
 
Siiiiiiiiiiiiiii. Questa non dà errori e funziona!
 
Frame f= (Frame) SwingUtilities.getWindowAncestor(evt.getComponent());
f.dispose();
 
e chiude l'unico form aperto.Ora volendo di seguito aprire il JavaForm 
Menu dell'applicazione, come scrivo l'istanza alla classe trovandomi in 
un package? Mica posso importare MENU!
Questo non lo posso scrivere:Frame fm=  new MENU();
perchè chiaramente non lo trova.
Questo: SwingUtilities.getAncestorNamed("MENU", f);
Mi da un bel NullPointerException



Questa sinceramente non l'ho capita per niente.
 
L'hai gia' detto qualche altra volta, ma non ci ho fatto caso: cosa 
intendi per "trovandomi in un package"?
 
E "Mica posso importare MENU!" secondo il tuo modo di vedere cosa significa?
 
Frame fm=  new MENU();
potresti anche scriverlo, dipendentemente da com'e' fatta la classe 
MENU. Se ad esempio:
 
public class MENU extends Frame { ....
 
allora sarebbe sarebbe perfettamente legale, ma non credo che sia questo 
il tuo dilemma.
Di sicuro puoi scrivere MENU fm = new MENU(); e se MENU e' quel 
"JavaForm Menu" ( di cui ignoro il significato), allora probabilmente 
fm.setVisible(true); lo fara' magicamente comparire. Ma se quello e' 
effettivamnete il menu dell'applicazione, sarebbe forse conveniente 
tenerti a disposizione la sua istanza (cioe' la variabile fm) in modo 
che in un solo colpo fai sparire la Frame e fai riapparire il menu.
 
(intanto complimenti che ti sei andato a cercare il metodo 
getAncestorNamed alla facciaccia di chi dice che non ti arrabatti!)
SwingUtilities.getAncestorNamed("MENU", f);  non funziona per due 
diversi motivi. Il NullPointerException te lo da perche' probabilmente f 
e' null. Se hai appena fatto f.dispose() e' possibile che f sia ormai un 
oggetto dimenicato. Inoltre non credo che "MENU" sia il nome di qualche 
Component, sempre che non glielo abbia imposto tu.
 
Devi sapere che tutti le classi che derivano da java.awt.Component 
ereditano un sacco di metodi, tra cui getName e setName. Questi metodi 
agiscono sulla proprieta "String name", che di per se non serve a nulla 
se non per assegnare un nome riconoscibile, in pratica e' di ausilio al 
programmatore per riconoscere gli oggetti per nome. Venendo al metodo 
getAncestorNamed, il "name" che cerca e' proprio quello, ovvero cerca un 
Component (nella fattispecie un Container) per cui 
getName().equals("MENU"). Ancestor ha un significato ben preciso. I 
Component e derivati, hanno il metodo "Container getParent()", parent in 
inglese significa genitore, qui utilizzato con accezione se vuoi 
impropria, che indica colui che contiene. Poiche' anche i Container, che 
a loro volta sono dei Component, possono avere il proprio parent, in una 
catena di "matrioske" senza limiti, ecco che ancestor, che propriamente 
significa antenato, e' una delle matrioske piu' esterne.
 
Vabbe', adesso vado a letto a vedere se riesco a dormire un po'. (che 
qui ci vorresti tu che sono insonne)

 significa?
 
Per poter utilizzare (vedere) delle classi dichiarate nei package devo 
fare un import:
 
import pubblico.Ini; //è una classe con cui scrivo e leggo un file .ini
import pubblico.Uty; // sono varie utility che richiamo al bisogno.
 
Se sto scrivendo del codice dentro una classe KeyTab che si trova in un 
package che ho chiamato pubblico, la scrittura:
 
Frame fm= new MENU();
fm.setVisible(true);
 
mi da errore: cannot find symbol, symbol: class MENU, location class KeyTab
 
Eppure la class MENU è dichiarata public:
public class MENU extends javax.swing.JFrame {
 
e, come dicevo, non posso fare import.
la class MENU è main class dell'applicazione.
 
Dopo aver letto il tuo post, avevo pensato di arrivarci a ritroso:
  Container c=f.getParent();
  Component p[]=c.getComponents();
  f.dispose();
  //ciclo p in cerca del form MENU
  for( Component fs : p ) {
      if (fs.getName().equals("MENU")){
          fs.setVisible(true);
      break;
  }
...
ma non è corretto. Ho controllato, quell'array è in realtà vuoto.



Intanto, se precedentemente la proprieta' name di fs non e' stata 
impostata a qualcosa diverso da null tramite il metodo setName, 
fs.getName() ritorna null, quindi fs.getName().equals("MENU") da' 
NullPointerException perche' non puoi mai chiamare un metodo d'istanza 
su un oggetto null. Per evitare il NullPointerException dovresti 
invertire il test, ovvero "MENU".equals(fs.getName()), in modo se 
fs.getName() e' null il test ritorna false.
 
Inoltre, per risalire la catena dei parent dovresti chiamare getParent() 
ricorsivamente, ad esempio:
 
Container c=f.getParent();
Component menu = null;
while (c != null && menu == null) {
   Component p[]=c.getComponents();
   for( Component fs : p )
     if ("MENU".equals(fs.getName()))
        menu = fs;
   c = c.getParent();
}
if (menu != null)
   menu.setVisible(true);
 
che direi che sia piu' o meno la stessa cosa che fa 
SwingUtilities.getWindowAncestor con la differenza che cerca un 
Container istanza di Window.


Rivedendo questo codice, ho notato che hai utilizzato f.dispose(), 
questo metodo rende non-visualizzabili tutti i componenti posseduti da f 
e li  distrugge.
Se f era un child del Container c parent di f, e se f era anche l'unico 
child, allora c.getComponents() non puo' che ritornare un array vuoto.
Se non hai l'effettiva necessita' di chiudere l'intera applicazione, non 
usare f.dispose(), magari ti basta f.setVisible(false);

 usare f.dispose(), magari ti basta f.setVisible(false);
OK, lo usavo all'uscita di ciascun form aprendo e ripartendo dal form 
MENU e pensavo fosse corretto per non lasciare occupate risorse.
Comunque seguirò il consiglio.
 
Ciclando Component p[]=c.getComponents(); come hai consigliato, non da 
alcun NullPointerException, ma egualmente non trova e non apre il form MENU.


 Netbeans
Il "default package" e' il package non ulteriormente descritto, ovvero 
il package senza nome (deprecato da svariati anni/versioni di Java). 
Quindi una classe nel default package non ha la dichiarazione package. 
Secondo le specifiche java, che io ricordi almeno da java 2 (ovvero Java 
1.2), non e' piu' possibile l'import di una classe definita nel 
default-package da una classe definita in un named-package.
 
Il miglior consiglio che ti possa dare e' quello di assegnare un package 
anche alle classi che non ce l'hanno. Non usando NetBeans, non so dirti 
l'esatta procedura per farlo. Con eclipse ho diversi modi, il piu' 
semplice e' quello trascinare le classi dal default package in uno gia' 
definito, anche creato per lo scopo. Un altro metodo e' quello di 
aggiungere la dichiarazione package alle classi che non ce l'hanno e 
gestire l'errore di compilazione istruendo l'ide a spostare la classe 
nel package dichiarato (che se non esiste viene creato da eclipse stesso).
Probabilmente, nel tuo specifico caso data la semplicita' 
dell'applicazione, spostando le classi dal default-package all'unico 
package che hai definito, non potresti che avere dei benefici.

 package che hai definito, non potresti che avere dei benefici.
 
.... e così fu. Ho creato un package MAIN e li ho spostato tutto da 
package default che una volta vuoto è sparito... maledetto ghost!
Ho fatto il mio bel import MAIN e tutto è andato OK... preferisco non 
dire: "ho risolto", sai, non vorrei che ci fosse "qualcuno" di guardia. :)
 
Però devo dire che l'essermi cimentato con i Parents e con l'Ancestor, è 
stata una bella esperienza che mi servirà in qualche altra occasione.
 
Grazie.
Ciao


 stata una bella esperienza che mi servirà in qualche altra occasione.
Come sempre. Finche' s'impara qualcosa di nuovo, la probabilita' di 
morire ignoranti cala.
 

 in java i package dovrebbero chiamarsi con nomi tutti in minuscolo.
 
[OT] Con qualche illustre eccezione:
 
# (dopo aver scompattato in una cartella vuota il file 
/usr/lib/jvm/java-1.8.0-openjdk/src.zip):
 
$ find . -type d | egrep "[A-Z]" | while read DIR; do JAVA=$(find "$DIR" 
-maxdepth 1 -name "*.java"); if [ "$JAVA" != "" ]; then echo "$DIR"; fi; 
done
./com/sun/tools/corba/se/idl/constExpr
./com/sun/tools/corba/se/idl/toJavaPortable
./com/sun/corba/se/impl/javax/rmi/CORBA
./com/sun/corba/se/internal/Interceptors
./com/sun/corba/se/internal/POA
./com/sun/corba/se/internal/CosNaming
./com/sun/corba/se/PortableActivationIDL
./com/sun/corba/se/PortableActivationIDL/RepositoryPackage
./com/sun/corba/se/PortableActivationIDL/LocatorPackage
./com/sun/corba/se/PortableActivationIDL/InitialNameServicePackage
./com/sun/corba/se/org/omg/CORBA
./com/sun/corba/se/spi/activation/RepositoryPackage
./com/sun/corba/se/spi/activation/LocatorPackage
./com/sun/corba/se/spi/activation/InitialNameServicePackage
./com/sun/jmx/snmp/IPAcl
./com/sun/org/omg/SendingContext
./com/sun/org/omg/SendingContext/CodeBasePackage
./com/sun/org/omg/CORBA
./com/sun/org/omg/CORBA/ValueDefPackage
./com/sun/org/omg/CORBA/portable
./sun/reflect/generics/reflectiveObjects
./sun/awt/X11
./sun/awt/X11/generator
./org/omg/PortableServer
./org/omg/PortableServer/POAPackage
./org/omg/PortableServer/POAManagerPackage
./org/omg/PortableServer/portable
./org/omg/PortableServer/ServantLocatorPackage
./org/omg/PortableServer/CurrentPackage
./org/omg/PortableInterceptor
./org/omg/PortableInterceptor/ORBInitInfoPackage
./org/omg/SendingContext
./org/omg/IOP
./org/omg/IOP/CodecPackage
./org/omg/IOP/CodecFactoryPackage
./org/omg/Messaging
./org/omg/CosNaming
./org/omg/CosNaming/NamingContextExtPackage
./org/omg/CosNaming/NamingContextPackage
./org/omg/CORBA_2_3
./org/omg/CORBA_2_3/portable
./org/omg/Dynamic
./org/omg/CORBA
./org/omg/CORBA/ORBPackage
./org/omg/CORBA/portable
./org/omg/CORBA/TypeCodePackage
./org/omg/CORBA/DynAnyPackage
./org/omg/DynamicAny
./org/omg/DynamicAny/DynAnyFactoryPackage
./org/omg/DynamicAny/DynAnyPackage
./javax/rmi/CORBA
 
(capisco "constExpr" o "toJavaPortable", un po' meno perché 
"CodecPackage" e non "codecPackage")

 "CodecPackage" e non "codecPackage")
Non ho mica detto che e' un obbligo, ma semplicemente l'opportunita' di 
utilizzare uno stile che porta qualche vantaggio.
Ad esempio, il java ti permette di creare contemporaneamente i package 
org.omg.IOP.CodecPackage e org.omg.IOP.codecpackage, in un file-system 
case-sensitive, tipo unix, va tutto bene, non altrettanto in un 
file-system case-insensitive tipo windows.
La stessa cosa avviene per i nomi delle classi, anch'essi sensibili al 
file-system sotteso, in questo caso c'e' un ulteriore stile di 
nomenclatura che consiglia di utilizzare il famoso camel-case, per cui 
seguendo questa semplice regola non si subiranno i rigori del file-system.
In definitiva, utilizzare uno stile consigliato, oltre ai vantaggi 
pratici, porta anche il vantaggio di non dover pensare a qualcosa di 
gia' pensato. :-)
 


Scusa, ma io non volevo affatto contraddirti. Solo, pensando che per 
parole composte fosse più opportuno usare la notazione a cammello 
(codecPackage, e non codecpackage), mi è venuta la curiosità di 
verificare il comportamento degli sviluppatori nel dare i nomi ai 
packages "ufficiali", scoprendo, con un po' di sorpresa da parte mia, 
quanto riferito prima.
Più una chiacchiera da bar, che una risposta alla tua osservazione (per 
questo avevo premesso un [OT] all'inizio).
 
Ciao
 
Marco