3 votes

Est-il possible d'arrêter le scintillement de l'info-bulle de java en mode heavyweight ?

Q similaire à ToolTip flicker in Java if outside JFrame ?

Une info-bulle légère constamment mise à jour fonctionne bien, mais dès qu'elle sort des limites de la fenêtre ou qu'elle devient plus lourde (en désactivant les popups légers), c'est la ville du scintillement.

J'ai essayé l'astuce "-Dsun.awt.noerasebackground=true" qui fonctionne à l'intérieur d'une fenêtre, mais au prix de quelques artefacts de peinture sur d'autres composants (cet exemple est juste un panneau vide). En dehors des limites d'une fenêtre, cela n'aide pas, il y a toujours des quantités horribles de scintillement.

Quelqu'un sait-il comment résoudre ce problème ? Ou est-ce que ce n'est pas possible actuellement ?

L'exemple se trouve dans ce code -->

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;

public class JTooltipFlickerTest extends JFrame {

JPanel panel;

static public void main (final String[] args) {
    new JTooltipFlickerTest ();
}

public JTooltipFlickerTest () {
    super ();
    //ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false); 
    //ToolTipManager.sharedInstance().setReshowDelay(0); 

    setTitle (this.getClass().toString());
    setSize (1024, 768);

    this.getContentPane().setLayout (new BorderLayout());

    SwingUtilities.invokeLater (
        new Runnable () {

            @Override
            public void run() {
                panel = new JPanel ();

                final MouseAdapter ma = new MouseAdapter () {

                    public void mouseMoved (final MouseEvent e) { 
                        panel.setToolTipText ("x: "+e.getX()+", y: "+e.getY());
                    }
                };  
                panel.addMouseMotionListener(ma);

                //panel.setDoubleBuffered(true);
                //panel.createToolTip().setDoubleBuffered(true);

                JTooltipFlickerTest.this.getContentPane().add (panel, "Center");                
                JTooltipFlickerTest.this.setVisible (true);
            }
        }
    );
}
}

1voto

eee Points 814

D'une manière ou d'une autre, le javax.swing.RepaintManager peut aider à résoudre le problème de la réapparition de l'info-bulle. La classe qui étend la classe RepaintManager ci-dessous est tirée de l'exemple de l'article Chapitre 11, Gestionnaire de repeint : http://www.java.net/external?url=http://www.curious-creature.org/2007/07/22/repaint-manager-demos-chapter-11/

Il est modifié pour repeindre JTooltipFlickerTest Le plan de contenu de l'...

Essayez de commenter installRepaintManager() dans le constructeur et vous verrez la différence...

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;

public class JTooltipFlickerTest extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    JPanel panel;

    static public void main (final String[] args) {
        new JTooltipFlickerTest ();
    }

    public JTooltipFlickerTest () {
        super ();
        panel = new JPanel ();          

        setTitle (this.getClass().toString());
        setSize (1024, 768);

        this.getContentPane().setLayout (new BorderLayout());

        SwingUtilities.invokeLater (
                new Runnable () {

                    @Override
                    public void run() {

                        final MouseAdapter ma = new MouseAdapter () {

                            public void mouseMoved (final MouseEvent e) { 
                                panel.setToolTipText ("x: "+e.getX()+", y: "+e.getY());
                            }
                        };  
                        panel.addMouseMotionListener(ma);

                        panel.setDoubleBuffered(true);
                        panel.createToolTip().setDoubleBuffered(true);

                        JTooltipFlickerTest.this.getContentPane().add (panel, "Center");                
                        JTooltipFlickerTest.this.setVisible (true);
                    }
                }
        );

        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        installRepaintManager();

    }

    private void installRepaintManager() {
        ReflectionRepaintManager manager = new ReflectionRepaintManager();
        RepaintManager.setCurrentManager(manager);
    }

    private class ReflectionRepaintManager extends RepaintManager {
        public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {

            int lastDeltaX = c.getX();
            int lastDeltaY = c.getY();

            Container parent = c.getParent();
            while (parent instanceof JComponent) {
                if (!parent.isVisible()) {
                    return;
                }

                if (parent instanceof JTooltipFlickerTest) {
                    x += lastDeltaX;
                    y += lastDeltaY;

                    int gap = getContentPane().getHeight() - h - y;
                    h += 2 * gap + h;

                    lastDeltaX = lastDeltaY = 0;

                    c = (JComponent) parent;
                }

                lastDeltaX += parent.getX();
                lastDeltaY += parent.getY();

                parent = parent.getParent();
            }

            super.addDirtyRegion(c, x, y, w, h);
        }
    }
}

édité

Quand installRepaintManager() est désactivé, l'ensemble de l'infobulle clignote de part et d'autre de la limite du bord (c'est le même effet que dans le code original de l'OP).

Quand installRepaintManager() est activée, une partie de la zone d'info-bulle ne scintille pas à l'intérieur de la limite du bord. En revanche, l'autre partie de la zone clignote à l'extérieur de la limite. Cependant, le scintillement n'est pas si grave comparé à ce qu'il est lorsque l'option installRepaintManager() est désactivé.

Je sais, il s'agit d'une différence subtile qui, je pense, ne laisse rien à désirer. Au moins, les mots dans la zone d'info-bulle sont un peu plus lisibles lorsque l'on est dans une zone d'info-bulle. installRepaintManager() est activée.

Même si les codes à double tampon sont désactivés, installRepaintManager() fonctionne comme prévu, c'est-à-dire que le composant lourd est rapidement repeint pour réduire le scintillement.

//panel.setDoubleBuffered(true);
//panel.createToolTip().setDoubleBuffered(true);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X