PDA

View Full Version : [java swing] repaint del jframe


s0nnyd3marco
04-02-2009, 09:42
Salve a tutti, vi illustro subito il mio problema. Ho una classe che estende un jframe, in cui metto un JScrollPane e un JPanel (che ho chiamato buttonPane). Nel JScrollPane inserisco un JPanel per lo sfondo a cui dovranno essere aggiunti, quando premo un pulsante contenuto nel buttonPane, degli altri JPanel conteneti delle informazioni ricavate tramite metodi remoti. Il problema è questo: dopo aver premuto il pulsante che crea il JPanel da inserire nel JPanel inserito nel JScrollPane, questo non compare, e compare solamente quando clicco con il mouse sul JPanel che contiene i bottoni. Ho provato ad inserire un repaint() nel ActionPerformed del bottone ma nulla. C'è un modo per passare un evento alla classe base per poi fare un refresh()?
Grazie a tutti

banryu79
04-02-2009, 10:10
Prova a postare un po' di codice, così possimao capire che problema c'è e dove.

s0nnyd3marco
04-02-2009, 10:21
public class BaseFrame extends JFrame{



BaseFrame(){

super();



setTitle("MASTER");

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setPreferredSize(new Dimension(800,450));

setResizable(false);

setVisible(true);

}




public class Master extends BaseFrame{

public static void main(String[] args){
Set<String> listaIP = new TreeSet<String>();
listaIP.addAll(ParameterFileImporter.LeggiFile(args));

if(!listaIP.isEmpty()){
Master master = new Master();
JTabbedPane tab = new JTabbedPane();
tab.setPreferredSize(new Dimension(550,450));

for(String indirizzo : listaIP){
tab.add("SLAVE: " + indirizzo,new TabElement(indirizzo));
}

master.add(tab);
master.pack();
}
}//fine main







public class TabElement extends JPanel implements ActionListener{

private String indirizzo;

private JScrollPane scrollPane;

private JPanel buttonPane;

private JPanel leftButtonPane;

private JPanel rightButtonPane;

private JPanel stanzePane;

private JButton creaStanzaButton;

private JButton inizializzaButton;

private JLabel statoLabel;

private JComboBox istanzaBox;

private JTextField nomeStanzaField;

private NominabileFactory stub;

private Set<String> listaNominabili = new TreeSet<String>();

private Boolean isConnected = false;

private String nomeStanza = "DefaultName";



TabElement(String indirizzo){

super(new BorderLayout());

this.indirizzo = indirizzo;

this.setBorder(BorderFactory.createTitledBorder("Elenco Stanze"));



stanzePane = new JPanel();

stanzePane.setBackground(Color.LIGHT_GRAY);

scrollPane = new JScrollPane(stanzePane);

scrollPane.setPreferredSize(new Dimension(600,310));

this.add(scrollPane, BorderLayout.NORTH);



buttonPane = new JPanel(new GridLayout(1,2));

this.add(buttonPane, BorderLayout.SOUTH);



leftButtonPane = new JPanel();

leftButtonPane.setBorder(BorderFactory.createTitledBorder("Gestione connessione"));

inizializzaButton = new JButton("Connetti");

inizializzaButton.setSize(new Dimension(100,40));

inizializzaButton.setActionCommand("inizializza");

inizializzaButton.addActionListener(this);

leftButtonPane.add(inizializzaButton);

statoLabel = new JLabel("Disconnesso");

leftButtonPane.add(statoLabel);

buttonPane.add(leftButtonPane);



rightButtonPane = new JPanel();

rightButtonPane.setBorder(BorderFactory.createTitledBorder("Gestione stanze"));

istanzaBox = new JComboBox();

istanzaBox.setEnabled(false);

istanzaBox.setPreferredSize(new Dimension(130,27));

rightButtonPane.add(istanzaBox);

nomeStanzaField = new JTextField("nome stanza");

nomeStanzaField.setEnabled(false);

nomeStanzaField.setPreferredSize(new Dimension(100,27));

rightButtonPane.add(nomeStanzaField);

creaStanzaButton = new JButton("Nuova stanza");

creaStanzaButton.setEnabled(false);

creaStanzaButton.setSize(new Dimension(100,40));

creaStanzaButton.setActionCommand("crea_stanza");

creaStanzaButton.addActionListener(this);

rightButtonPane.add(creaStanzaButton);

buttonPane.add(rightButtonPane);



}//fine main





public void actionPerformed(ActionEvent e){

if(e.getSource() instanceof JButton){

if(e.getActionCommand() == "inizializza"){

if(isConnected){

statoLabel.setText("Disconnesso");

creaStanzaButton.setEnabled(false);

istanzaBox.setEnabled(false);

nomeStanzaField.setEnabled(false);

inizializzaButton.setText("Connetti");

isConnected = false;

}else{

stub = RegistryManager.connect(indirizzo);

if(stub != null){

statoLabel.setText("Connesso");

creaStanzaButton.setEnabled(true);

istanzaBox.setEnabled(true);

nomeStanzaField.setEnabled(true);

inizializzaButton.setText("Disconnetti");

isConnected = true;

try{

listaNominabili.addAll(stub.elencaClassiDiNominabili());

for (String istanza : listaNominabili){

istanzaBox.addItem(istanza);

}

}catch(RemoteException re){

re.printStackTrace();

}

}else{

statoLabel.setText("ERRORE");

}

}

}// fine inizializza

if(e.getActionCommand() == "crea_stanza"){

try {

Stanza stanza = stub.createStanza((String)istanzaBox.getSelectedItem());

if(nomeStanzaField.getText().length() != 0){

nomeStanza = nomeStanzaField.getText();

}

stanza.setName(nomeStanza);

stanzePane.add(new StanzaManager(stanza, stub, listaNominabili, (String)istanzaBox.getSelectedItem()));

} catch (RemoteException re) {

re.printStackTrace();

}

}// fine crea_stanza

}//fine JButton handler

}//fine ActionPerformed



}// fine classe






public class StanzaManager extends JPanel implements ActionListener{

private Boolean luceAccesa = true;

private JPanel gestioneStanzaPane;

private JPanel gestionePersonaggioPane;

private JPanel creaPersonaggioPane;

private JComboBox tipiPersonaggioBox;

private JComboBox personaggiBox;

private JCheckBox isAngryBox;

private JButton isLightedButton;

private JButton creaPersonaggioButton;

private JTextField nomeField;

private JLabel illuminazioneLabel;

private String nomeStanza = "Default";

private ImageIcon lightbulb_on;

private ImageIcon lightbulb_off;



public StanzaManager(Stanza stanza, NominabileFactory stub, Set<String> listaNominabili, String tipoStanza){

super(new BorderLayout());

setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));

setPreferredSize(new Dimension(350,280));









}





public void actionPerformed(ActionEvent e) {


}



}


