I need to draw custom shapes. Now when a user clicks on several points on the panel I create a shape using a polygon.
public void mouseClicked(MouseEvent e) {
polygon.addPoint(e.getX(), e.getY());
repaint();
}
But I don't know if this is the best way to draw custom shapes.
It should be possible to edit a drawn shape:
- resize
- change its fill color
- change the stroke color
- copy/paste it
- move a single point of the polygon
- ...
I have seen people creating an own class implementing the Shape class and using a GeneralPath. But again I have no idea if this is a good way.
Now I can create my own shape with a polygon (or with a GeneralPath) but I have no clue how to attach all the edit functions to my own shape (the edit functions I mean the resize, move, etc from above).
I hope somebody could show me a way to do this or maybe write a little bit of code to demonstrate this.
Thanks in advance!!
Have you looked at the Graphics class in java (there is also a Polygon class)? There are draw and fill polygon methods, and each can take in an array of x-coordinates and y-coordinates. By using these arrays, you should be able to change the positions of the points fairly easily. Like you could change all of them equally for a re-size, or copy and paste by just moving all points equally. Changing the color is as easy as filling it with a new color and repainting.
The ImageJ project has a particularly nice implementation of a Polygon tool with adjustable vertices, as seen here and here.
In answer to your question, I would definitely do what you describe as an AWT solution--that way you can track the objects created and be able to allow the user to reload them onto an edit Canvas and more than likely each of the shapes the user creates would be a "layer" not the Layer Swing Container, but an object that would store and track what shapes are drawn and be able to redraw them--the main thing to keep in mind is "Draw order". Basically you can do this by assigning each object or group of object that are your "shapes" to have a Z=[0-100] etc. (100, can be any number) which determine what order each of the object/shapes are drawn in and thus how they over lay each other.
Basically you are going to need a shape class that stores the
you outlined and a storage object/manager that will enumerate the shape class objects/instances that are created. This classes will more or less be contained by a java.awt.Canvas container that will actually handle all the graphics.
Mostly you want to use awt over Swing due to the fact Swing is not Thread safe--that way you do not "paint yourself in the corner" early on in your design. Another reason is this is an implementation that needs to respond and interact in a way that a user is used to. Swing is built over the AWT and adds a great deal of complexity that an application like this doesn't need. Over all you are going to be creating a class Custom component that is exactly what the Canvas object was mean to provide and if Sun would have kept this tact earlier on they would not have gotten into the mess that Swing turned out to be... The Developer community--myself included--were well on the way to creating a lot of what Swing offered in "slickness" and component based design, but what we were building was totally AWT based. When Swing entered the scene, Java as a GUI platform was greatly complicated and started Sun and Java down a slippery path...
Also you have to decide what you ultimately want as far as control over what you are creating here. If you need it fast and do not really care about modifying it in the future, then there are lots of open-source examples that can do this--most for free. If you want to do it yourself, then hopefully what I have talked about above and the rubber band code below will be enough to get you there and have a deeper understanding of Java as a GUI. I personally hope you take it on yourself--this language desperately needs more "core" people that truly understand the Language and its design and not just how to "work" frameworks like Hibernate and Spring among others...
Good luck hope this helps,
WM
As far as "Rubber-band" select code goes, this is mine I have used in the past, just consider it GLP and use it as you need to...
First is the Listener interface:
Here is the class which is a custom AWT component--it should be fine in either Swing/AWT probably even SWT