I have a simple question to ask.
Is it possible to do an affine transform outside the paint/paintComponent context?
For instance, let's say i want to create a Shape made of a GeneralPath and then rotate it 45°.
Is it possible to create that object and then rotate it always in the class constructor instead of creating the object and then rotate it in the paint/paintComponent method?
Thank you very much.
UPDATE
Thank you very much for the info guys.
So today i have made a simple test as you suggested and it works.
This is with the Affine transform inside the paintComponent method, commented:
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(new Color(230, 230, 230));
g2.fill(enne.getNuvola());//enne.getNuvola(): code from an omitted class. returns a Shape of a cloud
g2.setColor(new Color(20, 20, 20));
/*
AffineTransform t = AffineTransform.getTranslateInstance(400,400);
g2.transform(t);
*/
g2.fill(rock.getRocket());
}//paintComponent
and this is the affine transform inside the class constructor of a GeneralPath
public class Rocket {
GeneralPath rocket;
public Rocket(){
rocket = new GeneralPath();
rocket.moveTo(10,10);
rocket.lineTo(15,15);
rocket.lineTo(15,50);
rocket.lineTo(5,50);
rocket.lineTo(5,15);
rocket.lineTo(10,10);
rocket.closePath();
AffineTransform t = AffineTransform.getTranslateInstance(400,400);
rocket.transform(t);
}//Rocket Costruttore
public GeneralPath getRocket(){
return this.rocket;
}
}//Rocket
But now i have another question:
Do i have to protect the current state of the current trasform also in the Rocket class like it is suggested to do for the paintComponent method in the java transforming tutorial?
Use the getTransform method to get the current transform.
Use transform, translate, scale, shear, or rotate to concatenate a transform.
Perform the rendering.
Restore the original transform using the setTransform method.
Again, thank you very much for your answers
No, the transform should be reset only to restore the state of the Graphics object, because that Graphics object could be reused by the system for other drawings. If you do the transform without a Graphics object, you don't need to worry about that.
Note for the future that you should not ask new questions by editing old questions, because this is confusing. You should post a completely new question (possibly linking your old question).
Related
I am making a game with Java and LWJGL..
Basically I want to write my game's fps on the screen, but I really don't understand how i should do that.
I am thinking its something related to the Graphics class, am i right?
Graphics g = new Graphics();
g.setColor(Color.YELLOW);
g.setFont(new Font("Impact", Font.PLAIN, 20));
g.drawString(fps + " FPS", 20, 30);
g.dispose();
This code returns me an error..it says that the constructor of the graphics class isn't implemented right.
Any ideas?
To draw, you need the draw handle for the original Graphics object and not by creating a new one yourself.
As far as I can tell, for a basic game, your controlling class should be extending BasicGame which provides a render method, from which you can grab a Graphics object.
See: BasicGame and render
I imagine what you need to do is override that method, like this:
public void render(GameContainer container, Graphics g) throws SlickException {
//grab graphics g here and use it.
}
For a basic template, look here.
You can't just create new Graphics instance from scratch and hope it will draw what you want and where you want.
Graphics contexts are obtained from other graphics contexts or are
created by calling getGraphics on a component.
If you want to put sime text on the screen with LWJGL then search exact and you will find a lot of solutions. Even on youtube.
I thought the create() function of graphics object creates a new copy of the current graphics object
this was my code
Graphics temp;
temp = g.create();
temp.drawString("hello world",100,100);
g.fillRect(200,200,50,50);
Now my understanding was that since temp is now a copy of the g, any change on temp would not be reflected on g. So my output should have been just a rectangle due to the fillRect function. But I am getting both the string and the rectangle on my paint output. Why is this happening and how to stop it?
I am a beginner in java, but, after looking into your code i see that you have put
g.create();
(i'm not very sure but) this could possibly mean that everything declare with g. would be affected. I suggest doing so:
Graphics2D g2d = (Graphics2D) g;
Graphics temp;
temp = g2d.create();
temp.drawString("hello world",100,100);
g.fillRect(200,200,50,50);
hope it worked
Can't you just make a class for the object, for example TextString and Box, and make them have a paint method like so:
public void paint(Graphics g){
g.setColor(Color.RED);
g.fillRect(50, 50, 100, 100);
}
And then wherever you are drawing the objects, call
box.paint(g); or whatever you called your object.
This way you can change the properties of the objects and draw them independently anytime you want without affecting the other objects.
Graphics.create gives you a full or specified section of the Graphics object that generated it - it is not a new Graphics object.
If you wish to draw to a graphics object (and reuse said object) I would suggest using the BufferedImage derivative, OffscreenImage and, from there, draw to the OffscreenImage.getGraphics
I am doing a project in which I need to print the label/description of the line (drawn using graphics) with respect to orientation of the line.
Does anyone know how to do it?
Look to the Graphics2D methods such as rotate(), scale() & translate() - as well as the more general translate(AffineTransform) method.
See Transforming Shapes, Text, and Images in the Java tutorial for more details and working examples, especially of using an AffineTransform (which can concatenate scale, rotate, transform & shear operations).
You do not mention how you obtain the Graphics object. The Graphics object passed to Swing components in paintComponent(Graphics) will generally be a Graphics2D instance, and can be cast to one. To get a Graphics2D instance from a BufferedImage, call createGraphics().
Make a class called "Labelled line" and make it something like this
class LabeledLine {
private int x1, y1, x2, y2;
private String label;
public void drawOn(Graphics g) {
// need more features? thickness, etc? add it
g.drawLine(x1,y1,x2,y2);
// compute size of text, position of text, angle of text
// draw that text
}
}
A quick google for drawing angled text gave me a couple results, so that should be easy to do.
Are there any in-built methods in the Java API which would allow me to resize a polygon?
Would it be quite a simple task to write my own method, or are there any others already made?
No, nothing built in, altho, when you draw the polygon, you can draw the polygon with a transformation matrix applied which could scale the polygon for you. (or rotate, skew, etc, etc).
see
Graphics2D.setTransform(transform);
Lets assume you are drawing the polygon in a JPanel, and you have overridden the paintComponent method of JPanel. Cast the Graphics object to a Graphics2D object, and use transforms to scale it as appropriate:
public void paintComponent(Graphic g) {
Graphics2D g2d = (Graphics2D) g;
AffineTransform saveTransform = g2d.getTransform();
try {
AffineTransform scaleMatrix = new AffineTransform();
scaleMatrix.scale(1.5, 1.5);
//or whatever you want
g2d.setTransform(scaleMatrix);
g2d.drawPolygon(myPolygon);
} finally {
g2d.setTransform(saveTransform);
}
}
Chances are you can set up the transformation matrix elsewhere (once) instead of each time in the paintComponent method, but i did here to show how to do it.
Also note, that this will move the polygon, you would probably want apply this to the transform:
add a translate to move the polygon to the origin
add a scale
add a translate to move the polygon back to the original position
in this way, the object doesn't move it just scales.
Yes, AffineTransform.createTransformedShape(Shape) will create a transformed copy of any Shape (which may be a Polygon or Path2D.)
I'm Basically programming a simple game engine but I'm having problems with my sprites/images not appearing when they should... or at all!
I'll try and keep this as simple as possible. I have a Sprite, GameEngine and Display class. In the gameloop, I have a method that sets the new position of my Sprite (so it just sets the x and y variables). Next I call a transform method which does the following:
public void transform() {
affineTransform.setToIdentity();
affineTransform.translate(x, y);
}
Following that, I then call a draw method in the Sprite:
public void draw() {
graphics2D.drawImage(image, affineTransform, jFrame);
}
Finally, in my thread I then call repaint() on the JFrame (the Display class). My paint method for that class is as follows:
public void paint(Graphics g) {
g.drawImage(backbuffer, insets.left, insets.top, this);
}
But nothing is appearing, apart from a black screen!
I'm also getting confused between Graphics g, and Graphics2D and when to use either. (The overridden paint method uses Graphics g). For the record, I do have a Graphics2D variable in the class that is created by calling backbuffer.createGraphics();
Another thing that is confusing me is this AffineTransform... I've read the documentation but I'm still utterly confused on how and when to use it - and what exactly it seems to do. Is there any explanation in relatively simple terms?
Surely this should be working... am I missing something out here?
To answer part of your question:
From the Graphics2D JavaDoc
This Graphics2D class extends the Graphics class to provide more sophisticated control over geometry, coordinate transformations, color management, and text layout. This is the fundamental class for rendering 2-dimensional shapes, text and images on the Java(tm) platform.
Essentially, with Graphics2D you can do much more than you can with Graphics. And with a Sun JVM 1.5+, it should be safe to cast the Graphics object you get in paint() to Graphics2D
I just noticed this: For the record, I do have a Graphics2D variable in the class that is created by calling backbuffer.createGraphics();
You should make sure you're not drawing on a Graphics[2D] canvas (I'll use this term to refer to the drawable area that the Graphics[2D] object provides) that you later throw away. If you're drawing your image on a separate canvas, you should ensure that you then draw that image onto your actual display canvas.
I don't really have a good explanation of AffineTransform but maybe these will help?
http://www.javalobby.org/java/forums/t19387.html
https://secure.wikimedia.org/wikipedia/en/wiki/Affine_transformation
From Wikipedia - In general, an affine transformation is composed of linear transformations (rotation, scaling or shear) and a translation (or "shift"). Several linear transformations can be combined into a single one. Basically, you use this class to perform operations such as rotation, translation, zoom etc.