|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Nov 2001
Città: Lainate (MI)
Messaggi: 831
|
[JAVA] Problema con le finestre
Ciao a tutti,
sto scrivendo una GUI per un progetto dell'università e mi sono imbattuto in questo problema che non riesco a risolvere. In pratica ho due finestre che contengono una lista, in pratica la prima finestra (quella principale) visualizza l'elenco attuale, mentre la seconda serve per inserire nuovi elementi nella lista. Tutto procede bene fino a quando non passo daal finestra secondaria a quella pricipale: in pratica non riesco più a visualizzare la lista. Le ho provate tutte con i metodi validate, revalidate, paint e repaint su form contenitori e ogni possibile componente ma nulla da fare. Vi posto qui un esempio giocattolo per rendere l'idea cosa ho bisogno che faccia il programma. La prima finestra ha un pulsante che apre l'altra; la seconda finestra ha due bottoni: il primo per aggiungere gli elementi in un vector tampone, il secondo per inserire il tutto nella lista e chiudere la finestra corrente. Il motivo è che le modifihce non sono effettuate fino a quando l'utente non conferma col secondo pulsante. La cosa SNERVANTE è che se riapro la finestra secondaria dalla principale DOPO le modifiche, i nuovi elementi sono presenti. Se mi potete dare una mano, ve ne sarei grato. Codice:
//FINESTRA PRINCIPALE
package finestre;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Testform extends JFrame {
// elementi
private JList lista = null;
private JButton bottone = null;
private JScrollPane scroll = null;
private DefaultListModel modello = null;
private JPanel pannello = null;
// metodi
public Testform() {
super("Test");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// creo oggetti della finestra
bottone = new JButton("Apri");
modello = new DefaultListModel();
lista = new JList(modello);
scroll = new JScrollPane(lista);
//eventi
ApriAction azione = new ApriAction();
bottone.addActionListener(azione);
// layout e contenitori
pannello = new JPanel();
pannello.add(bottone);
// posizionamento oggetti nella finestra
this.add(scroll, BorderLayout.CENTER);
this.add(pannello, BorderLayout.EAST);
}// end costruttore
private class ApriAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
TestForm2 t2 = new TestForm2(lista, Testform.this);
t2.pack();
t2.setVisible(true);
Testform.this.setVisible(false);
}// enn actionPerformed
}// end inner class
}// end finestra di test
//FINESTRA SECONDARIA
package finestre;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class TestForm2 extends JFrame {
// oggetti
private JList lista = null;
private JScrollPane scroll = null;
private JButton aggiungi = null;
private JButton ok = null;
private Testform finestra = null;
private Vector<String> elementi = null;
// contenitori
private JPanel pannelloEst = null;
private JPanel pannelloSud = null;
public TestForm2(JList elenco, Testform win) {
super("Test 2");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
lista = elenco;
finestra = win;
// disegno la form
// oggetti
elementi = new Vector<String>();
scroll = new JScrollPane(lista);
aggiungi = new JButton("Aggiungi");
ok = new JButton("Ok");
// eventi
AggiungiAction aggAz = new AggiungiAction();
OkAction okaz = new OkAction();
aggiungi.addActionListener(aggAz);
ok.addActionListener(okaz);
// layout e contenitori
pannelloEst = new JPanel();
pannelloSud = new JPanel();
// aggiunta oggetti
pannelloEst.add(aggiungi);
pannelloSud.add(ok);
this.add(scroll, BorderLayout.CENTER);
this.add(pannelloEst, BorderLayout.EAST);
this.add(pannelloSud, BorderLayout.SOUTH);
}// end costruttore
private class AggiungiAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
elementi.add("Nuovo Elemento");
JOptionPane.showMessageDialog(TestForm2.this,
"Aggiunto nuovo elemento", "Attenzione",
JOptionPane.INFORMATION_MESSAGE);
}// end actionPerformed
}// end inner class AggiungiAction
private class OkAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
DefaultListModel modello = (DefaultListModel) lista.getModel();
for (int i = 0; i < elementi.size(); i++) {
modello.addElement(elementi.get(i));
}// end for
finestra.validate();
finestra.setVisible(true);
TestForm2.this.dispose();
}// actionPerformed
}// end OkAction
}// end TestForm2
__________________
Alea iacta est. Che io deceda se recedo |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Passa alla seconda finestra il modello (DefaultListModel) invece della JList.
Nel costruttore della seconda finestra costuirai un'altra JList con il model passato. Nella action della seconda finestra esegui gli inserimenti direttamente sul model passato. Grosso modo, ApriAction diventa: Codice:
private class ApriAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
TestForm2 t2 = new TestForm2(modello, TestForm.this);
t2.pack();
t2.setVisible(true);
TestForm.this.setVisible(false);
}// enn actionPerformed
}// end inner class
Codice:
class TestForm2 extends JFrame {
// oggetti
private DefaultListModel modello = null;
private JScrollPane scroll = null;
private JButton aggiungi = null;
private JButton ok = null;
private TestForm finestra = null;
...
Codice:
public TestForm2(DefaultListModel mod, TestForm win) {
super("Test 2");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
modello = mod;
JList lista = new JList(modello);
finestra = win;
...
Codice:
private class OkAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// riga eliminata
for (int i = 0; i < elementi.size(); i++) {
modello.addElement(elementi.get(i));
}// end for
finestra.setVisible(true);
TestForm2.this.dispose();
}// actionPerformed
}// end OkAction
http://download.oracle.com/javase/tu...t.html#mutable E se bazzichi da poco nelle Swing e vuoi una guida base, guarda il link che ho in firma.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Nov 2001
Città: Lainate (MI)
Messaggi: 831
|
Quanto tempo ci ho perso?!?! 3 giorni?! Effettivamente se volevo modificare la serie di elementi, avrei dovuto lavorare sul modello e non sulla lista Comunque, ti ringrazio per i link, avevo già scoperto "googlando" la guida sul GridBagLayout di PGI-Bis e avere quella sullo Swing non guasta. Ho, però, un altro un altro effetto simpatico su cui i mitici (o meglio inutili) metodi validate e compagnia bella non funzionano. In questo caso ho bisogno di creare dei pulsati a comando nella parte centrale di una finestra e in posizioni ben precise. Per fare questo uso un GridBagLayout in cui inserisco dei pannello vuoti (verdi) per avere una specie di inizializzazione. Poi quando premo un bottone viene inserito un nuovo pulsante nella posizione voluta. Ora, la prima versione del codice prevedeva di inserire i bottoni direttamente; l'effetto era che NON venivano disegnati fino a quando non ci passavo sopra col cursore del mouse. Nella seconda versione, quella che ti posto, ho aggiunto l'uso del metodo remove del pannello scoperto spulciando la documentazione. Il motivo per cui il primo pannello è arancione è che avevo bisogno di verificare che remove andasse a prendere il pannello verde corretto. Comunque, in questo caso il risultato è ancora più stupefacente: alcuni bottoni me li disegna, altri no... Al momento mi tengo i bottoni fantasma che appaiono al passare del puntatore, non è proprio bellissimo ma almeno i bottoni ci sono Grazie per l'aiuto (e la comprensione) Codice:
package finestre;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Testform extends JFrame {
// elementi
private int contatore = 0;
private JButton bottone = null;
private JPanel panneloEst = null;
private JPanel pannelloCent = null;
private GridBagConstraints vincoli = null;
private GridBagLayout layout = null;
// metodi
public Testform() {
super("Test");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// oggetti
bottone = new JButton("inserisci");
vincoli = new GridBagConstraints();
// eventi
Azione a = new Azione();
bottone.addActionListener(a);
// layout e contenitore est
panneloEst = new JPanel();
// layout e pannello centrali
layout = new GridBagLayout();
pannelloCent = new JPanel(layout);
// aggiunta oggetti pannello est
panneloEst.add(bottone);
// aggiunta oggetti pannello cent
inizializzaCentro(9);
pannelloCent.getComponent(contatore).setBackground(Color.ORANGE);
// aggiunta oggetti alla form
this.add(panneloEst, BorderLayout.EAST);
this.add(pannelloCent, BorderLayout.CENTER);
}// end costruttore
private void inizializzaCentro(int max) {
for (int i = 0; i < max; i++) {
vincoli.gridx = i % 3;
vincoli.gridy = i / 3;
vincoli.weightx = 1;
vincoli.weighty = 1;
vincoli.anchor = GridBagConstraints.CENTER;
vincoli.fill = GridBagConstraints.BOTH;
vincoli.insets = new Insets(10, 10, 10, 10);
JPanel pan = new JPanel();
pan.setBackground(Color.GREEN);
layout.setConstraints(pan, vincoli);
pannelloCent.add(pan);
}// end for
}// end inizializzaCentro
private class Azione implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
JButton nuovoBottone = new JButton("Bottone" + (contatore + 1));
vincoli.gridx = contatore % 3;
vincoli.gridy = contatore / 3;
vincoli.fill = GridBagConstraints.BOTH;
vincoli.anchor = GridBagConstraints.CENTER;
vincoli.insets = new Insets(10, 10, 10, 10);
layout.setConstraints(nuovoBottone, vincoli);
pannelloCent.remove(contatore);
pannelloCent.add(nuovoBottone);
pannelloCent.validate();
pannelloCent.revalidate();
pannelloCent.repaint();
Testform.this.repaint();
contatore++;
}// end actionPerformed
}// end inner class Azione
}// end finestra di test
__________________
Alea iacta est. Che io deceda se recedo |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quando rimuovi/aggiungi un component da/a un container il cui stato è displayable devi chiamare validate.
L'errore sta nel fatto che per sostituire il componente ad un certo indice nel codice postato rimuovi il vecchio componente che si trova a quell'indice e poi aggiungi quello nuovo (il bottone) senza specificare l'indice. Modifica Action così: Codice:
private class Azione implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
JButton nuovoBottone = new JButton("Bottone" + (contatore + 1));
vincoli.gridx = contatore % 3;
vincoli.gridy = contatore / 3;
vincoli.fill = GridBagConstraints.BOTH;
vincoli.anchor = GridBagConstraints.CENTER;
vincoli.insets = new Insets(10, 10, 10, 10);
layout.setConstraints(nuovoBottone, vincoli);
pannelloCent.remove(contatore);
pannelloCent.add(nuovoBottone, contatore);
pannelloCent.validate();
contatore++;
}// end actionPerformed
}// end inner class Azione
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Nov 2001
Città: Lainate (MI)
Messaggi: 831
|
Capisco. In sostanza non erano i metodi validate che non andavano, ma semplicemente andava in confusione perché non gli indicavo quale componente sostituire.
Grazie mille, mi hai aiutato tantissimo.
__________________
Alea iacta est. Che io deceda se recedo |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:32.



















