eine gezeichnete graphik speichern.

Status
Nicht offen für weitere Antworten.

raffnix

Bekanntes Mitglied
Hallo.
Ich zeichne auf einem Panel und möchte nach dem zeichnen eines objekts auf einem Button klicken und dann ein neues objekt zeichnen.
Mein problem dabei ist, das wenn ich die alten variablen freigebe um neue werte zu vergeben. Meine ursprüngliche Zeichnung gelöscht wird, sobald ich repaint() aufrufe. Sie soll aber weiter existieren. Nur halt unabhängig.
Gibt es eine möglichkeit diese Zeichnung zu "vefestigen"?
 
Gibt es keine Möglichkeit etwas gezeichnetes zu festigen, sodaß ich die paintComponent wieder verwenden kann?
 
Ich möchte, aber das das gezeichnete noch zu sehen ist.

Wenn ich die PaintComponent weiter benutze und etwas neues zeichne wird das alte gelöscht.
Die daten sind nicht so das problem die kann ich ja auch speichern . mir gehts um das gezeichnete "sichtbare" objekt.
 
Pack alle Objekte, die gezeichnet werden sollen in eine Collection und lass paintComponent alle Objekte dieser Collection zeichnen und fertig...
 
kann ich denn paintComponent die objekte der Collection einzeln zeichnen lassen? sodass ich sie einzeln mit AffineTransform ändern kann? Hier mal etwas code. vll. wird dann mein problem etwas klarer.
Code:
public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
			//Ein Bild anzeigen
			 if ( img != null){
				g2d.drawImage(img, 0, 0, this);
		         }   
			//Affine Transform erzeugen
			 AffineTransform as = new AffineTransform();
			//ein Rechteck malen
			Iterator zaehler = rectpointList.iterator();
			
	         while (zaehler.hasNext())
	         {
	         	g2d.setColor(Color.GREEN);
	         punktrect = (Point) zaehler.next();
	         rechteck.getPathIterator(as);
	         rechteck = new Rectangle2D.Double(punktrect.x,punktrect.y,rectWidth,rectHeight);
	         
	         }	
	         //rechteck scalieren
			if(scaleWidth >0 & scaleHeight >0){
			 as.scale(scaleWidth, scaleHeight);
			double transposx = rechteck.x - rechteck.x * scaleWidth;
			double transposy = rechteck.y - rechteck.y * scaleHeight;
			as.translate(transposx/scaleWidth,transposy/scaleHeight);
			g2d.setTransform(as);}	
			
	        //rechteck rotieren
	         g2d.rotate(theta,rechteck.getCenterX(), rechteck.getCenterY());	
			g2d.draw(rechteck);
			
			
		}

Ich zeichne ein Rechteck und lasse es per maus rotieren, scalieren und verschieben.
 
raffnix hat gesagt.:
kann ich denn paintComponent die objekte der Collection einzeln zeichnen lassen? sodass ich sie einzeln mit AffineTransform ändern kann?
Sicher.
Code:
            while (zaehler.hasNext()) 
            { 
               g2d.setColor(Color.GREEN); 
            punktrect = (Point) zaehler.next(); 
            rechteck.getPathIterator(as); 
            rechteck = new Rectangle2D.Double(punktrect.x,punktrect.y,rectWidth,rectHeight); 
            //An dieser Stelle kannst du jedes Rechteck einzel zeichnen und drehen
            }
 
Das ist super. so könnte es klappen..
nur wie bekomme ich es hin, dass die transformationen immer auf das neuste rechteck angewendet werden??
im moment werden die Transformationen ja immer auf alle objekte angewendet..
Code:
public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
			//Ein Bild anzeigen
			 if ( img != null){
				g2d.drawImage(img, 0, 0, this);
		         }   
			//Affine Transform erzeugen
			 AffineTransform as = new AffineTransform();
			//ein Rechteck malen
			Iterator zaehler = rectpointList.iterator();
			
	         while (zaehler.hasNext())
	         {
	         	g2d.setColor(Color.GREEN);
	         punktrect = (Point) zaehler.next();
	         rechteck.getPathIterator(as);
	         rechteck = new Rectangle2D.Double(punktrect.x,punktrect.y,rectWidth,rectHeight);
	         
	         //rechteck schieben
	         if(locpoint != null){
	         rechteck.setRect(locpoint.x,locpoint.y,rectWidth,rectHeight);
	         }
	         //rechteck scalieren
			if(scaleWidth >0 & scaleHeight >0){
			 as.scale(scaleWidth, scaleHeight);
			double transposx = rechteck.x - rechteck.x * scaleWidth;
			double transposy = rechteck.y - rechteck.y * scaleHeight;
			as.translate(transposx/scaleWidth,transposy/scaleHeight);
			g2d.setTransform(as);}	
			
	        //rechteck rotieren
	         g2d.rotate(theta,rechteck.getCenterX(), rechteck.getCenterY());	
			g2d.draw(rechteck);
	         }
			
		}
 
