web-dev-qa-db-fra.com

Comment faire de la toile avec Swing?

J'essaie de créer un éditeur de peinture avec Java dans lequel j'ai une barre d'outils avec les objets que je voudrais coller dans le canevas. J'utilise des composants Swing pour créer l'interface graphique, mais quand j'ai cherché le moyen de créer le canevas, je n'ai trouvé que le canevas de classe d'AWT.

Existe-t-il un moyen de créer quelque chose de similaire à la toile avec Swing? (par exemple, JPanel?) J'ai lu que l'utilisation du canevas de classe d'AWT avec une interface graphique faite avec swing ne fonctionnera pas correctement, est-ce vrai?

24
mccrank

Afin de créer un "Canvas" personnalisé en swing, vous écrivez généralement une sous-classe de JPanel . Ensuite, vous devez remplacer la méthode protected paintComponent(Graphics g) de JPanel.

Dans la méthode Paint, vous pouvez appeler des méthodes sur l'objet Graphics pour dessiner réellement sur le JPanel.

Comme toujours, les tutoriels Java Java ont un grande référence à ce sujet pour vous aider à démarrer.

45
jjnguy

Vous voudrez probablement créer une sous-classe de JPanel et implémenter votre propre façon de peindre les composants que vous souhaitez dessiner sur le panneau.

L'approche de base consistera probablement à assigner un MouseListener à la sous-classe de JPanel, puis à implémenter la fonctionnalité de peinture.

L'idée de base peut être quelque chose comme:

class MyCanvas extends JPanel implements MouseListener
{
    Image img;      // Contains the image to draw on MyCanvas

    public MyCanvas()
    {
        // Initialize img here.
        this.addMouseListener(this);
    }

    public void paintComponent(Graphics g)
    {
        // Draws the image to the canvas
        g.drawImage(img, 0, 0, null);
    }

    public void mouseClicked(MouseEvent e)
    {
        int x = e.getX();
        int y = e.getY();

        Graphics g = img.getGraphics();
        g.fillOval(x, y, 3, 3);
        g.dispose();
    }

    // ... other MouseListener methods ... //
}

L'exemple ci-dessus est incomplet (et non testé - il ne compilera certainement pas), mais il donne une idée de la façon d'implémenter une classe MyCanvas dans laquelle un utilisateur peut cliquer et dessiner des cercles.

L'objet img est utilisé pour contenir l'image du canevas. La méthode paintComponent est utilisée pour peindre l'objet img sur le canevas. Dans la méthode mouseClicked, l'objet Graphics associé à img est récupéré afin de fillOval sur l'image.

Étant donné que l'une des exigences est de coller des images sur le canevas, il peut être judicieux de conserver certains Image que vous souhaitez coller dans le canevas. Peut-être quelque chose du genre:

Image[] myImages;    // Used to store images to Paint to screen.

Ensuite, dans la routine pour peindre l'image sur img stockée dans MyCanvas:

g.drawImage(myImage[INDEX_OF_DESIRED_IMAGE], 0, 0, null);

En utilisant la méthode drawImage de l'objet Graphics , d'autres Image peuvent être dessinés sur Images.


Quant à la question sur AWT et Swing, oui, il est vrai que vous ne voulez pas mélanger les composants de l'AWT et de Swing, car ils diffèrent dans la façon dont ils rendent les composants GUI. AWT est basé sur des composants lourds, ce qui signifie qu'ils sont des fenêtres natives pour peindre l'interface graphique, tandis que Swing est basé sur des composants légers, ce qui signifie que l'interface graphique est dessinée par Java lui-même sans utiliser de composants natifs).

Un bon guide sur la différence entre AWT et Swing est fourni dans Peinture en AWT et Swing article de Sun.

16
coobird

Sous-classe simplement JComponent.

JPanel est une classe inappropriée. Il est souvent suggéré car il semble que setOpaque(true) soit invoqué automatiquement dessus. C'est en fait le PL&F qui fait cela, et si cela se produit ou non dépend de l'implémentation et du fournisseur.

Canvas est un composant lourd. C'est-à-dire qu'il est contrôlé par le système de fenêtrage sous-jacent. Le résultat est qu'il sera généralement dessiné sur le dessus des composants Swing, sans égard à l'ordre z ou à l'écrêtage (le placer dans un volet de défilement donnera un comportement étrange).

13

Vous voudrez peut-être regarder l'API Minueto. C'est une API graphique très simple à utiliser, et vous pouvez combiner l'événement Java en l'écoutant pour fournir votre capacité de dessin.

http://minueto.cs.mcgill.ca/

2
Coyote