String"text" mit der Maus auf Graphic2D verschieben

munuel

Mitglied
Hallo ,
Ich möchte auf einem Graphics2D einen String-Text markieren können und diesen mit der Maus verschieben können. Ich weiss aber nicht wie ich herausbekomme ob die Maus gerade den String berührt. Bei Figuren gibt es ja die .contains( ) Methode bei einem String aber nicht.

Mein Gerüst sieht wie folgt aus:

PHP:
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class TextMedia extends JPanel {

	private String string = new String("hallo");
	private Font ft = new Font(string,1,5);

	public TextMedia(){
		addMouseListener(new MouseAdapter() {
		      public void mousePressed(MouseEvent evt) {
		        int x = evt.getX();
		        int y = evt.getY();
		      }
		      public void mouseClicked(MouseEvent evt) {
		        int x = evt.getX();
		        int y = evt.getY();
		        // wie kann ich hier herausfinden ob ich den String treffe?
		      }
		    });
	}
	public static void main(String[] args) {
		JFrame frm = new JFrame();
		frm.setBounds(100, 100, 400, 400);
		frm.setLayout(new GridLayout());
		TextMedia textMedia = new TextMedia();
		textMedia.setBounds(100, 100, 300, 300);
		frm.add(textMedia);
		frm.setVisible(true);
	}
	public void paint(Graphics g){
		Graphics2D d = (Graphics2D) g;		
		d.drawString(string, 100, 100);
	}
}

Viele Grüsse munuel
 
Moin!
Hier ein kleines Beispiel um zu testen, ob die Maus auf dem Text liegt:
Code:
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;


/**
 * @author Jörg Weckbach
 *
 */
public class TestPanel extends JPanel implements MouseListener{
    private Font font= null;
    private FontMetrics fm = null;
    private String text = "Text Test";
    private int xPos = 80;
    private int yPos = 50;
    public TestPanel(){
        font = new Font(Font.SERIF, Font.PLAIN,18);
        fm = getFontMetrics(font);
        this.addMouseListener(this);
        
    }
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setFont(font);
        g2.drawString(text, xPos,yPos);
        
    }
    
    

    

    public void mouseClicked(MouseEvent arg0) {
        Point mousePoint = arg0.getPoint();
        int with = fm.stringWidth(text);
        int height = fm.getHeight();
        Rectangle rec = new Rectangle(xPos,yPos-height,with,height);
        System.out.println("mousePosition:= "+mousePoint);
        System.out.println("string bounds := "+rec.getBounds());
        if(rec.contains(mousePoint)){
            System.out.println("contains point");
        }
        else{
            System.out.println("not contains point");
        }
    }


    public void mouseEntered(MouseEvent arg0) {}


    public void mouseExited(MouseEvent arg0) {}


    public void mousePressed(MouseEvent arg0) {}


    public void mouseReleased(MouseEvent arg0) {}    
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        TestPanel  p= new TestPanel();
        frame.getContentPane().add(p);
        frame.setSize(200,200);
        frame.setVisible(true);
    }
}


*grüssle*
MeinerEiner
 
Zuletzt bearbeitet von einem Moderator:
hi danke für die Hilfe Jörg,

Ich hab an dem Beispiel mal weitergemach. Bin aber auf ein Problem gestossen.:mad:


PHP:
package maus;

/**
 * @author Chris Joh
 *
 */

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;


/**
 * @author Jörg Weckbach
 *
 */
public class TestPanel extends JPanel implements MouseListener , MouseMotionListener{
    private Font font= null;
    private FontMetrics fm = null;
    private String text = "Text Test";
    private int xPos = 80;
    private int yPos = 50;
    private boolean bTouche = false;
    public TestPanel(){
        font = new Font("TimesRoman", Font.PLAIN,18);
        fm = getFontMetrics(font);
        this.addMouseListener(this);
        
    }
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setFont(font);
        g2.drawString(text, xPos,yPos);
        
    }
    
    public void mouseClicked(MouseEvent arg0) {
        Point mousePoint = arg0.getPoint();
        int with = fm.stringWidth(text);
        int height = fm.getHeight();
        Rectangle rec = new Rectangle(xPos,yPos-height,with,height);
        System.out.println("mousePosition:= "+mousePoint);
        System.out.println("string bounds := "+rec.getBounds());
        if(rec.contains(mousePoint)){
            System.out.println("contains point");   
        }
        else{
            System.out.println("not contains point");
        }
    }

    public void mouseEntered(MouseEvent arg0) {}

    public void mouseExited(MouseEvent arg0) {}

    public void mousePressed(MouseEvent arg0) {
    	Point mousePoint = arg0.getPoint();
        int with = fm.stringWidth(text);
        int height = fm.getHeight();
        Rectangle rec = new Rectangle(xPos,yPos-height,with,height);
        if(rec.contains(mousePoint)){         
            bTouche = true;
        }
        else{         
            bTouche = false;
        }
    }
   
    public void mouseReleased(MouseEvent arg0) {}
    
    public void mouseDragged(MouseEvent arg0){
    	if (bTouche == true){    	
    		Point mousePoint = arg0.getPoint();                         
            Graphics2D g = (Graphics2D) this.getGraphics();
            g.setFont(font);            
            g.drawString(text,mousePoint.x,mousePoint.y);
            g.dispose();
    	}        	
    }

    public void mouseMoved(MouseEvent arg0){
    	
    }
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        TestPanel  p= new TestPanel();
        frame.getContentPane().add(p);
        frame.setSize(200,200);
        frame.setVisible(true);
        
        Container contentPane = frame.getContentPane();
        contentPane.add(new MouseDragActionPanel());
        
    }
}