Il problema è questo: quando da tabElement (che gestisce i vari slave) premo il pulsante per far comparire a schermo il stanzamanger, devo premere con il mouse vicino al bottone o attivare il Combobox perciò che sul JScrollPane compaia lo stanza manager. Penso che dovrei forzare il repaint() e il validate() nella classe Master ma non so come passare l'evento.

banryu79
04-02-2009, 10:34
Rispondo un pezzetto alla volta perchè sono di fretta (ufficio).

Leggendo il tuo codice ho visto questo:

...
for(String indirizzo : listaIP) {
tab.add("SLAVE: " + indirizzo,new TabElement(indirizzo));
}

con tab che è un'istanza di JTabbedPane.
Ora leggendo la documentazione ufficiale per la classe JTabbedPane, si trova spiegato questo:

Tabs/components are added to a TabbedPane object by using the addTab and insertTab methods. A tab is represented by an index corresponding to the position it was added in, where the first tab has an index equal to 0 and the last tab has an index equal to the tab count minus 1.

Intanto comincia col correggere questo, poi io non ho letto tutto il codice e potrebbero esserci altri errori.
Se ti serve sapere altro di "ufficiale" sui TabbedPane vedi qui (http://java.sun.com/javase/6/docs/api/javax/swing/JTabbedPane.html).

Appena posso finisco di guardare con calma il codice.

s0nnyd3marco
04-02-2009, 10:49
Grazie per la risposta
Io utilizzavo il metodo:

add(String title, Component component)
Adds a component with the specified tab title.

invece di

void addTab(String title, Component component)
Adds a component represented by a title and no icon.

Il tutto funzionava anche prima... Il problema rimane come forzare il repaint del JScrollPane dopo la pressione del pulsante "crea stanza"

banryu79
04-02-2009, 10:57
Solo una cosa, nell'evento "crea_stanze":

...
if(e.getActionCommand() == "crea_stanza")
{
try
{
Stanza stanza = stub.createStanza((String)istanzaBox.getSelectedItem());

if (nomeStanzaField.getText().length() != 0)
{
nomeStanza = nomeStanzaField.getText();
}
stanza.setName(nomeStanza);

stanzePane.add(new StanzaManager(stanza, stub, listaNominabili, (String)istanzaBox.getSelectedItem()));

}
catch
(RemoteException re)
{
re.printStackTrace();
}
...


stanzePane è un JPanel, e ogni volta che viene lanciato l'evento "crea_stanza" gli viene aggiunto un nuovo StanzaManager: però bisogna anche che quello vecchio venga rimosso, succede da qualche parte?


Comunque quando aggiungi un nuovo componente all'interno di un Container che è già visibile (come quando invochi il metodo add sul tuo JPanel "stanzePane.add") devi subito dopo invocare il metodo validate sul quel container perchè il nuovo componente venga visualizzato.

s0nnyd3marco
04-02-2009, 11:09
No, io non voglio che venga rimosso quello vecchio, ma che venga visualizzato contemporaneamente entramebi o quanti io decido di aggiungerne (e fino a qua ci sono). I JPanel hanno delle dimensioni fisse e nel JScrollPane c'è spazio per visualizzarne due.
Probabilmente mi mancava di invocare il metodo validate dopo aver aggiunto al container già visibile un altro elemento. Proverò a richiamare tale metodo nell'evento creastanze.
Grazie mille per l'aiuto. Questa sera appena torno a casa dall'ufficio provo e ti dico come va...

banryu79
04-02-2009, 11:14
Sì, te lo chiesto solo perchè non avevo chiaro se quello che volevi era appunto aggiungere JPanel a cascata o averne solo uno da sostituire di volta in volta.

Per via del metodo add() invece di addTab(): hai ragione tu, ho preso una svista.

s0nnyd3marco
04-02-2009, 11:25
Ti ringrazio ancora per l'aiuto... sta sera/notte provo, e se va male ci sentiamo domani :sofico:

Ciau