drawing simple shapes -> paint method and interface for JavaFX - java

I'm doing an assignment for school and I can't get my head around the logic I need to use to solve this. I hope some of you can point me in the right direction.
I have some classes to draw simple shapes:
Class Diagram 1
Extended Class Diagram
According to the assignment every deferred class under DrawingItem needs a paint() method to be able to paint the particular (Oval, Spline etc..) independent from GraphicsContext. For Oval, my guess is this method would be something like:
public void paint(Graphics g){
g.setColor(super.getColor());
g.drawOval(
(int) dw.getAnchor().getX(), (int) dw.getAnchor().getY(),
(int)this.width, (int)this.height
);`
}
Extended class diagram shows an interface IPaintable which I have created with a method for every shape. The JavaFX side (DrawingTool) implements this interface and all of its methods. These methods want the shape object as argument. I use these methods to draw the shapes in javaFX, again the oval example:
strokeOval(
oval.getHeight(), oval.getWidth(), oval.getAnchor().getX(), oval.getAnchor().getY()
);
The main questions I have are these:
Am I going in the right direction with the paint() methods in the shape subclasses and if so how do I call them from the JavaFX side?
How can I "implement" the paint(paintable:IPaintable) method in the Drawing and DrawingItem classes?

There are 2 design patterns easily identifiable in the class diagrams:
The IPaintable is supposed to be a wrapper(Facade) for the GUI drawing operations allowing you to use the classes in Class Diagram 1 independent from the GUI library used. You should only use the methods provided by IPaintable in the paint methods.
The classes in Class Diagram 1 are the command part of the Command Pattern; DrawingTool is the invoker/client and IPaintable is the receiver.
The DrawingTool class should contain code like this:
IPaintable paintable = new JavaFXPaintable(canvas.getGraphicsContext());
and use it like this, if the drawing needs to be redrawn:
drawing.paint(paintable);
Implementing the paint methods
Since a Oval can be drawn using IPaintable's methods, it should implement paint like this:
public void paint(IPaintable paintable) {
paintable.setColor(color);
paintable.paintOval(this);
}
Polygon would use the paintLine methods of the IPaintable passed to it's paint method for drawing itself, Drawing.paint would clear the IPaintable and draw all it's items ect.
In JavaFxPaintable the paintOval method would be implemented like this:
public void paintOval(Oval oval) {
Point anchor = oval.getAnchor();
graphics.strokeOval(anchor.getX(), anchor.getY(), oval.getWidth(), oval.getHeight());
}
You may need to modify this a bit, if anchor denotes the top-left instead of the the center.

Thanks fabian, pointing me in this direction realy helped a lot (as cleaning up my post for readability did too).
Now I have implemented these pointers and they seem to work. With the draw() method in Drawingtool I call the paint(IPaintable paintable) method in the Drawing class, which loops through the list of drawingitems in this class like so:
public void paint(IPaintable paintable){
for (DrawingItem test : drawingitems){
if (test instanceof Oval){
paintable.paintOval((Oval) paintable);
} else if (test instanceof Image){
paintable.paintImage((Image) paintable);
This should paint the shapes and seem to work. The last part is adding them to the canvas initialized in the DrawingTool class. I can't seem to figure out how to do this. I've tried to add them while going through the list with drawing items but this does not seem to work (or I'm handling it wrong).

Related

Java Swing brief paintComponent graphics

I am creating a java 2D game and have come to a point where I am thinking of creating "pop-up graphics" i.e graphics that will populate the screen when a certain event occurs. Say, you pick up a certain item, I want this item to be displayed in the middle of the screen in a box containing information about said item.
Currently I have one big paintComponent that paints all of the graphics for the game (tiles, entities, players etc (which has been done efficiently I might add)). I know that I can probably have a boolean value which checks if an item has been picked up in that method, but it feels wrong.
What I am wondering is, is there a way for items to have their own paintComponent so that when it is called, it will show say a bo for a brief period WITHOUT having a boolean value in the big paintComponent method that I currently use for everything?
Small code example (won't execute)
public class popUpGraphics extends (JComponent or JPanel or whatever works best for this scenario)
{
public popUpGraphics(){
}
#Override
protected void paintComponent(Graphics g){
//g.Draw(stuff);
}
}
and then somewhere in an event I instantiate this or somesuch.
I do not want this to override the other paintcomponent, I just want to add to it
(as if it was another layer) to the paintComponent
In short I want to know:
1. Is is possible to have brief graphics shown without including in the huge paintComponent method
2. What Swing library should be extended (JComponent, JPanel etc)
Thanks in advance!

How to dispose box2d shapes properly?

I'm starting to create my World with Box2d in Libgdx and I have to create shapes for different game objects. The tutorial I've read said I should dispose my shapes when I'm done using them.
So, I started keeping references like that:
private CircleShape circle;
private PolygonShape ground;
private PolygonShape wall;
private PolygonShape box;
//...
//(getters)
And disposing my objects like that:
#Override
public void dispose()
{
circle.dispose();
ground.dispose();
wall.dispose();
box.dispose();
world.dispose();
}
I decided to change this to a list for expansion but the problem is somewhere else in my code, I'm adding bodies on click so I need to let the access to some shapes from external classes. I could create extra shapes and let access to my list but I don't like the idea of creating a giant list of disposable objects.
A solution would be to create a ShapeManager object that has an internal list of shapes. I could dispose this object and it would wrap the shapes constructors letting me return an already existing shape if it fit the need.
However, this solution seem too heavy. Why Box2d (or LibGDX) made the shapes objects that need to be disposed ? Is there a class like I described already included in LibGDX ? Is there a better solution ?
You can dispose after making the definition of your body.

How to Draw a "Class" in Java on a JPanel

Currently I am using a JFrame that has a JPanel in it. In my JPanel I have overridden the paint component method, However, I want to "draw" a "Hero" class as a unit. Let me elaborate. The hero class as of right now has two parts: A health bar and an image. Originally, in the paint component method of my JPanel, I was drawing the character and health bar individually.
public void paintComponent(Graphics g){
g.drawImage(h.getImage(), h.getX(), h.getY(),null);
g.setColor(Color.red);
g.fillRect(h.getX()+7, h.getY()-16, 50, 10);
g.drawLine(h.getX() + (h.getImage().getWidth(getFocusOwner())/2), h.getY()-40, h.getX() + (h.getImage().getWidth(getFocusOwner())/2), h.getY()+40);
}
This properly aligned the health bar and character together, however, this seemed inefficient and messy. So, is there anyway I could draw the two together as a unit? I pondered making them a separate JPanel, but realized that was a silly idea. Is there anyway to do this more efficiently? One of the biggest reasons i am looking for a solution now is that i would like to be able to extend the character class with other classes IE: Monster, Knight, Goblin but when i draw them their respective health bars and images lined up. If you need any further explanation please ask. Thank you!
Also, to spark any ideas that you might have, I'm imagining something like this. Another thing: Would using canvas be of any use?
paint(Hero);
Thank you again!
In your Hero class define a drawing method which accepts a Graphics object:
public void drawHero(Graphics g)
{
// implementation
}
Then in your main JPanel subclass draw the Hero with this drawing method:
public void paintComponent(Graphics g)
{
// other drawing code
hero.drawHero(g);
}

Adding a method draw() to custom shape classes

This is a bonus question on my homework assignment.
The title says it all, I've built custom shape classes and need to define the draw() method for each one and I'm having a bit of trouble finding a good source tutorial for how to go about doing this.
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
This explains exactly what I'm attempting to do but there's no guidance beyond what I already had so if anyone has any additional sources that I can utilize, I'd really appreciate the links.
As far as what I currently have:
abstract public void draw();
I've defined my draw function in my Shape class like so, and within each of my inherited shapes I've put:
public void draw(){}
So they currently do nothing. That is where my problem lies. I'm not sure where to continue from here, as far as actual implementations go, for instructing the shape to draw onto the jframe window and additionally, how I will eventually call the functions themselves in order to draw them on the actual window.
Any links, sources or other posts are more than welcome as my brain is rather mushy right now.
Thanks!
Edit 1: So looking over the typical 2D graphics stuff I realized I couldn't use the normal implementations because of how my shapes are made. They're constructed using a Point reference and then built based on those points, so for instance my Circle looks something like this:
class Circle extends Shape{
private static final double PI = Math.PI;
private Point point;
private double radius;
public Circle (Point p, double rad){
point = p;
radius = rad;
}
}
So I'm not able to use the normal oval(int,int,int,int) format. Sorry for not including this earlier, brain mush.

Mouselistener in chess game

I am creating a chess game, and I have now populated my graphic chessboard with all the pieces, now I need to use Mouselistner to move the pieces around. Before implementing the graphic version I created a 2D console version, that took in "player moves", so I do have all those methods, but I need to now use Mouselistener, I read up about the methods, however, do I need to implement mouselistener in each class?
I have 1 abstract Piece class as well as 7 subclasses (incl Dummy piece), and a ChessBoard class that populates all the pieces and provides methods for moving (from the console version..) so where do I put the mouselistener? In the Jcomponent extension, JFrame or ChessBoard class that contains the methods to populate the chessboard and moves?
Sorry for such a simple answer, but all you need to do is add the mouselistener to your ChessBoard class. From there I'm assuming you can access the Piece subclass objects you've instantiated and call methods on them (i.e. mouseClicked, piece.pickUp()). If you code is arranged in such a way that you need to implement a mouse listener in many of your classes, consider the following:
addMouseListener( new MouseAdapter() {
#Override
public void mouseClicked( MouseEvent e ) {
// Do something
}
} );
http://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseAdapter.html
Also, if it were me, I would transfer the methods for moving your Pieces to your Piece class, preferably at a higher level and then you don't have to rewrite the same code twice. Then in your game, whenever mouseReleased is invoked, call some method like attemptToMove(BoardPoint p) that will check if your piece's current position and the new position, p are within your piece's means of travel. A BoardPoint could be something you set up with x, y coordinates for your own board in an 8 X 8 style, like a 2-dimensional integer array.
It depends somewhat on how you have your pieces implemented. If they are GUI objects themselves, such as buttons or panels, then putting the mouseListener on them will allow the Swing framework to figure out which one has been clicked on. If the pieces all extend a Piece class, then you can put a handler in that as long as the logic it needs to execute (such as moving a piece around) can be made the same for all pieces.
If, on the other hand, you are drawing graphic images on the board in your code, so there is no GUI component for Swing to detect being clicked, then it makes more sense to implement the mouseListener on the board. In this case, your code is going to have to figure out which square was clicked on, and whether it has a piece on it; after that the handling will be much like the previous case.

Categories

Resources