Leider hab ich das Problem das die Funktion mouseDragged nie aufgerufen wird.
Daher kann ich auch nicht die Position der Schrift verändern.
Anscheinen ist ein String keine Componente die auf die Maus-Events reagiert :confused:
Hat jemand vielleicht eine Lösung :)

Viele Grüsse munuel
 
Moin!
Ohne den Code jetzt weiter zu teste, würde ich behaupten, es liegt daran, dass du keinen MouseMotionListener registriert hast...

*grüssle*
MeinerEiner
 
Hallo!

für Pixelgenaue "Anfasspunkte" würde sich auch folgendes anbieten:
Java:
/**
 * 
 */
package de.tutorials;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;

import javax.swing.JFrame;

/**
 * @author Tom
 * 
 */
public class MoveStringThroughPointerExample extends JFrame {

    String s = "www.tutorials.de";
    GlyphVector glyphVector;
    Font font;
    int x = 100;
    int y = 200;

    public MoveStringThroughPointerExample() {
        super("MoveStringThroughPointerExample");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(640, 480);
        setVisible(true);
        font = getGraphics().getFont().deriveFont(Font.BOLD).deriveFont(36f);
        glyphVector = font.createGlyphVector(getGraphics().getFontMetrics()
                .getFontRenderContext(), s);
        addMouseMotionListener(new MouseMotionAdapter() {

            int xOld = -1;
            int yOld = -1;

            @Override
            public void mouseDragged(final MouseEvent e) {
                final Point point = e.getPoint();
                final GeneralPath outline = (GeneralPath) glyphVector
                        .getOutline();
                outline.transform(AffineTransform.getTranslateInstance(x, y));
                if (outline.contains(point)) {
                    if (xOld != -1 && yOld != -1) {
                        final int dx = xOld - point.x;
                        final int dy = yOld - point.y;
                        x -= dx;
                        y -= dy;
                        repaint();
                    }
                }

                xOld = point.x;
                yOld = point.y;
            }

            @Override
            public void mouseMoved(final MouseEvent e) {
                xOld = -1;
                yOld = -1;
            }
        });
    }

    @Override
    public void paint(final Graphics g) {
        super.paint(g);
        g.setFont(font);
        g.drawString(s, x, y);
    }

    /**
     * @param args
     */
    public static void main(final String[] args) {
        new MoveStringThroughPointerExample();
    }
}

Gruß Tom
 
Hi,
Vielen Dank für Eure Beiträge!
@MeinerEiner
Da hast du natürlich recht (Vergessen am MotionListener anzumelden), typischer Anfängerfehler.:rolleyes:

@Thomas
Dein Bsp. ist sehr schön aber beim bewegen des Textes beim ziehen wird man immer wieder unterbrochen. (Vielleicht liegt das an der Pixelgenauigkeit).

Ich hab mein Bsp. erweitert und es klappt ganz gut jetzt. Bis darauf das der Text beim ziehen etwas "schliert". Beim Bewegen wird nachgezeichnet. Gibt es da vielleicht noch einen Trick ;-) .


PHP:
/**
 * @author Chris Joh
 *
 */

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Jörg Weckbach
 *
 */
public class TestPanel extends JPanel implements MouseListener , MouseMotionListener{
    private Font font= null;
    private FontMetrics fm = null;
    private String text = "Text Test";
    private int xPos = 80;
    private int yPos = 50;
    private boolean bTouche = false;
    private boolean bDragged = false;
    public TestPanel(){
        font = new Font("TimesRoman", Font.PLAIN,18);
        fm = getFontMetrics(font);
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        
    }
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setFont(font);
        g2.drawString(text, xPos,yPos);       
    }
    
    public void mouseClicked(MouseEvent arg0) {}
    public void mouseEntered(MouseEvent arg0) {}
    public void mouseExited(MouseEvent arg0) {}

    public void mousePressed(MouseEvent arg0) {
    	bDragged = false;
    	Point mousePoint = arg0.getPoint();
        int with = fm.stringWidth(text);
        int height = fm.getHeight();
        Rectangle rec = new Rectangle(xPos,yPos-height,with,height);
        if(rec.contains(mousePoint)){         
            bTouche = true;
        }
        else{         
            bTouche = false;
        }
    }
   
    public void mouseReleased(MouseEvent arg0) {
    	if (bDragged){
    	Point mousePoint = arg0.getPoint(); 
    	 Graphics2D g = (Graphics2D) this.getGraphics();
    	 xPos = mousePoint.x;
    	 yPos = mousePoint.y;
    	g.drawString(text,xPos,yPos);
        g.dispose();
        this.repaint();
    	}
    }
    
    public void mouseDragged(MouseEvent arg0){
    	if (bTouche == true){    	
    		Point mousePoint = arg0.getPoint();        
    		Graphics g = getGraphics();
    	    g.setXORMode(getBackground());    	   
            g.drawString(text,mousePoint.x,mousePoint.y);
            g.dispose();        
            bDragged=true;          
    	}      
    }

    public void mouseMoved(MouseEvent arg0){
    }
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        TestPanel  p= new TestPanel();
        frame.getContentPane().add(p);
        frame.setSize(200,200);
        frame.setVisible(true);
        
        Container contentPane = frame.getContentPane();
        contentPane.add(new MouseDragActionPanel());        
    }
}

Viele Grüsse munuel
 
Moin!
du solltest die draw Methoden nicht in den Event Methoden aufrufen. Sondern nur die Punkte aktualisieren:
Code:
/**
 * @author Chris Joh
 *
 */

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Jörg Weckbach
 *
 */
public class TestPanel extends JPanel implements MouseListener , MouseMotionListener{
    private Font font= null;
    private FontMetrics fm = null;
    private String text = "Text Test";
    private int xPos = 80;
    private int yPos = 50;
    private boolean bTouche = false;
    private boolean bDragged = false;
    public TestPanel(){
        font = new Font("TimesRoman", Font.PLAIN,18);
        fm = getFontMetrics(font);
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        
    }
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setFont(font);
        g2.drawString(text, xPos,yPos);
        
    }
    
    public void mouseClicked(MouseEvent arg0) {}
    public void mouseEntered(MouseEvent arg0) {}
    public void mouseExited(MouseEvent arg0) {}

    public void mousePressed(MouseEvent arg0) {
        bDragged = false;
        Point mousePoint = arg0.getPoint();
        int with = fm.stringWidth(text);
        int height = fm.getHeight();
        Rectangle rec = new Rectangle(xPos,yPos-height,with,height);
        if(rec.contains(mousePoint)){         
            bTouche = true;
        }
        else{         
            bTouche = false;
        }
    }
   
    public void mouseReleased(MouseEvent arg0) {
        if (bDragged){
            Point mousePoint = arg0.getPoint(); 
            Graphics2D g = (Graphics2D) this.getGraphics();
             xPos = mousePoint.x;
             yPos = mousePoint.y;
             this.repaint();
        }
    }
    
    public void mouseDragged(MouseEvent arg0){
        if (bTouche == true){        
            Point mousePoint = arg0.getPoint();        
            xPos = mousePoint.x;
            yPos = mousePoint.y;
            bDragged=true;  
            this.repaint();
        }      
    }

    public void mouseMoved(MouseEvent arg0){}
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        TestPanel  p= new TestPanel();
        frame.getContentPane().add(p);
        frame.setSize(200,200);
        frame.setVisible(true);
        
        Container contentPane = frame.getContentPane();
        //contentPane.add(new MouseDragActionPanel());        
    }
}
 
Hallo,

jo schaut ganz so aus als wäre die Pixelgenaue Variante doch nicht so das gelbe vom Ei...
Java:
/**
 * 
 */
package de.tutorials;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;

/**
 * @author Tom
 * 
 */
public class MoveStringThroughPointerExample extends JFrame {

    String s = "www.tutorials.de";
    GlyphVector glyphVector;
    Font font;
    int x = 100;
    int y = 200;

    Rectangle outline;

