View Full Version : [java] inserire botton in JFrame
bouncey2k
23-05-2007, 12:11
Dopo aver creato una Finestra (vedi codice sottostante), come posso inserire un bottone all'interno della finestra?
JFrame finestra = new JFrame("Finestra");
finestra.setSize(400,600);
finestra.setVisible(true);
Dipende da dove lo vuoi inserire. Supponendo che tu voglia metterlo in alto a sinistra puoi dire:
JFrame finestra = new JFrame("Finestra");
JPanel pannelloPulsanti = new JPanel(new FlowLayout(FlowLayout.LEFT));
JButton pulsante = new JButton("Maramao");
pannelloPulsanti.add(pulsante);
finestra.add(pannelloPulsanti, BorderLayout.NORTH);
finestra.setSize(400,600);
finestra.setVisible(true);
Dopo aver creato una Finestra (vedi codice sottostante), come posso inserire un bottone all'interno della finestra?
JFrame finestra = new JFrame("Finestra");
finestra.setSize(400,600);
finestra.setVisible(true);Innanzitutto in genere è meglio creare una sottoclasse di JFrame, non creare un JFrame così .. al volo.
Comunque per aggiungere componenti si usa uno dei metodi add() in overload di Container. Poi comunque bisogna anche tenere in considerazione il layout-manager utilizzato, che se non diversamente specificato per default è il BorderLayout.
Non concordo sul fatto che sia meglio creare sottoclassi. Anzi, credo che, se possibile, l'estensione andrebbe evitata ad ogni costo.
bouncey2k
23-05-2007, 12:30
è normale che oltre ai bordi del pulsante compaiano dei bordi anche intorno alla scritta?
In un AbstractButton (tra cui JButton) il bordo interno segnala il possesso del focus. Se aggiungi un altro pulsante:
JFrame finestra = new JFrame("Finestra");
JPanel pannelloPulsanti = new JPanel(new FlowLayout(FlowLayout.LEFT));
JButton pulsante = new JButton("Maramao");
pannelloPulsanti.add(pulsante);
JButton altroPulsante = new JButton("Marameo");
pannelloPulsanti.add(altroPulsante);
finestra.add(pannelloPulsanti, BorderLayout.NORTH);
finestra.setSize(400,600);
finestra.setVisible(true);
noterai come il bordo interno è presente solo in uno dei due. Puoi dire ad un pulsante di non disegnare questo bordo con setFocusPainted(false).
pulsante.setFocusPainted(false);
Trattandosi di un segnale utile nel caso in cui l'utente interagisca con l'interfaccia attraverso la tastiera sarebbe preferibile lasciarlo o, nel caso in cui sia rimosso, sostituirlo con un qualche genere di "highlight" (da fare a mano).
Non concordo sul fatto che sia meglio creare sottoclassi. Anzi, credo che, se possibile, l'estensione andrebbe evitata ad ogni costo.Eh? E perché?
E tutte le ben note questioni sulla "coesione", sul riutilizzo, ecc..?? Le friggiamo?
Premetto che è un certo (ab)uso dell'estensione ad essere problematico più che l'estensione in sè. E' come il martello che qualcuno amava citare nei suoi messaggi: puoi piantarci un chiodo o darlo in testa al tuo vicino. In entrambi i casi adoperi lo strumento ma nel secondo caso è abuso.
Il problema dell'estensione è che, in quanto forma di ereditarietà, la specie (estensore) dichiara il possesso di tutte le caratteristiche del genere (esteso).
Nel momento in cui io estendo JFrame dichiaro il rispetto di un contratto costituito da 319 metodi pubblici a cui andrebbero aggiunti i protetti e gli innominabili.
Questo è quello che io, programmatore, devo leggere quando mi trovo di fronte a quel sorgente. Chi l'ha scritto ha "visto" un insieme di oggetti con 319 comportamenti. Una elementare considerazione di economia razionale, che in grammatica diventa regola, vuole che un oggetto dichiari tutti e soli i metodi di cui ha bisogno per assolvere al suo compito nel sistema di cui è parte.
E qui sta il punto. A meno che io non stia creando un oggetto che è parte del sistema swing, che non è un'interfaccia utente ma un framework per la creazione di ogni genere di interfacce utente, l'estensione viola l'elementare principio di economia razionale secondo cui uno dichiara ciò che è necessario ad esprimere un significato.
E' la stessa differenza che c'è tra dire:
<<Pierluigi, vai a prendere il pane.>>
e dire
<<Pierluigi, nel mezzo del cammin di nostra vita... e dopo una settimana ... l'amor che move il sole e l'altre stelle, vai a prendere il pane.>>
Dirò una blasfemia: si chiamano "linguaggi" perchè sono forme di comunicazione. E la comunicazione ha le sue regole anche quando il destinatario sia un calcolatore.
Il problema dell'estensione è che, in quanto forma di ereditarietà, la specie (estensore) dichiara il possesso di tutte le caratteristiche del genere (esteso).
Nel momento in cui io estendo JFrame dichiaro il rispetto di un contratto costituito da 319 metodi pubblici a cui andrebbero aggiunti i protetti e gli innominabili.Su questo sono d'accordo, se estendo un JFrame allora MioFrame è-un JFrame, pertanto tutto quello che potrei fare su un JFrame potrei farlo pure sul MioFrame.
Tu però ti stai basando solo sul fatto che semplicemente non vuoi che tutto ciò che fa parte di un JFrame venga visto anche nella classe derivata. Ma bisogna anche valutare ben altri aspetti secondo me.
Se non volessi estendere JFrame, JDialog, ecc.... allora potrei fare una mega classe MiaApplicazione in cui butto dentro la gestione di tutti i vari JFrame, JDialog ecc... di cui posso avere bisogno. Bello ... verrebbe una cosa enorme e ingestibile!
E se i vari JFrame, JDialog li devo utilizzare più volte nella applicazione, che faccio? E se devono avere, come è tipico, uno "stato", cioè contenere informazioni varie, reference ad altri oggetti, ecc... cosa faccio? dove le metto queste informazioni?
Estendendo JFrame ecc... invece ho diversi vantaggi:
- coesione: la classe è ben focalizzata su un ben preciso scopo.
- incapsulazione: lo stato interno del frame posso nasconderlo.
- riutilizzo: la classe posso riutilizzarla, se necessario, più volte nella applicazione in modo semplice.
Insomma ... è vero quello che hai detto all'inizio ma secondo me non estendere JFrame & company porta più svantaggi che vantaggi. Percui si dovrebbe privilegiare l'ereditarietà piuttosto che il voler evitare che un tuo frame venga visto con tutto quello che ha un JFrame.
Dopotutto se sviluppo una applicazione, allora l'utilizzo dei vari frame/dialog è ben specifico e se è una applicazione non è una libreria, pertanto deve essere subito ben chiaro a tutti che non si può utilizzare quel tal frame o dialog per farci chissà che cosa a mo' di libreria.
Tutto questo ovviamente secondo la mia (modesta e insignificante) opinione. ;)
Sì, ma tutto quello che potresti fare con un JFrame non è tutto quello che fai con un JFrame. Tra l'altro non vedo come questo possa condurre alla creazione della megaclasse MiaApplicazione. La soluzione sta nell'uso del semplicissimo composition and forwarding.
public class FinestraApplicazione {
private JFrame frame = new JFrame("Hello");
public void show() {
frame.setVisible(true);
}
}
Ciò che FinestraApplicazione può fare a differenza di FinestraApplicazione extends JFrame è esprimere l'insieme necessario di comportamenti che qualificano il concetto di "finestra" non per il framework Swing, che ha i suoi scopi e le sue necessità, ma per la mia applicazione, che ne certamente ben altri.
La soluzione sta nell'uso del semplicissimo composition and forwarding.
public class FinestraApplicazione {
private JFrame frame = new JFrame("Hello");
public void show() {
frame.setVisible(true);
}
}È vero ... mi ero dimenticato di questa possibilità. :ops2:
Non mi dò dello scemo perché non lo sono .... posso rimangiarmi un pezzettino di quello che ho scritto prima? :p
Io in effetti ho sempre esteso JFrame & company .... da ora in poi proverò a usare la composizione. Però stavo pensando ... questo cosa comporta? Intendo il fatto che frame è private. Se per caso fosse necessario dall'esterno (da altre classi) fare riferimento a quel frame?
^TiGeRShArK^
23-05-2007, 16:06
public class FinestraApplicazione {
private JFrame frame = new JFrame("Hello");
public void show() {
frame.setVisible(true);
}
public JFrame frame() {
return frame;
}
}
è la prima cosa che m'è venuta in mente :p
... oppure getFrame() se si vogliono rispettare le care convenzioni Java :p
Dal punto di vista del significato comporta tutto e solo quello che è pubblico. Io vedo quella roba lì e dico che per chi l'ha scritta una "FinestraApplicazione" è qualcosa che può essere visualizzato.
"E se qualcuno avesse bisogno di quel frame"...sarebbe un bell'intoppo :D.
Penso che si dovrebbe analizzare quel bisogno per capire quale parte del contratto di JFrame lo soddisfi. Se i metodi che saltano fuori sono relativamente pochi si può continuare con il composition and forwarding. Altrimenti si riduce la classe con un'interfaccia e si pubblica questa.
Poi è anche possibile che sia richiesto tutto il contratto di JFrame. Anche in questo caso, tuttavia, prima di dichiarare una classe con 300 metodi io tenterei un "vampiro". Che è facile ma un po' lungo da spiegare :D.
public JFrame frame() {
return frame;
}
:D e a quello che fa una cosa così noi ci tagliamo i ditini santi :D
Scherzi a parte è anche possibile che sia inevitabile pubblicare tutto il contratto di JFrame. Però è una faccenda piuttosto seria. JFrame serve per fare omnia mundi et quibusdam aliis. E' difficile riuscire a costringere l'utente del metodo "getFrame" a rispettare eventuali limiti imposti dalle necessità di FinestraApplicazione. Giusto una testa di cavallo nel letto...
^TiGeRShArK^
23-05-2007, 16:28
cmq ora che ci penso mi sfugge perchè si dovrebbe avere accesso diretto al frame :mbe:
^TiGeRShArK^
23-05-2007, 16:29
:D e a quello che fa una cosa così noi ci tagliamo i ditini santi :D
Scherzi a parte è anche possibile che sia inevitabile pubblicare tutto il contratto di JFrame. Però è una faccenda piuttosto seria. JFrame serve per fare omnia mundi et quibusdam aliis. E' difficile riuscire a costringere l'utente del metodo "getFrame" a rispettare eventuali limiti imposti dalle necessità di FinestraApplicazione. Giusto una testa di cavallo nel letto...
infatti l'ho scritto nel commento precedente ke era rimasto in sospeso mentre facevo passare un junit :D
La soluzione + ovvia imho è mettere a disposizione solo i metodi strettamente necessari a meno ke non sia strettamente necessario :p
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.