Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

copier le dessin d'un JPanel


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    copier le dessin d'un JPanel
    Bonjour,
    Je tiens à m'excuser sir ce n'est pas bon forum ou si une question équivalente a été posée. J'ai cherché sur le forum et je n'ai pas trouvé.
    Voilà ce qui m'amène : je dessine dans un JPanel (feuille) doté d'un JScrollPane car ce que je dessine ne peut tenir entièrement à l'écran. à côté, je crée un aperçu qui est le contenu du JPanel en plus petit. Pour le moment je redéfinis paintComponent de l'aperçu et j'applique les modifications que j'ai apporté à mon dessin via une transformation d'échelle.
    Je pense qu'il doit être possible de récupérer le dessin qui se trouve dans feuille pour le dessiner directement dans l'aperçu.
    Ce que je voudrai pratiquement
    BufferedImage image = recuperation de l'image de feuille
    puis dans apercu.paintComponent : g2.drawImage(image,0,0,l,h,null) où l et h sont les dimensions de l'aperçu.

    Merci et bonne journée à tous
    Patrice
    C'est en respectant les autres que l'on se fait respecter.

  2. #2
    Modérateur

    Salut,

    Tu peux utiliser la méthode print().

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    public class Paint extends JPanel {
     
    	List<Point2D> points = new ArrayList<>();
    	public Paint(BufferedImage image) {
    		setPreferredSize(new Dimension(image.getWidth(),image.getHeight()));
    		setBackground(Color.BLACK);
    		addMouseMotionListener(new MouseAdapter() {
    			@Override
    			public void mouseDragged(MouseEvent e) {
    				points.add(new Point2D.Double(e.getX(),e.getY()));
    				repaint();
    				updatePreview(image);
    			}
    		});
    	}
     
    	@Override
    	public void paint(Graphics g) {
    		super.paint(g);
    		Graphics2D g2d = (Graphics2D) g;
    		int x,y;
    		g2d.setColor(Color.WHITE);
    		if (points.size()>0) {
    			x=(int)points.get(0).getX();
    			y=(int)points.get(0).getY();
    			for(int i=0; i<points.size(); i++) {
    				int x1=(int)points.get(i).getX();
    				int y1=(int)points.get(i).getY();
    				g2d.drawLine(x,y,x1,y1);
    				x=x1;
    				y=y1;
    			}
    		}
    	}
     
    	protected void updatePreview(BufferedImage image) {
    		Graphics2D g = image.createGraphics();
    		print(g);
    		g.dispose(); 
    	}
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		BufferedImage preview = new BufferedImage(1000,1000,BufferedImage.TYPE_INT_RGB);
    		Paint paint = new Paint(preview);
    		JScrollPane pane = new JScrollPane(paint, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
     
    		frame.add(pane);
     
    		Dimension dim = new Dimension(200, 200);
    		JPanel previewpanel = new JPanel() {
     
    			@Override
    			public void paint(Graphics g) {
    				super.paint(g);
    				g.drawImage(preview, 0,0, dim.width, dim.height, this);
    			}
     
    		};
    		previewpanel.setPreferredSize(dim);
    		previewpanel.setMaximumSize(dim);
    		previewpanel.setMinimumSize(dim);
    		frame.add(previewpanel,BorderLayout.EAST);
     
    		paint.addMouseMotionListener(new MouseAdapter() {
    			@Override
    			public void mouseDragged(MouseEvent e) {
    				previewpanel.repaint();
    			}
    		});
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    }



    Mais le plus simple et le plus pratique est de dessiner dans une BufferedImage au lieu de dessiner dans le fond d'un JPanel, et tu l'affiches dans le composant de dessin et dans l'aperçu.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre averti
    dessin d'un aperçu
    Citation Envoyé par joel.drigo Voir le message
    Salut,



    Mais le plus simple et le plus pratique est de dessiner dans une BufferedImage au lieu de dessiner dans le fond d'un JPanel, et tu l'affiches dans le composant de dessin et dans l'aperçu.
    En effet cette méthode toute simple est sûrement ce qu'il me faut.

    Je creuse cette réponse.
    Merci
    C'est en respectant les autres que l'on se fait respecter.

  4. #4
    Membre averti
    Ca doit être trop simple ou je suis très fatigué mais je n'arrive à rien.
    Voici mes essais et si quelqu'un peut m'expliquer pourquoi mon panel ne présente une élupse rouge sur un fond jaune, je lui en serai reconnaissant.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    package test;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
     
    import javax.swing.JFrame;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JPanel;
     
    public class Test extends JFrame
    {
    	BufferedImage image, copie;
    	Dessin feuille, apercu;
     
    	public Test()
    	{
    		super("Test de dessin dans une bufferedImage");
    		//plein écran
    		setExtendedState (JFrame.MAXIMIZED_BOTH);
    		//la taille de la fenêtre réduite
    		setSize(new Dimension(1200,600));
    		//on finit l'application en fermant la fenêtre
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JMenuItem item = new JMenuItem("dessiner");
    		item.addActionListener(new ActionListener()
    		{
     
    			@Override
    			public void actionPerformed(ActionEvent arg0) 
    			{
    				dessiner();
    			}
     
    		});
    		JMenuBar menu = new JMenuBar();
    		menu.add(item);
    		setJMenuBar(menu);
     
    		JPanel panneau = new JPanel();
     
     
    		feuille = new Dessin(750,"image");
    		apercu = new Dessin(200,"aperçu");
    		panneau.add(feuille);
    		panneau.add(apercu);
     
     
    		image = new BufferedImage(750, 750, BufferedImage.TYPE_INT_RGB);
    		Graphics2D g = (Graphics2D) image.getGraphics();
    		g.setColor(Color.YELLOW);
    		g.fillRect(0, 0, 750, 750);
    		g.setColor(Color.RED);
    		g.fillOval(150,300, 50, 25);
     
     
    		copie = copie(image);
     
    		this.getContentPane().add(panneau);
     
    		setVisible(true);
    	}
     
    	protected void dessiner() 
    	{
    		feuille.dessiner(image);
    		apercu.dessiner(image);
    	}
     
     
    	private BufferedImage copie(BufferedImage source)
    	{
            BufferedImage copie = new BufferedImage(source.getWidth (), source.getHeight (),BufferedImage.TYPE_INT_RGB);
            Graphics g = copie.getGraphics ();
            g.drawImage(source, 0, 0, source.getWidth(), source.getHeight(), null);
            g.dispose ();
            return copie ;
    	}
     
    	public static void main(String[] args) 
    	{
    		//création de l'interface graphique
    		javax.swing.SwingUtilities.invokeLater(new Runnable() 
    		{
    			public void run() 
    			{
    				new Test();
    			}
    		});
    	}
    }

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    package test;
     
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
     
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    import javax.swing.border.Border;
    import javax.swing.border.EtchedBorder;
     
    public class Dessin extends JPanel 
    {
     
    	Border bordure = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
    	BufferedImage image;
    	int x;
     
    	public Dessin(int x, String nom)
    	{
    		super();
    		this.x = x;
    		setPreferredSize (new Dimension(x,x));
    		setBorder(BorderFactory.createTitledBorder(bordure,nom));
    	}
     
    	@Override
    	protected void paintComponent(Graphics g)
    	{
    		if (image!=null)
    		{
    			g.drawImage(image, x, x, null);
    		}
    	}
     
    	public void dessiner(BufferedImage image) 
    	{
    		this.image = image;
    		repaint();
    	}
    }
    C'est en respectant les autres que l'on se fait respecter.

  5. #5
    Modérateur

    En faisant g.drawImage(image, x, x, null);, ça dessine l'image juste en dehors de l'image, puisque ses dimensions sont x × x.

    C'est g.drawImage(image, 0,0, x, x, null);
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre averti
    Citation Envoyé par Patrice Henrio Voir le message
    Ca doit être trop simple ou je suis très fatigué mais je n'arrive à rien.
    Je confirme, c'était la fatigue.
    La méthode paintComponent de dessin doit être définie ainsi
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	@Override
    	protected void paintComponent(Graphics g)
    	{
    		if (image!=null)
    		{
    			g.drawImage(image, 0, 0, x, x, null);
    		}
    	}

    Et maintenant ça marche.
    Il ne me reste plus qu'à adapter à mon projet qui vous vous en doutez est un peu plus complexe que de dessiner un ovale rouge sur un fond jaune.
    Merci à Joel de m'avoir mis sur la piste.
    C'est en respectant les autres que l'on se fait respecter.

  7. #7
    Membre averti
    Citation Envoyé par joel.drigo Voir le message
    En faisant g.drawImage(image, x, x, null);, ça dessine l'image juste en dehors de l'image, puisque ses dimensions sont x × x.

    C'est g.drawImage(image, 0,0, x, x, null);
    désolé, j'ai pas vu ton message et comme tu vois j'étais arrivé à la même conclusion. Je ne m'explique pas cette erreur car la procédure copie utilisait convenablement drawImage
    C'est en respectant les autres que l'on se fait respecter.

  8. #8
    Rédacteur/Modérateur

    Citation Envoyé par Patrice Henrio Voir le message
    Je confirme, c'était la fatigue.
    La méthode paintComponent de dessin doit être définie ainsi
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	@Override
    	protected void paintComponent(Graphics g)
    	{
    		if (image!=null)
    		{
    			g.drawImage(image, 0, 0, x, x, null);
    		}
    	}

    Il manque un appel a super.paintComponent(g) ou une initialisation de la surface, ce qui peut mener a des soucis d'artefacts graphiques lorsque image vaut null.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook