Domanda

I have been trying to transfer images (drawings) from the clipboard to JTextPane or JTextArea. The attached code correctly displays the images in these windows but the images disappear as soon as I take the cursor off the windows. How can I fix the images in the JText...? Something is clearly missing in my code. My internet search did not produce anything useful. I did not have this problem with C#. I would highly appreciate your help.

    private void jTextPaneStructuresMouseClicked(java.awt.event.MouseEvent evt)     {                                                 

    TransferImage.TransferableImage newImage = new TransferImage.TransferableImage(image);

        transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents( null );

        if ( transferable != null && transferable.isDataFlavorSupported( DataFlavor.imageFlavor ) ) {
            try {
                image = (Image)transferable.getTransferData( DataFlavor.imageFlavor );
                Image cpImage = newImage.getTransferData(DataFlavor.imageFlavor);
                jTextPaneStructures.getGraphics().drawImage(cpImage, 0, 0, rootPane);
            } catch (    UnsupportedFlavorException | IOException ex) {
                Logger.getLogger(WeeklyData.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }     



    /* This is what TransferImage.TransferableImage refers to */

    public class TransferImage 
{ 
  static class TransferableImage implements Transferable
  {
      /* -- image for transfer */
        private final Image image;

      /* -- constructor */

      public TransferableImage(Image image)
      {
      this.image = image;
      {
   }
      }
    @Override
   public DataFlavor[] getTransferDataFlavors()
         {
            return new DataFlavor[]
            { 
                DataFlavor.imageFlavor
            };
         }

    @Override
   public boolean isDataFlavorSupported( DataFlavor flavor )
        {
            return flavor == DataFlavor.imageFlavor;
        }

    @Override
   public Image getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException {
        if ( isDataFlavorSupported( flavor ) )
        {
             return image;
        } 
        else
        {
             throw new UnsupportedFlavorException( flavor );
        }
      }
   }          
È stato utile?

Soluzione

If you execute getGraphics().drawImage in your listener you do draw the image on the JTextArea, but as soon as the systems repaints the JTextArea your image disappears because it's not stored in the JTextArea.

I think you should follow a different approach:

  • Write a new class that extends JTextArea (MyTextArea)
  • include a private property to store the image (myImage)
  • provide a set method to set the image (setImage)
  • override paintComponent method so that:
    • it calls super.paintComponent
    • then executes graphics.drawImage(myImage, 0, 0, rootPane) //Well, you may have to fix something about rootPane

Then, in your code:

  • jTextPaneStructures must be an instance of your new class (MyTextArea)
  • in your listener (you may even want to provide a single method in MyTextArea that performs these three tasks):
    • jTextPaneStructures.setImage(cpImage);
    • jTextPaneStructures.invaliate();
    • jTextPaneStructures.repaint();

Example:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

public class MyTextArea extends JTextArea implements MouseListener {

   private Image myImage;

   public MyTextArea() {
      addMouseListener(this);
   }

   public void addImage(Image image) {
      this.myImage = image;
      invalidate();
      repaint();
   }

   @Override
   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(myImage, 0, 0, this);
   }

   public static void main(String[] args) {
      JFrame f = new JFrame("Test");
      MyTextArea txt = new MyTextArea();
      f.getContentPane().add(txt);
      f.getContentPane().add(new JButton("Just another component to click on"), BorderLayout.SOUTH);
      f.pack();
      f.setVisible(true);

   }

   @Override
   public void mouseClicked(MouseEvent e) {
      ImageIcon img = new ImageIcon("twitter.png"); //place a png image in your working directory for testing
      addImage(img.getImage());

   }

   @Override
   public void mousePressed(MouseEvent e) {
      // TODO Auto-generated method stub

   }

   @Override
   public void mouseReleased(MouseEvent e) {
      // TODO Auto-generated method stub

   }

   @Override
   public void mouseEntered(MouseEvent e) {
      // TODO Auto-generated method stub

   }

   @Override
   public void mouseExited(MouseEvent e) {
      // TODO Auto-generated method stub

   }

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top