Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

PopupMenu items "à la volée"

15 réponses
Avatar
yvon.thoravalNO-SPAM
B'jour tous(tes),

j'ai un PopupMenu dont je souhaite me servir dans une frame qui peut
afficher, simultanément ou séparement, des tables et une tretable.

Je souhaite bien sûr que ce menu soit contextualisé, donc je fabrique
les items à la volée suivant la table (la treetable) dans laquelle
l'utilisateur a clické.

Ca marche, MAIS, au deuxième click seulement ????

Au premier le PopupMenu affiche un item par défaut, au second click il
affiche ce que je lui ai demandé ???

Pourtant quand je fais un print out du nombre d'items, avant de faire
popup.show(), le nb d'items est bien celui escompté ???

J'ai du oublié qqc ?

--
yt

10 réponses

1 2
Avatar
Thibal
Yvon Thoraval wrote:
B'jour tous(tes),

j'ai un PopupMenu dont je souhaite me servir dans une frame qui peut
afficher, simultanément ou séparement, des tables et une tretable.

Je souhaite bien sûr que ce menu soit contextualisé, donc je fabrique
les items à la volée suivant la table (la treetable) dans laquelle
l'utilisateur a clické.

Ca marche, MAIS, au deuxième click seulement ????

Au premier le PopupMenu affiche un item par défaut, au second click il
affiche ce que je lui ai demandé ???

Pourtant quand je fais un print out du nombre d'items, avant de faire
popup.show(), le nb d'items est bien celui escompté ???

J'ai du oublié qqc ?


Ben là comme ça sans aucun morceau de code j'avoue que j'ai du mal à
comprendre ce qui peut bien se passer dans ton PopupMenu...

Avatar
yvon.thoravalNO-SPAM
Thibal wrote:


Ben là comme ça sans aucun morceau de code j'avoue que j'ai du mal à
comprendre ce qui peut bien se passer dans ton PopupMenu...


Bonne remarque ;-)
<code>
import java.awt.PopupMenu;
[...]
public class ShowDesktop {
[...]
static PopupMenu popup;
[...]
JXTable bottlesTable = new JXTable(datas, columnNames);
[...]
bottlesTable.add(popup);
bottlesTable.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
switch(e.getModifiers()) {
case InputEvent.BUTTON3_MASK: {
Enumeration enumeration = (Enumeration) ((TableColumnModel)
((JXTable) e.getSource()).getColumnModel()).getColumns();
PopupMenuBuild(enumeration, e.getComponent(), e.getX(),
e.getY());
break;
}
}
[...]
});
[...]
static PopupMenu createPopupMenu() {
popup = new PopupMenu("PopupMenu");
popup.add(new MenuItem("MenuItem"));
return popup;
}
static void PopupMenuBuild(Enumeration enumeration, Component
component, int x, int y) {
int idx = 0;
popup.removeAll();
while (enumeration.hasMoreElements()) {
TableColumn tc = (TableColumn) enumeration.nextElement();
popup.insert(new MenuItem((String) tc.getHeaderValue()),
idx);
idx++;
}
popup.show(component, x, y);
}
}
</code>
donc si, dans la boucle while juste au-dessus je fais un print-out j'ai
bien les headers de la table concernée, si je fais un print-out avant ET
après cette boucle de l'item count de popup, j'ai le bon résultat (1
avant, 7 après...)

Mais le show() qui suit n'affiche que l'item pas défaut...

si qq'un voit où est ma bévue... j'en serai ravi ;-)
--
yt

Avatar
Thibal
Yvon Thoraval wrote:
Thibal wrote:


Ben là comme ça sans aucun morceau de code j'avoue que j'ai du mal à
comprendre ce qui peut bien se passer dans ton PopupMenu...



Bonne remarque ;-)
<code>
import java.awt.PopupMenu;
[...]
public class ShowDesktop {
[...]
static PopupMenu popup;
[...]
JXTable bottlesTable = new JXTable(datas, columnNames);
[...]
bottlesTable.add(popup);
bottlesTable.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
switch(e.getModifiers()) {
case InputEvent.BUTTON3_MASK: {
Enumeration enumeration = (Enumeration) ((TableColumnModel)
((JXTable) e.getSource()).getColumnModel()).getColumns();
PopupMenuBuild(enumeration, e.getComponent(), e.getX(),
e.getY());
break;
}
}
[...]
});
[...]
static PopupMenu createPopupMenu() {
popup = new PopupMenu("PopupMenu");
popup.add(new MenuItem("MenuItem"));
return popup;
}
static void PopupMenuBuild(Enumeration enumeration, Component
component, int x, int y) {
int idx = 0;
popup.removeAll();
while (enumeration.hasMoreElements()) {
TableColumn tc = (TableColumn) enumeration.nextElement();
popup.insert(new MenuItem((String) tc.getHeaderValue()),
idx);
idx++;
}
popup.show(component, x, y);
}
}
</code>
donc si, dans la boucle while juste au-dessus je fais un print-out j'ai
bien les headers de la table concernée, si je fais un print-out avant ET
après cette boucle de l'item count de popup, j'ai le bon résultat (1
avant, 7 après...)

Mais le show() qui suit n'affiche que l'item pas défaut...

si qq'un voit où est ma bévue... j'en serai ravi ;-)


Ben déjà avant d'aller plus loin dans le code, je te proposerai tout
d'abord d'utiliser un debugger (tu utilises eclipse non ?). Comme ça tu
regardes par où passe ton code exactement et tu trouveras peut être le bug.

Sinon, rassure moi : Tu n'as pas fait un mélange AWT/Swing quand même ?
Car n'oublie pas que c'est TRES déconseillé, et que le comportement
d'une GUI devient très vite aléatoire quand on mélange Swing et AWT.
Donc, si tu es bien en Swing comme ton "JXTable" me le laisse penser,
alors tu devrais penser à utiliser un JPopupMenu plutôt qu'un PopupMenu.

Voilà, si avec ces deux conseils ça ne marche toujours pas, renvoie le
nouveau code et j'aprofondirais un peu plus la question.

Bon courage,

A++

P.S: Juste par curiosité, c'est quoi ton JXTable ?


Avatar
yvon.thoravalNO-SPAM
Thibal wrote:


Voilà, si avec ces deux conseils ça ne marche toujours pas, renvoie le
nouveau code et j'aprofondirais un peu plus la question.


Ben merci beaucoup, en effet j'ai mélangé Swing et AWT...
... "c'est la première fois", ça m'apprendra ;-)

Bon, je passe tout en Swing et donne le résultat.

Cependant, j'ai un peu le même pb avec la JXTable, j'ai mon :
public class ShowHideTableModel extends AbstractTableModel

qui donc, joue sur la visibilité des colonnes du model, quand, avec le
popupmenu l'user change une visibilité, ce qui ajoute ou retranche une
colonne dans la JXTable, le model fait un :

this.fireTableStructureChanged();

pas de pb, là, la JXTable se met bien à jour

le pb est dans les width des colonnes, comme une colonne a été
ajoutée/retranchée, je dois mettre à jour les width ce que je fais par :

model.addTableModelListener(new TableModelListener() {
[...]
public void tableChanged(TableModelEvent e) {
TableColumn column = null;
int columnIndex = 0;
for (int i = 0; i < preferredWidth.size(); i++) {
if (((Boolean) visibility.get(i)).booleanValue() && (i <
bottlesTable.getColumnCount())) {
System.out.println(i + " " + columnIndex);
column = bottlesTable.getColumnModel().getColumn(columnIndex);
column.setPreferredWidth(((Integer)
preferredWidth.get(i)).intValue());// <<<-- ça déconne ICI
columnIndex++;
}
}
}
});

déjà, il n'y a que tableChanged d'activé (et pas columnAdded ni
columnRemoved) , remarques c'est peut-être "normal" car je fais un
"fireTableStructureChanged" ...

Mais bon, passons, le pb est que la JXTable, même si elle affiche la
nouvelle structure, "ne voit pas" la nouvelle colonne quand j'en ai
ajouté une et donc je me retrouve avec un index out of bound.

En résumé :

- après "fireTableStructureChanged" je me retrouve avec une JXTable qui
a la nouvelle structure ;
- mais si, dans la foulée, je veux mettre les bonnes preferredWidth,
tout se passe "comme si" le nombre de colonnes n'avait pas changé ???

Bon, mais peut-être que c'est indirectement influencé par le fait que
j'ai mélangé AWT et Swing car sur cette JXTable je fais un :
bottlesTable.add(popup);

avec un popup qui reste, pour l'instant en AWT ???

En tout cas merci beaucoup pour ton aide, j'apprécie vraiment !
--
yt

Avatar
yvon.thoravalNO-SPAM
Yvon Thoraval wrote:


Bon, je passe tout en Swing et donne le résultat.


Après l'ajout de qq "J" j'ai eu la "J"oie de constater que ça marche
nettement mieux )))

Cependant, reste le problème (cf post précédent) de la màj des widths
des colonnes, qui ne fait rien du tout...

--
yt

Avatar
Thibal
Yvon Thoraval wrote:

Yvon Thoraval wrote:


Bon, je passe tout en Swing et donne le résultat.



Après l'ajout de qq "J" j'ai eu la "J"oie de constater que ça marche
nettement mieux )))

Cependant, reste le problème (cf post précédent) de la màj des widths
des colonnes, qui ne fait rien du tout...


Eh eh, je me doutais qu'en rajoutant quelques J ca passerait mieux...
Sinon, je pense que tu te compliques la vie pour pas grand chose, moi
aussi j'ai fait mon propre JTable, (t'as mis quoi d'ailleurs comme
fonctions toi dans le tien ?) et ben je me suis pas pris autant le tête
pour les colonnes visibles/invisibles !

Tiens, je te passe mon code, voit si tu peux composer un peu avec ça (à
copier coller dans un vrai éditeur pour avoir une indentation correcte):

public void setColumnVisible(boolean visible, int columnIndex) {

if(! (visible ^ isColumnVisible(columnIndex)))
return;

if(columnIndex < columnWidths.length) { // Si le numéro de colonne est
correct

TableColumn colonne = columnModel.getColumn(columnIndex);

if(visible) {

// Récupération des tailles enregistrées
int[] widths = (int[])
columnWidths[convertColumnIndexToModel(columnIndex)];

colonne.setMinWidth(widths[1]);
colonne.setMaxWidth(widths[2]);
colonne.setPreferredWidth(widths[0]);
}
else{ // Pour rendre la colonne invisible, on réduit sa largeur à 0

// Sauvegarde de la taille de la colonne avant de la réduire à 0
updateVecteurTaillesAt(columnIndex);

colonne.setPreferredWidth(0);
colonne.setMinWidth(0);
colonne.setMaxWidth(0);
}
}
}


public void updateVecteurTaillesAt(int index) {

TableColumn colonne = columnModel.getColumn(index);

columnWidths[convertColumnIndexToModel(index)] = new int[] { // Les
tailles de la colonne i

colonne.getPreferredWidth(),
colonne.getMinWidth(),
colonne.getMaxWidth() };
}


Pour moi ça marche nickel, les colonnes deviennent visibles/invisibles à
volonté, et conservent toutes leurs tailles, et j'ai pas besoin de
m'embeter à changer le TableModel ou à gérer des listener et firer des
events partout ;). Au fait, ton bouton declencheur de PopupMenu tu l'as
mis ou ? Moi je l'ai mis dans le coin en haut à droite du tableau, au
dessus de la barre de défilement.


Voilà, j'espère que celà va t'aider, tiens moi au courant.

Bon courage,

P.S: si quelqu'un a des critiques à faire sur mon code je suis toujours
preneur.


Avatar
yvon.thoravalNO-SPAM
Yvon Thoraval wrote:

Cependant, reste le problème (cf post précédent) de la màj des widths
des colonnes, qui ne fait rien du tout...


j'ai trouvé la bonne méthode :

bottlesTable.getColumnModel().addColumnModelListener(
new TableColumnModelListener() { ...});

--
yt

Avatar
yvon.thoravalNO-SPAM
Thibal wrote:

Au fait, ton bouton declencheur de PopupMenu tu l'as
mis ou ? Moi je l'ai mis dans le coin en haut à droite du tableau, au
dessus de la barre de défilement.


Ben dans la JXTable ((JXTable) majxtable.add(popup)) pcq je n'édite pas
la table, si qq'un veut éditer j'ouvre une jframe pour ça pcq la table
n'est qu'un résumé visuel de l'objet en question (j'utilise une bd
objet).

Mais bien ça y est j'ai trouvé ça marche avec mon model, sur le popup
j'ai du ajouter un "popup.repaint()" sinon les JCheckBoxMenuItem
n'étaient pas à jour au niveau graphique (par contre le getState is ok)

Aussi, mes columns width sont OK maintenant (avec
bottlesTable.getColumnModel().addColumnModelListener(...);).

je préfére utiliser un model car je dois faire un binding entre le model
et ma bd.

je vois bien ton astuce de mettre les columns à zéro, mais bon, c'est
pas du MVC ça ))))

remarques j'ai un doute sur l'intérêt du MVC...
ça alourdit considérablement le code et je ne suis pas sûr, du tout, que
ça le rende vraiment plus maintenable.

en philosophie (Platon) on montre que la technique, c'est l'astuce (ce
que tu fais), ingé en première formation, je constate que la technique
ne prend pas du tout cette orientation...

Mais bon, j'ai l'intention de rendre mon ui scriptable (avec bistro un
smalltalk pour java) par l'utilisateur...

Je trouve que les composants swing sont particulièrement mal conçus.

J'ai essayé SWT, c'est plus facile d'accès mais, en tout k sur MacOS X,
ya des tas de petits bugs par exemple sur une checkbox qui mange la (ou
+) première lettre(s) de l'item visualisé (qqfois même l'item devient
complétement blanc), la treetable affiche les icons width et height à sa
guise etc...

eclipse (3.1 M4) est assez buggé je pense qu'il y a un pb d'encodage
caractère qui traine sur MacOS X car qqfois j'ai des messages d'erreurs
sur des trucs corrects, c'est énervant...

dans un :

MDIView text = new MDIView(editorFrame, treeTable,
"Appellations"""""""""", icon);

le titre "Appellations"""""""""" apparaît comme
"Appellations"""""""""[][][][][]" je ne vois pas d'où ça vient...
--
yt

Avatar
yvon.thoravalNO-SPAM
Thibal wrote:

if(! (visible ^ isColumnVisible(columnIndex)))


tiens, au fait, c'est quoi cette opérateur "^" ????
--
yt

Avatar
Thibal
Yvon Thoraval wrote:
Thibal wrote:


if(! (visible ^ isColumnVisible(columnIndex)))



tiens, au fait, c'est quoi cette opérateur "^" ????


Ou Exclusif :-p


1 2