[Résolu] Besoin d'aide : Distortion JDialog

yanngrenier
[Résolu] Besoin d'aide : Distortion JDialog

Bonjour,

Je me suis créé un JDialog personnalisé en ce sens que j'ai retiré le cadre par défaut de Windows, que j'ai ajouté un TitleBorder et que je contrôle le drag du dialog sur le TitleBorder.

J'ai utilisé deux listeners pour le drag : MouseMotionListener(mouseDragged()) et MouseListener(mousePressed()).

Mon problème est que quand j'ai plusieurs Components à l'intérieur de ma fenêtre et que je drag mon dialog il a tendance à distortionner. Le dialog se met à danser en zig zag dans l'écran.

Quelqu'un a une idée du pourquoi j'obtien ce résultat non souhaité?

Merci d'avance!

yanngrenier

Présentement, la seule piste que je possède concerne le JPanel que j'ai ajouté dans le LabDialog afin de faire apparaître mon TitleBorder. Est-ce que ce serait lui qui n'arrive à à bien se redessiner???

Toutes les idées sont bonnes!

fredericmazue

Bonsoir,

Quote:
Je me suis créé un JDialog personnalisé

Fallait pas :twisted: :lol:
Quote:
j'ai retiré le cadre par défaut de Windows

Qu'est-ce à dire exactement ?
Quote:
j'ai plusieurs Components à l'intérieur

Components ou JComponents dans le JDialog ?
Quote:
il a tendance à distortionner

Distortion fuzz ou distorsion overdrive ?
Quote:
Le dialog se met à danser en zig zag dans l'écran

Normal si ça Swing je dirais :lol:

Quote:
Quelqu'un a une idée du pourquoi j'obtien ce résultat non souhaité?

Parce que tu as codé en Java au lieu de prendre un langage sérieux :lol:

Bon ta question manque de précisions pour diagnostiquer le problème de manière sûre. Cependant on dirait que tu as mélangé la programmation Swing et Awt voire mélangé des composants Swing et Awt (JDialog et Component ?)
Bref ça faut pas le faire, Sun est bien clair là dessus.
Déjà que Swing c'est un magasin de farces et attrapes quand tu l'utilises de la façon politiquement correcte, si tu débrides ta créativité, alors là....
:lol:

Voilà pour le principe de base.
Maintenant que tu ais implémenté un Drag toi même ça n'est pas de bon augure non plus. Sans préjuger de tes talents, mais pour la raison citée ci-dessus. Faudrait voir comment tu as fait ça. Mais je suis loin, je vieilli un peu plus chaque jour et du coup j'ai la vue qui baisse. Bref d'ici, je n'arrive pas à voir ton code sur ton bel écran. A l'occasion poste en un petit bout.

yanngrenier

Je sais que le mélange n'est pas idéal, mais c'est une demande de mon patron... alors pas de question SVP :) hihihi!

voici un bout de code :

public void initDialog(Component componentToShow)
{
   JDialog dialog = new JDialog();
   JPanel borderPanel = new JPanel();
   TitleBorder border = BorderFactory.createTitleBorder(strTitle);
   borderPanel.setBorder(border);
 
   dialog.setUndecorated(true); 
   dialog.setResizable(false);
   dialog.getContentPane().removeAll();
   dialog.getContentPane().setLayout(TableLayout.createDefaultLayout(FILL_TYPE)); //this is a custom layout
   dialog.getContentPane().add(borderPanel, "1,1");
 
   borderPanel.setLayout(TableLayout.createDefaultLayout(FILL_TYPE));
   borderPanel.add(componentToShow, "1,1");
 
   DialogMouseListener mouseListener = new DialogMouseListener(dialog);
   borderPanel.addMouseMotionListener(mouseListener);
   borderPanel.addMouseListener(mouseListener);
}
 
private static class DialogMouseListener implements MouseMotionListener, MouseListener
{
   private JDialog dialog = null;
   private Point origin = null;
 
   public DialogMouseListener(JDialog objDialog)
   {
      dialog = objDialog;
      origin = new Point();
   }
 
   public void mouseDragged(MouseEvent e)
   {
      Point p = dialog.getLocation();
 
      if (objDialog != null && origin.getY() <= 26) // 26 = TitleBorder Height
      {
         dialog.setLocation(p.x + e.getX() - origin.x, p.y + e.getY() - origin.y);
      }
   }  
 
   public void mousePressed(MouseEvent e)
   {
      origin.x = e.getX();
      origin.y = e.getY();
   }
 
   //other events are empty so not shown here...
}
fredericmazue

Quote:
Je sais que le mélange n'est pas idéal, mais c'est une demande de mon patron... alors pas de question SVP hihihi!

Patron ou pas, il a doublement tort:

1) on ne mélange pas Swing et AWT.
2) Quand on veut des zôlies fenêtres personnalisées, on prend C++ et une librairie convenable. Pas Java et Swing.

Bon j'ai regardé ton code.
Pour virer le bord de la fenêtre du appelles setUndecorated, si je comprends bien. C'est déjà à ressort puisque c'est une méthode AWT, mais bon faire une bidouile personnelle ne serait certainement pas mieux.

On voit bien que tu mets des composants AWT dans le JDialog (donc Swing). Ca faut pas le faire.
Après pour le déplacement, tu appelles setLocation en boucle, en suivant la souris je veux dire.
Bon comme déjà ce que tu fais ne peux pas marcher (Swing + AWT) et compte tenu qu'avec le mélange des genres de composants le rafraichissement va forcément te jouer des tours, si j'étais toi j'éviterais de rafraîchir en boucle comme ça. Au premier clic de souris, je ferai disparaître le JDialog, pour ne laisser qu'un cadre (un simple rectable quoi) et c'est ce cadre que je tracerais en suivant les déplacement du pointeur. Puis une fois le bouton de la souris relâché, je redessinerais le JDialog.
Comme ça, ca ira peut être. J'insiste sur le peut être. C'est évidemment beaucoup de boulot pour rien de tracer un rectangle dans le bureau et de l'effacer au fur et à mesure du déplacement.
Et puis attention, déjà que Java est le langage le moins portable du monde, alors là les problèmes de portabilités du risque d'en rencontrer...

Sinon pour une solution plus immédiate, je ne vois pas. Désolé. Sun le dit très clairement qu'il ne faut pas mélanger Swing et AWT. Même si tu réussis à faire marcher ton truc ici et maintenant, tu coures toujours le risque que le problème ou un problème connexe ressurgissent plus tard ou ailleurs :(

Evidemement il y a une solution malgré tout: tout AWT. Mais je sais déjà ce que ton patron va dire ;)

yanngrenier

Je m'excuse si cette question apparaît ridicule, mais que considères-tu comme faisant partie de AWT et de SWING dans mon code?

Pour moi Swing étends AWT, ce n'est pas clair dans mon esprit quand tu me dis que je mélange les deux.

Merci de ton temps:)

yanngrenier

J'utilise un JDialog et un JPanel tous deux de Swing. La seule composante de AWT que je peux voir c'est le listener????????????????

fredericmazue

Quote:
Je m'excuse si cette question apparaît ridicule,

Aucunement ridicule.

Quote:
mais que considères-tu comme faisant partie de AWT et de SWING dans mon code?

Simple:

Quote:
JDialog dialog = new JDialog();

Ca c'est du Swing n'est-ce pas ?

par ailleurs

Quote:
public void initDialog(Component componentToShow)
et
JPanel borderPanel = new JPanel();
et enfin
borderPanel.add(componentToShow, "1,1");

JDialog et JPanel sont des classes Swing.
Component est AWT sinon ce serait JComponent
Quand tu ajoutes componentToShow dans borderpanel tu mets bien un composant AWT dans un conteneur Swing, donc tu mélanges les genres, ce qu'il ne faut pas faire.

A ce niveau là le mélange est clair. Maintenant:

Quote:
Pour moi Swing étends AWT

En effet
Et il est tentant de penser qu'un composant Swing se comporte comme un AWT. C'est ce à quoi on s'attendrait avec l'héritage.
Malheureusement ça ne fonctionne pas. Je n'ai plus le lien en tête mais Sun l'explique sur son site. Tu trouveras facilement.

Bien que l'un dérive de l'autre il y a des couches logicielles entre le deux qui font qu'ils ne se comportent pas pareil. Par exemple pour le rafraîchissement qui doit être ce qui te pose problèlme.
Bref Swing dérive de AWT mais ils ne sont pas compatibles. :(

Une de ces horreurs comme on ne trouve qu'en Java (tu ne le sais peut être pas mais je déteste ce #### langage)

Tu vois je ne suis pas surpris que ta fenêtre saute dans tous les sens lors du déplacement, justement à cause de ces différentes de traitement du rafraîchissement. Même si ça marche avec telle JVM aujourd'hui et telle plate-forme, tôt ou tard tu auras une mauvaise surprise.
En plus dans ton code, tu demandes un rafraîchissement (implicitement avec setLocation) pour tous les événements de la souris ce qui va surcharger la JVM.

Tiens, je pense à quelque chose. Tu as bien vu que setLocation attend des coordonnées relatives à la fenêtre parent ? Si tu essaies de tirer ton JDialog en dehors de la fenêtre, ça peut provoquer des sauts aussi ça.

yanngrenier

Est-ce que la simple utilisation d'un JComponent à la place du Component pourrait régler mon problème?

Assumant que je fais les modifications nécessaires pour que le tout fonctionne avec un JComponent! :)

yanngrenier

J'ai tracé en debug un cas où je lui passe un JComponent (JPanel dans ce cas-ci) et il flicker tout de même... mmmpppffff!!! Je commence à comprendre ton aversion pour Java!!!!

fredericmazue

En théorie je dirais oui, mais en théorie...
En pratique ça peut le faire ou pas.
ca dépend si ta JVM se débrouille bien avec de nombreux rafraichissement à la volée, si la file d'événements ne sature pas, si la machine est puissante...
Par exemple sous X-Windows sans accélération graphique avec une machine poussive va savoir ce que ça va faire.
Bon j'exagère un peu quand même je dois reconnaître, avec Java 6.0 c'est quand même bien meilleur que ce que ça a été :)

Mais si tu mets du JComponent partout, ton code devient politiquement correct et tu peux légitimement espérer que ça fonctionne :)

Attention quand même à cette histoire de coordonnées relative à la fenêtre parent. Tu as regardé ce point déjà ?

yanngrenier

J'ai lu ton message qui parlait de ces coordonnées relatives à la fenêtre parent. Je travaille avec deux écrans et lorsque je sors mon dialog de ma fenêtre d'application principale elle ne frickle plus autant voir même presque plus!

Est-ce que ca serait ça que tu veux dire? Est-ce que le fait de sortir du cadre de ma fenêtre principale changerait quelque chose que ce soit?

yanngrenier

Oublies ce que je viens de dire... :?

J'ai fais d'autres tests et ca frickle partout dans mes deux écrans!

Donc, est-ce que tu as des suggestions pour remplacer mon setLocation()? :) J'en demande bcp p-e?

yanngrenier

EUREKA! J'ai peut-être une piste de solution...

Je me suis dis que peut-être y avait-il trop d'événements de mouseDragged à gérer. Donc j'ai mis une boucle for de 100 000 itérations à l'intérieur de la méthode mouseDragged et il n'y a presque plus de frickles.

Il ne me reste plus à trouver une solution à ce problème :):)

yanngrenier

OK Fred, ceci sera mon dernier post sur ce foutu BUG de m....!

J'ai finalement trouvé!!!

En fait tout se situait au niveau de mon setLocation(). Je faisais un calcul avec e.getX() et e.getY() où e est mon EVENT.

À la quantité d'event qui étaient lancés, le binding sur chacunes des coordonées de chacun des events prenait un temps fou à "processer".

J'ai utilisé MouseInfo.getMouseInfo.getLocation() qui me retourne la position du curseur dans l'écran et je l'ai soustrait de mon point de clique d'origine. De cette façon, mon événement n'est plus en référence!!!!!

VOILÀ!

Merci pour ton aide... je m'en souviendrai !

fredericmazue

Quote:
Je me suis dis que peut-être y avait-il trop d'événements de mouseDragged à gérer
[...]
À la quantité d'event qui étaient lancés, le binding sur chacunes des coordonées de chacun des events prenait un temps fou à "processer".

Je te l'ai signalé dès que tu as montré ton code, en plus de la question AWT ;) Je n'avais peut être pas été suffisament clair puisque qu'on parlé d'AWT en même temps.
Je n'ai pas eu de mal à y penser, tu connais mon opinion sur Java. Alors quand j'ai vu un rafraîchissement implicite à chaque événement dans le gestionnaire de déplacement de souris, ça a été comme un réflexe pour moi ;)

Je suis heureux que tu ais satisfaction, mais ma grande estime de Java m'incite à insister sur le fait de mettre du JComponent partout. Je ne sais pas si tu l'as déjà fait. Mais sinon, tu devrais le faire.

Quote:
Merci pour ton aide...

Ca a été avec plaisir :)
Au plaisir de te revoir sur ce forum :)