    Runnable renderer = new Runnable() {
        public void run() {
            while (true) {

                Graphics2D g = (Graphics2D) getBufferStrategy()
                        .getDrawGraphics();
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g.setFont(font);
                g.clearRect(0, 0, getWidth(), getHeight());
                g.drawString(s, x, y);
                if (outline != null) {
                    g.draw(outline);
                }
                g.dispose();
                getBufferStrategy().show();

                try {
                    TimeUnit.MILLISECONDS.sleep(50L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    };

    public MoveStringThroughPointerExample() {
        super("MoveStringThroughPointerExample");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);
        setVisible(true);
        font = getGraphics().getFont().deriveFont(Font.BOLD).deriveFont(72f);
        glyphVector = font.createGlyphVector(getGraphics().getFontMetrics()
                .getFontRenderContext(), s);
        addMouseMotionListener(new MouseMotionAdapter() {

            int xOld = -1;
            int yOld = -1;

            @Override
            public void mouseDragged(final MouseEvent e) {
                final Point point = e.getPoint();
                Rectangle2D visualBounds = glyphVector.getVisualBounds();
                outline = new Rectangle(x + (int) visualBounds.getX(), y
                        + (int) visualBounds.getY(), (int) visualBounds
                        .getWidth(), (int) visualBounds.getHeight());
                if (outline.contains(point)) {
                    if (xOld != -1 && yOld != -1) {
                        final int dx = xOld - point.x;
                        final int dy = yOld - point.y;
                        x -= dx;
                        y -= dy;
                    }
                }

                xOld = point.x;
                yOld = point.y;
            }

            @Override
            public void mouseMoved(final MouseEvent e) {
                xOld = -1;
                yOld = -1;
                outline = null;
            }
        });

        createBufferStrategy(2);
        Executors.newSingleThreadExecutor().execute(renderer);
    }

    /**
     * @param args
     */
    public static void main(final String[] args) {
        new MoveStringThroughPointerExample();
    }
}

Gruß Tom
 
So, und wenn wir jetzt noch ein bisserl beim Thomas klauen *grins* und uns ebenfalls die alten Koordinanten merken, verschiebt sich der Text auch nicht mehr beim ziehen:
Code:
import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Jörg Weckbach
 *
 */
public class TestPanel extends JPanel implements MouseListener , MouseMotionListener{
    private Font font= null;
    private FontMetrics fm = null;
    private String text = "Text Test";
    private int xPos = 80;
    private int yPos = 50;
    private int xOld = -1;
    private int yOld =-1;
    private boolean bTouche = false;
    private boolean bDragged = false;
    public TestPanel(){
        font = new Font("TimesRoman", Font.PLAIN,18);
        fm = getFontMetrics(font);
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        
    }
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setFont(font);
        g2.drawString(text, xPos,yPos);
        
    }
    
    public void mouseClicked(MouseEvent arg0) {}
    public void mouseEntered(MouseEvent arg0) {}
    public void mouseExited(MouseEvent arg0) {}

    public void mousePressed(MouseEvent arg0) {
        bDragged = false;
        Point mousePoint = arg0.getPoint();
        int with = fm.stringWidth(text);
        int height = fm.getHeight();
        Rectangle rec = new Rectangle(xPos,yPos-height,with,height);
        if(rec.contains(mousePoint)){         
            bTouche = true;
        }
        else{         
            bTouche = false;
        }
    }
   
    public void mouseReleased(MouseEvent arg0) {
        if (bDragged){
            Point mousePoint = arg0.getPoint(); 
            Graphics2D g = (Graphics2D) this.getGraphics();
            if((xOld != -1)&&(yOld!= -1)){
                int dx = xOld - mousePoint.x;
                int dy = yOld - mousePoint.y;
                xPos -= dx;
                yPos -= dy;
            }
            xOld = mousePoint.x;
            yOld = mousePoint.y;
            //g.drawString(text,xPos,yPos);
             //g.dispose();
            this.repaint();
        }
    }
    
    public void mouseDragged(MouseEvent arg0){
        if (bTouche == true){        
            Point mousePoint = arg0.getPoint();        
            if((xOld != -1)&&(yOld!= -1)){
                int dx = xOld - mousePoint.x;
                int dy = yOld - mousePoint.y;
                xPos -= dx;
                yPos -= dy;
            }
            xOld = mousePoint.x;
            yOld = mousePoint.y;
            bDragged=true;  
            this.repaint();
        }      
    }

    public void mouseMoved(MouseEvent arg0){
        xOld = -1;
    	yOld = -1;
    }
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        TestPanel  p= new TestPanel();
        frame.getContentPane().add(p);
        frame.setSize(200,200);
        frame.setVisible(true);
        
        Container contentPane = frame.getContentPane();
        //contentPane.add(new MouseDragActionPanel());        
    }
}

*grüssle*
MeinerEiner
 
Zuletzt bearbeitet von einem Moderator:
Zurück