Détection de modification de donnée dans un onglet tab

Résolu
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012 - 6 juil. 2012 à 10:47
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 - 17 juil. 2012 à 11:04
Bonjour,

Mon programme permet de gérer des onglets et d'afficher des données contenues dans des JTable.
Mon but serait de modifier le nom de mes onglets en ajoutant une * lorsque le contenu d'un onglet est modifié.
Les onglets peuvent contenir des structures de données différentes et l'idéal serait donc d'utiliser un Listener (à priori) de façon générique.

J'ai fouillé sur le net mais j'arrive pas à trouver d'exemple similaire. Un idée ?

32 réponses

cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
13 juil. 2012 à 17:55
voila un petit code tout con tout moche qui modifie les titres des tab....
chaque tab contient un champ de texte, tu écris ce que tu veux dedans puis ENTER et paf, il modifie le titre de l'onglet qui contient le champ texte...

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class Main extends JFrame{

  public Main() {
    super("Change Tab Title");
    setLayout(new BorderLayout());
    
    genUI();
    
    pack();
    setLocationRelativeTo(null);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setVisible(true);
  }
  
  private void genUI() {
    JTabbedPane tp = new JTabbedPane();

    tp.insertTab("1", null, new TabPane(0, tp), null, 0);
    tp.insertTab("2", null, new TabPane(1, tp), null, 1);
    
    add(tp, BorderLayout.CENTER);
  }
  
  public static void main(String [] arg) {
    new Main();
  }
  
  private class TabPane extends JPanel {

    public TabPane(int pIndex, JTabbedPane pTabbedPane) {
      super();
      setLayout(new BorderLayout());
      _parent = pTabbedPane;
      _index = pIndex;
      _title = new JTextField();
      _title.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e){
          _parent.setTitleAt(_index, _title.getText());
        }
      });
      add(_title, BorderLayout.CENTER);
    }
    
    private int _index;
    private JTextField _title;
    private JTabbedPane _parent;
  }
}


c'est sans commentaire (je sais, c'est mal) mais bon, ça fonctionne très bien...
3
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
6 juil. 2012 à 11:44
salut,

comme ça, je te dirais de faire un composant à toi qui étendrait un jpanel avec une méthode qui tirerait un évènement lors de la modification du contenu...

public class TabContent extends JPanel {
   public TabContent() {
      super();
   }

   public void alertContentChanged() {
      listener.firePropertyChange(PROPERTY_ID, true, true);
   }
   public final static String PROPERTY_ID = "Tab Content Change";
}


ton JTabbedPane qui ecoute tes contenus de tab changerait le nom du tab lorsqu'il y aurait du changement...
cependant, chaque panneau devrait lui meme dire quand il faudrait appeler la méthode alertContentChanged()...

en gros, tu devrais implémenter tous les listeners de composant possible dans la classe TabContent (ItemListener, ListSelectionListener, ...) et faire que tes composants soient écoutés par le TabContent qui les contient...
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
6 juil. 2012 à 15:21
Dans ma classe héritant de JTabbedPane j'ai pu récupéré les noms des différents onglets (stockés dans un variable "tab").
Toujours dans cette classe, j'ai créé une méthode afin de modifier le nom de mon onglet si son contenu est modifié à l'aide de getTitleAt().

J'ai une autre classe contenant l'ensemble des Listeners afin de signaler quand le contenu est modifié.

Quand je fais des println le nom est bien modifié (dans ma variable "tab") mais il ne l'ai pas visuellement dans mon onglet.

Ai-je oublié d'utiliser une méthode ou une réaffectation de ma variable "tab" ?
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
6 juil. 2012 à 15:31
tu n'as fait que changer ta variable?
tu as utilisé la méthode setTitleAt(...)?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
6 juil. 2012 à 15:34
Arf il faudrait peut être que je réaffecte "tab" dans mon objet xD.

Par contre je récupère actuellement les noms dans la méthode stateChanged().

Si je désire le faire dans ma méthode qui modifie les noms je ne peux pas car j'ai du la déclaré en static et je ne peux pas utiliser "this" dans un méthode static :(.

La je sèche ...
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
6 juil. 2012 à 15:41
oui j'ai utilisé setTitleAt() pour mettre à jour ma variable "tab".
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
6 juil. 2012 à 15:49
il faudrait peut être que je précise que j'ai pas utilisé firePropertyChange().
En fait j'appelle ma méthode qui modifie les noms directement dans ma méthode actionPerformed qui est contenue dans ma classe contenant l'ensemble des Listeners.
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
6 juil. 2012 à 15:59
il y a une différence à ta méthode setTitleAt et la méthode setTitleAt de la classe JTabbedPane...
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
9 juil. 2012 à 08:34
heu j'utilise setTitleAt et getTitleAt au sein de ma classe héritant de JTabbedPane. C'est pas bon ?

De plus, j'ai toujours le problème que ma méthode permettant de changer le nom des onglets doit être déclarée en static ....
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
9 juil. 2012 à 09:01
Voici la méthode créée dans la classe héritant de JTabbedPane :

