begin process at 2012 02 15 10:34:43
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

Swing

 > DESSINER AVEC SWING (2): UN PROGRAMME DE DESSIN SIMPLE

DESSINER AVEC SWING (2): UN PROGRAMME DE DESSIN SIMPLE


 Information sur le tutoriel

Note :
Aucune note

 Description

Cet exemple de programme permet le dessin de lignes colorées ayant différentes épaisseurs. Le dessin se fait à main libre en tirant avec la souris. Par cet exemple nous apprenons:

    * comment des repaint multiples sont réunis
    * comment nous pouvons restreindre la zone à dessiner

Tutorial

Réunir des repaint multiples

Chaque ligne dessinée se compose d'une suite de cercles (Graphics#fillOval), qui sont déterminés par interpolation entre deux points de souris. Avec ça, repaint(x,y,brushSize,brushSize) est appelé à plusieurs reprises dans une boucle:

    @Override
    public void mouseDragged(final MouseEvent e) {
        double xDelta = e.getX() - lastPoint.getX();
        double yDelta = e.getY() - lastPoint.getY();
        double delta = Math.max(Math.abs(xDelta), Math.abs(yDelta));
        double xIncrement = xDelta / delta;
        double yIncrement = yDelta / delta;
        double xStart = lastPoint.getX();
        double yStart = lastPoint.getY();
        for (int i = 0; i < delta; i++) {
            Point interpolated = new Point((int) xStart, (int) yStart);
            draw(interpolated);
            xStart += xIncrement;
            yStart += yIncrement;
        }
        draw(e.getPoint());
        lastPoint = e.getPoint();
    }
 
    private void draw(final Point start) {
        int brushSize = drawingPanel.getBrushSize();
        int x = start.x - (brushSize / 2) + 1;
        int y = start.y - (brushSize / 2) + 1;
        drawingPanel.getG2d().fillOval(x, y,brushSize, brushSize);
        drawingPanel.repaint(x, y,brushSize, brushSize);
    }

Quand des repaint() multiples sont appelé sur un composant avant que le premier appel soit traité, le Repaintmanager de Swing peut réunir les appels multiples en un seul appel. Quand des appels multiples sont réunis, le rectangle "clip" résultant est égal à la réunion des rectangles qui sont contenus dans les appels réunis.

Restreindre la zone à dessiner

Pendant que Swing essaie de rendre le processus de dessin aussi performant que possible, l'implémentation de la méthode paintComponent() peut elle-même avoir un impact considérable sur la performance globale. Nous pouvons influencer ce processus, en utilisant les informations "clip" pour restreindre la zone à dessiner.

Si ton composant est simple -- par exemple, si c'est un bouton -- alors ce n'est pas la peine de
de traiter le graphiqe pour dessiner uniquement la partie qui chevauche le rectangle "clip"; il est préférable de dessiner le composant intégralement et laisser agir les optimisations standard. Mais quand tu as construit un composant avec sortie compliquée, comme un composant de texte, alors il est nécessaire que ton code utilise les informations "clip" pour restreindre la zone à dessiner. La méthode Graphics#getClipBounds nous donne accès au rectangle "clip":

    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        // initialises the image with the first paint
        // or checks the image size with the current panelsize
        if (image == null || image.getWidth(this) < getSize().width || image.getHeight(this) < getSize().height) {
            resetImage();
        }
        Rectangle r = g.getClipBounds();
        g.drawImage(image, r.x, r.y, r.width + r.x, r.height + r.y, r.x, r.y, r.width + r.x, r.height + r.y, null);
    }

L'appel drawImage(..) avec les paramètres indiqués, ne redessine que la partie de l'image qui chevauche le rectangle "clip".

Code source intégral

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
 
public class DrawOnImage extends JFrame implements ActionListener {
 
    private DrawingPanel drawingPanel;
    private JPanel buttonPanel;
    private JButton clearButton,  upSize,  downSize;
 
    public DrawOnImage() {
        super("DrawOnImage");
        drawingPanel = new DrawingPanel();
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(2, 0, 2, 2));
        addButton(Color.BLACK);
        addButton(Color.BLUE);
        addButton(Color.GREEN);
        upSize = addButton(null);
        upSize.setText("+");
        addButton(Color.RED);
        addButton(Color.ORANGE);
        clearButton = addButton(null);
        clearButton.setText("Clear");
        downSize = addButton(null);
        downSize.setText("-");
        getContentPane().add(new JScrollPane(drawingPanel));
        getContentPane().add(buttonPanel, BorderLayout.SOUTH);
    }
 
    private JButton addButton(final Color color) {
        JButton button = new JButton();
        button.setBackground(new Color(230, 240, 250));
        button.setBorder(BorderFactory.createEtchedBorder());
        if (color != null) {
            button.setForeground(Color.WHITE);
            button.setBackground(color);
        }
        button.setText("Paint");
        buttonPanel.add(button);
        button.addActionListener(this);
        return (button);
    }
 
    public void actionPerformed(final ActionEvent e) {
        String s = e.getActionCommand();
        if (s.equals("Paint")) {
            JButton button = (JButton) e.getSource();
            drawingPanel.setPaintColor(button.getBackground());
        } else if (s.equals("Clear")) {
            drawingPanel.clearPaint();
        } else if (s.equals("+")) {
            drawingPanel.increaseBrushSize();
        } else {
            drawingPanel.decreaseBrushSize();
        }
    }
 
    public static void main(final String[] args) {
        Runnable gui = new Runnable() {
 
            @Override
            public void run() {
                JFrame frame = new DrawOnImage();
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        };
        //GUI must start on EventDispatchThread:
        SwingUtilities.invokeLater(gui);
    }
}