Am sinnvollsten verwendest du eine eigene Rechteck Klasse die sich selbst zeichnet und selektierbar ist.
Wird ein Rechteck angeklickt ist es selektiert und mit der Maus kannst du dann die rotation bestimmen.
Die paintComponent deines Panels reicht dann beim das Graphics2D Objekt beim repaint an alle Rechtecke weiter.
 
Ähhh...
Ich glaube ich verstehe was du meinst..
nur kann ich mir im Moment nicht vorstellen wie so eine klasse aussehen soll.
Alles was jetzt in meiner paintComponent ist muss dann doch in diese klasse.
wie mache ich die klasse dann selectable?? oder sich selbst zeichnend??
hast du vll. ein Bsp. für so eine klasse?
 
So in etwa. Das Panel muss bei Mausklick entscheiden welches Rectangle selektiert wurde, und ändert dann dessen Eigenschaften, zB den Winkel theta.
Code:
class RectangleShape
{
    private Rectangle r;
    private double theat;

    public RectangleShape(Rectangle r)
    {
        this.r=new Rectangle2D.Double(r.x,r.y,r.width,r.height);

    }

    public void setTheta(double theta)
    {
        this.theta=theta;
    }

    public void draw(Graphics2D g2d)
    {
        g2d.rotate(theta,r.getCenterX(), r.getCenterY());  
        g2d.draw(r);
    }
}
 
Hmm also die class Rechteck hab ich fertig. ich kann auch zeichnen. Wie geht das nun mit dem selectieren?

nun ist es auch nicht anders als es vorher war.. Ich habe bloss noch eine klasse mehr..
Code:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

public class Rechteck{
	 private Rectangle2D r;
	    private double theta;
	    private Point locpoint=null;
	    private double widthScale;
	    private double heightScale;
	    

	    public Rechteck(Rectangle2D.Double r)
	    {
	        this.r=new Rectangle2D.Double(r.x,r.y,r.width,r.height);

	    }

	    public void setTheta(double theta)
	    {
	        this.theta=theta;
	    }

	    public void setLocPoint(Point p){
	    	this.locpoint = p;
	    }
	    
	    public void setScales(double scaleWidth, double scaleHeight){
	    	this.widthScale = scaleWidth;
	    	this.heightScale = scaleHeight;
	    }
	    
	    	    
	    public void draw(Graphics2D g2d)
	    {
	    	g2d.setColor(Color.GREEN);
	    	 AffineTransform as = new AffineTransform();
					
		         //rechteck schieben
		         if(locpoint != null){
		         r.setRect(locpoint.x,locpoint.y,r.getWidth(),r.getHeight());
		         }
		         //rechteck scalieren
				if(widthScale >0 & heightScale >0){
				 as.scale(widthScale, heightScale);
				double transposx = r.getX() - r.getX() * widthScale;
				double transposy = r.getY() - r.getY() * heightScale;
				as.translate(transposx/widthScale,transposy/heightScale);
				g2d.setTransform(as);}
	    	
	        g2d.rotate(theta,r.getCenterX(), r.getCenterY()); 
	        g2d.draw(r);
	    }
	    
	}


Code:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JPanel;


class RechteckDraw extends JPanel{
	Rechteck reckt; 
	public ArrayList scaleList = new ArrayList();
	public ArrayList rectpointList   = new ArrayList();
	public ArrayList transList   = new ArrayList();
	double newWidth;
	double newHeight;
	double Height;
	double Width;
	public double scaleWidth;
	public double scaleHeight;
	double rectWidth = 80;
	double rectHeight = 60;
	public double theta;	
	Image img;	
	Rectangle.Double rechteck = new Rectangle2D.Double(210.0,210.0,80.0,60.0);
	Point punktrect;
	Point locpoint= null;	
	
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		reckt.draw(g2d);
	        	
		}
public void scalegraph (Point p){
	
	newWidth =  p.x - rechteck.x + rechteck.getWidth();
	newHeight = p.y - rechteck.y + rechteck.getHeight();
		Height= newHeight;
	    Width = newWidth;
	    scaleWidth = newWidth/rechteck.getWidth();
	    scaleHeight = newHeight/rechteck.getHeight();
	
	    if(scaleWidth * rechteck.getWidth()== 0 || scaleHeight * rechteck.getHeight()==0 ){
	    	System.out.println("Rechteck zu klein");
	    }
	    else{
	    	reckt.setScales(scaleWidth,scaleHeight);
		repaint();
	    }
}