private JTabbedPane tab;
  
    /**
     * Modified tab title
     */
    public void setTitleTab(JTabbedPane tab){
    	tab = (JTabbedPane)this;
    int number_tab = tab.getTabCount();
    int current_tab = tab.getSelectedIndex();
    
    	for(int i=0;i<number_tab;i++){
String title = tab.getTitleAt(i);
System.out.println("Title tab : "+title);
System.out.println("1° caract : "+title.substring(0, 1));

if (i == current_tab && !title.substring(0, 1).equalsIgnoreCase("*")){
title = "* " + title;
tab.setTitleAt(i,title);
this.tab = tab;
        }
    	}	
    }


Mais j'ai un problème pour l'appeler dans la classe héritant de JPanel. Voila comment j'ai fait (enfin j'essaye plusieurs trucs mais sans succès ...) :
private JTabbedPane tab;
   private MyTabbedPane mytabbedpane;
   
           mytabbedpane.setTitleTab(tab);
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
9 juil. 2012 à 10:16
Bon je viens de créer un getter afin de récupérer le contenu de ma JTabbedPane mais lorsque je l'appelle dans ma classe héritant de JPanel, elle me retourne un contenu nulle.

Ce getter est déclaré dans ma classe héritant de JTabbedPane :
    @Getter
    public JTabbedPane getTab(){
    	tab = (JTabbedPane)this;
    	return tab;
    }
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
9 juil. 2012 à 11:23
Bon visiblement cela est normal car je crée une nouvelle instance de la classe MyTabbedPane(héritant de JTabbedPane) dans la classe FileTab(héritant de JPanel).

Pour récupérer l'instance existante j'ai vu qu'il fallait déclarer MyTabbedPanecomme un attribut passé en paramètre du constructeur de FileTab. J'ai donc fait ceci :

private MyTabbedPane mytabbedpane;
 public FileTab(MyTabbedPane mytabbedpane)
 {
   this.mytabbedpane = mytabbedpane;
 }


Mais toujours sans succès ....
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
10 juil. 2012 à 15:17
Bon j'ai refait ma méthode pour changer de nom. Elle se trouve dans ma classe MyTabbedPane qui hérite de JTabbedPane.

 public void setTitleTab(){
    int current_tab = getSelectedIndex();

if (!getTitleAt(current_tab).substring(0, 1).equalsIgnoreCase("*")){
String title = this.getTitleAt(current_tab);
System.out.println("Title tab (getTitleAt) : "+title);
title = "* " + title;
this.setTitleAt(current_tab,title);
        }
    }


Mais lorsque je veux l'appeler dans la classe FileTab, plus précisément dans la méthode actionPerformed() (qui écoute l'ensemble de mes composants), j'y arrive pas...
Si j'écris MyTabbedPane.setTitleTab() le compilateur me dit de mettre setTitleTab() en static et si j'instancie MyTabbedPane alors le contenu est null.

Une idée ? je suis sur que c'est quasiment rien comme erreur en plus ...
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
10 juil. 2012 à 16:03
je pense que tu devrais remplacer this.setTitleAt(current_tab,title);
par super.setTitleAt(current_tab,title);

ensuite que veux-tu dire par le contenu est null?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
11 juil. 2012 à 08:40
Ca me retourne l'exception suivante : java.lang.NullPointerException

J'ai trouvé une solution pour récupérer le contenu de MyTabbedPane dans ma classe FileTab. Je fais ceci : window.getMainPanel().setTitleTab();
Ma classe window hérite de JFrame.

Quand je fait un println dans ma méthode setTitleTab() j'ai bien le nom qui a changé mais impossible de l'avoir en visuelle.

Je doit mal m'y prendre mais la je vois pas ...
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
11 juil. 2012 à 09:20
tu es certain que getMainPanel te retourne ton JTabbedPane?
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
11 juil. 2012 à 10:15
Normalement oui car ma classe window permet d'appeler mes méthodes de ma classe MyTabbedPane pour créer/afficher un nouvel onglet ou le recharger lors de l'ouverture du programme.

Voici ma méthode getMainPanel() contenu dans la classe window :
	@Getter
public MyTabbedPane getMainPanel()
{
return mainPanel;
}
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
13 juil. 2012 à 13:56
Je viens de penser à truc.
Est-ce que par hasard le nom ne s'afficherait pas car je ne recharge pas le contenu MyTabbedPane ?
0
cormandyr Messages postés 600 Date d'inscription samedi 20 mai 2006 Statut Membre Dernière intervention 8 juillet 2016 11
13 juil. 2012 à 14:02
tu peux toujours essayer avec les methodes validate ou invalidate appelée sur ton JTabbedPane...
0
Darf33 Messages postés 40 Date d'inscription mardi 26 mai 2009 Statut Membre Dernière intervention 14 août 2012
13 juil. 2012 à 17:34
Ces 2 méthodes ne fonctionnent pas ... Je pense qu'il faut que je trouve un moyen t'actualiser l'affichage de mes onglets (surement dans ma classe window) vu que le contenu de JTabbedPane se modifie bien.
0
Rejoignez-nous