import java.awt.Point;
import java.awt.event.MouseEvent;
import javax.swing.event.MouseInputAdapter;
 
class MouseHandler extends MouseInputAdapter {
 
    private DrawingPanel drawingPanel;
    private Point lastPoint;
 
    MouseHandler(DrawingPanel drawingPanel) {
        this.drawingPanel = drawingPanel;
    }
 
    @Override
    public void mousePressed(final MouseEvent e) {
        lastPoint = e.getPoint();
        draw(lastPoint);
    }
 
    @Override
    public void mouseDragged(final MouseEvent e) {
        double xDelta = e.getX() - lastPoint.getX();
        double yDelta = e.getY() - lastPoint.getY();
        double delta = Math.max(Math.abs(xDelta), Math.abs(yDelta));
        double xIncrement = xDelta / delta;
        double yIncrement = yDelta / delta;
        double xStart = lastPoint.getX();
        double yStart = lastPoint.getY();
        for (int i = 0; i < delta; i++) {
            Point interpolated = new Point((int) xStart, (int) yStart);
            draw(interpolated);
            xStart += xIncrement;
            yStart += yIncrement;
        }
        draw(e.getPoint());
        lastPoint = e.getPoint();
    }
 
    private void draw(final Point start) {
        int brushSize = drawingPanel.getBrushSize();
        int x = start.x - (brushSize / 2) + 1;
        int y = start.y - (brushSize / 2) + 1;
        drawingPanel.getG2d().fillOval(x, y,brushSize, brushSize);
        drawingPanel.repaint(x, y,brushSize, brushSize);
    }
}

import java.awt.*;
import javax.swing.*;
 
class DrawingPanel extends JComponent {
 
    private Image image;
    private Graphics2D g2d;
    private int brushSize = 5;
 
    public DrawingPanel() {
        super();
        setPreferredSize(new Dimension(300, 300));
        MouseHandler mh = new MouseHandler(this);
        addMouseListener(mh);
        addMouseMotionListener(mh);
    }
 
    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        if (image != null) {
            size.width = image.getWidth(this);
            size.height = image.getHeight(this);
        }
        return size;
    }
 
    public void setPaintColor(final Color color) {
        g2d.setColor(color);
    }
 
    public void clearPaint() {
        g2d.setColor(Color.white);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        repaint();
        g2d.setColor(Color.black);
    }
 
    public void increaseBrushSize() {
        brushSize += 2;
    }
 
    public void decreaseBrushSize() {
        brushSize -= 2;
        if (brushSize <= 0) {
            brushSize = 1;
        }
    }
 
    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        // initialises the image with the first paint
        // or checks the image size with the current panelsize
        if (image == null || image.getWidth(this) < getSize().width || image.getHeight(this) < getSize().height) {
            resetImage();
        }
        Rectangle r = g.getClipBounds();
        g.drawImage(image, r.x, r.y, r.width + r.x, r.height + r.y, r.x, r.y, r.width + r.x, r.height + r.y, null);
    }
 
    private void resetImage() {
        Image saveImage = image;
        Graphics2D saveG2d = g2d;
        image = createImage(getWidth(), getHeight());
        g2d = (Graphics2D) image.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.white);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.setColor(Color.black);
        if (saveG2d != null) {
            g2d.setColor(saveG2d.getColor());
            g2d.drawImage(saveImage, 0, 0, this);
        }
    }
 
    public Graphics2D getG2d() {
        return g2d;
    }
 
    public int getBrushSize() {
        return brushSize;
    }
}

 Historique

01 décembre 2010 06:52:08 :
Ajout d'une REMARQUE

Commentaires

Commentaire de ing46 le 16/11/2009 18:22:32

slt uhrand,

C'est bien continus...........

Commentaire de cha7ri le 02/12/2009 11:11:43

thinks...................

Commentaire de faouzighandour le 22/04/2010 12:03:36

trés bien

Commentaire de laguchori le 04/11/2010 21:36:53

merci tres bien

Commentaire de laguchori le 30/11/2010 23:07:04

merci

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,437 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales