Java Swing How to - Detect image on current mouse position and edit text mixed with Image in JTextPane








Question

We would like to know how to detect image on current mouse position and edit text mixed with Image in JTextPane.

Answer

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
//from   w  w  w.  ja  v a  2s.co  m
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class Main {

  private static AttributeSet getAttributes(MouseEvent e) {
    JTextPane text = (JTextPane) e.getSource();
    Point mouseLocation = new Point(e.getX(), e.getY());
    int pos = text.viewToModel(mouseLocation);

    if (pos >= 0) {
      try {
        Rectangle rect = text.modelToView(pos);
        int lowerCorner = rect.y + rect.height;
        if (e.getX() < rect.x && e.getY() < lowerCorner && pos > 0) {
          pos--;
        }
      } catch (BadLocationException ex) {
        ex.printStackTrace();
      }
      StyledDocument doc = text.getStyledDocument();
      Element element = doc.getCharacterElement(pos);
      return element.getAttributes();
    }
    return null;
  }

  public static ImageIcon createImage() {
    BufferedImage image = new BufferedImage(28, 28, BufferedImage.TYPE_INT_ARGB);
    Graphics g = image.getGraphics();
    g.setColor(Color.RED);
    g.fillRect(0, 0, 32, 32);
    g.dispose();
    return new ImageIcon(image);
  }

  public static final void main(String[] args) throws Exception {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextPane textPane = new JTextPane();
    textPane.addMouseMotionListener(new MouseAdapter() {
      public void mouseMoved(MouseEvent e) {
        AttributeSet style = getAttributes(e);
        if (style != null && StyleConstants.getIcon(style) != null) {
          textPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        } else {
          textPane.setCursor(Cursor.getDefaultCursor());
        }
      }
    });
    frame.add(new JScrollPane(textPane));

    StyledDocument doc = (StyledDocument) textPane.getDocument();

    SimpleAttributeSet style = new SimpleAttributeSet();
    StyleConstants.setIcon(style, createImage());

    doc.insertString(doc.getLength(), "this is a test", null);
    doc.insertString(doc.getLength(), "test", style);
    doc.insertString(doc.getLength(), "this is a test\n", null);
    doc.insertString(doc.getLength(), "another image", style);

    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setVisible(true);

  }
}