3 votes

Dessiner des éléments personnalisés au-dessus de composants opaques dans un JPanel

J'ai un JPanel peuplé de plusieurs composants personnalisés opaques. J'aimerais maintenant dessiner quelque chose au-dessus de ces composants en surchargeant la méthode paintComponent(). Mon problème est que l'élément peint est placé derrière les composants intégrés et, comme ils sont opaques, il est couvert par eux.

Existe-t-il un moyen de faire apparaître la peinture au-dessus des composants ?

Voici un petit exemple de ce que j'essaie de faire :

public class DrawOnTop {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame("Draw on top");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new MyPanel());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

class MyPanel extends JPanel {

    public MyPanel() {
        setLayout(new BorderLayout(3, 3));
        add(new JButton("Button 1"), BorderLayout.NORTH);
        add(new JButton("Button 2"), BorderLayout.CENTER);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.drawLine(0, 0, getVisibleRect().width, getVisibleRect().height);
    }
}

2voto

Boro Points 6305

Vous aviez raison de penser ainsi. Le seul problème est que vous auriez dû surcharger la fonction paintChildren() comme dans le code ci-dessous. C'est parce que la méthode paintComponent() est appelée en premier et effectue l'arrière-plan, etc. de la peinture du composant lui-même (la méthode MyPanel ), puis est appelé paintBorders() et enfin le paintChildren() qui peint tout ce qui se trouve à l'intérieur du composant qui l'appelle.

public class DrawOnTop {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("Draw on top");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new MyPanel());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

class MyPanel extends JPanel {

    public MyPanel() {
        setLayout(new BorderLayout(3, 3));
        JButton b1 = new JButton("Button 1");
        MouseListener ml = new MouseAdapter() {

            @Override
            public void mouseExited(MouseEvent e) {
                super.mouseExited(e);
                MyPanel.this.repaint();
            }
        };
        b1.addMouseListener(ml);
        JButton b2 = new JButton("Button 2");
        b2.addMouseListener(ml);
        add(b1, BorderLayout.NORTH);
        add(b2, BorderLayout.CENTER);
    }

    @Override
    protected void paintChildren(Graphics g) {
        super.paintChildren(g);
        g.setColor(Color.red);
        g.drawLine(0, 0, getVisibleRect().width, getVisibleRect().height);
    }
}

Important à noter dans l'exemple de code, que j'ai également ajouté un MouseListener pour repeindre le panneau lorsque la souris sort d'un bouton, sinon les boutons resteraient toujours au-dessus de la ligne lorsque la souris entre sur l'un d'entre eux.

Mais si vous voulez avoir une peinture personnalisée qui soit toujours au-dessus de vos composants, je vous suggère d'utiliser une vitre. Exemples d'utilisation d'une vitre sont fournis ici :

  1. C'est simple.
  2. Une plus complexe.

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