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
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.