public void getLocationPoints(Point p){
	locpoint = p;
	reckt.setLocPoint(p);
}

public void getRectPoint(Point p){
 	rectpointList.add(p);
 	Iterator zaehler = rectpointList.iterator();
	
     while (zaehler.hasNext())
     {     	
     punktrect = (Point) zaehler.next();
     rechteck = new Rectangle2D.Double(punktrect.x,punktrect.y,rectWidth,rectHeight);				       
     reckt = new Rechteck(rechteck);
     }		
 	repaint();
 }

public void rotategraph (Point p){		
			theta =  - Math.atan2(p.x - rechteck.getCenterX(), p.y-rechteck.getCenterY());	
			reckt.setTheta(theta);
				repaint();}	
	

public void machImage(String path){
 	try{
 	img = Toolkit.getDefaultToolkit().getImage(path);
 	}
 	catch (Exception exc){
 		System.out.println("Die Datei" + path +"ist kein Bild oder ist beschädigt");
 	}
 	repaint();
 }

}
Code:
import java.awt.BorderLayout;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.SwingUtilities;


class RechteckShow extends JFrame implements MouseListener,MouseMotionListener
{
	
	RechteckDraw mal;
	ButtonGroup grp = new ButtonGroup();
	 JRadioButtonMenuItem move;
	 JRadioButtonMenuItem rotate;
	 JRadioButtonMenuItem point;
	 JRadioButtonMenuItem scale;
	 JRadioButtonMenuItem rect;
	JPopupMenu popup; 
	
	
	RechteckShow(){
		
		popup  = new JPopupMenu();
		move   = new  JRadioButtonMenuItem("move");		
		rotate = new  JRadioButtonMenuItem("rotate");
		scale  = new  JRadioButtonMenuItem("scale");
		rect  = new  JRadioButtonMenuItem("rect");
				
		grp.add(move);
		grp.add(rotate);
		grp.add(scale);
		grp.add(rect);
		
		popup.add(move);
		popup.add(rotate);
		popup.add(scale);
		popup.add(rect);
		
	mal = new RechteckDraw();
	mal.addMouseListener(this);
	mal.addMouseMotionListener(this);
	mal.setSize(500,500);
	getContentPane().add(mal, BorderLayout.CENTER);
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	setSize(800, 600);
	setLocation(100, 100);
			
	}

	public static void main(String[] args){
		ShowPoly f = new ShowPoly();
		f.setVisible(true);
	}
	
	public void mouseClicked(MouseEvent e) {
		if(SwingUtilities.isLeftMouseButton(e)){
		if(e.getSource()== mal & rect.isSelected()==true){
		mal.getRectPoint(e.getPoint());
		}
			
		}
	}
		
	public void mousePressed(MouseEvent e) {
		 if (e.getSource()== mal && SwingUtilities.isRightMouseButton(e))
	           popup.show(e.getComponent(), e.getX(), e.getY());
		
	}
	public void mouseDragged(MouseEvent e) {
		if(e.getSource()== mal && SwingUtilities.isLeftMouseButton(e)){
						
		 if(e.getSource() == mal & rotate.isSelected()==true){
		mal.rotategraph(e.getPoint());
		}
		else if(scale.isSelected()==true){
			mal.scalegraph(e.getPoint());
		}
		else if(move.isSelected() == true){
			mal.getLocationPoints(e.getPoint());
		}
		}
		repaint();
		}

	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub		
	}
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub		
	}
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}	
}

In welcher classe muss ich denn auf den click reagieren?
ich könnte mir vorstellen über contains(p.x,p.y) die rechtecke abzufragen.. Aber wie du ja schon bemerkt hast, geht das nicht wenn das rechteck gedreht ist.
 
Auf den Click reagierst du logischerweise im MosueListener...
rauszufinden auf was geklickt wurde ist eben genau das Problem. Such mal in google, ich kann dir da auch keinen Algorithmus geben.
Ist eben nicht ganz so einfach mit komplexeren Formen. Viel Glück :wink:
 
Ok. soweit schonmal vielen dank.
Kann ich die Rechtecke der reihe nach einer collection adden und dann über ein Auswahlmenü die rechtecke selectieren?? wäre das möglich oder ist das noch komplizierter als auf einen click zu reagieren??
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben