Using JPanel to draw straight lines and get point coordinates - java

I am at a total loss right now. I haven't worked much with building GUIs in Java, I've been reading all about swing and JPanel, and I think what I am trying to do is possible, I just haven't figured out how.
I'm trying to build a GUI in which you can draw straight lines within a certain drawing area, I would like to be able to get the start/endpoint coordinates in order to perform some math with those points. Any help would be greatly appreciated!

I will leave the code to you so here is the algorithm:
1. Create a JFrame and add a JPanel to it.
2. Add a mouse listener for the JPanel
3. Every time the mouse is pressed, get the x and y of the click. (starting points)
4. When the mouse is dragged , record x and y continuously.
5. When mouse is released, record the x and y. (ending points)
6. You could either use the drawLine() method of Graphics class or use draw() of Graphics2D in this case you will need a Line2D.Double -- the arguments remain the same - start x, start y, end x and end y
here is an image to explain a lil bit better:

Start with Performing Custom Painting and 2D Graphics.
Basically, you going to need a mouse listener to monitor the user interaction with your panel, check out How to write mouse listeners for more infor still.
Depending on your needs, if you need to maintain all the click points of the user, you would need to store them in something like a List, or if you just need to know the start and end points, the you just need a couple of Point objects.
You would be able to use these to paint onto your surface and performing your required calculations.
Remember, in this context, the points are contextual to the container they were generated on. That is 0x0 will be the top left of the container
Updated
You could also take advantage of the Shape API, using a Line2D to represent the two points. This would make it easier to distinguish between distinct lines/points

This is harder than just "draw straight lines with (x1,y1) and (x2, y2)" approach.
You need a Line(your custom) object that is dynamically created and placed on the JPanel which is listening for MouseEvents The canvas area being the JPanel itself. You also need to separate the MODEL from the VIEW so that your custom canvas JPanel will draw itself properly with an override for paintComponent()
The question is slightly vague, so I can't provide any code.

you need to add the mouse listener on JPanel.
then:
public void mouseClicked(MouseEvent me){
if(click==1){
int x1=me.getX();
int y1=me.getY();
click=click+1;
}
else{
int x2=me.getX();
int y2=me.getY();
click=1;
}
}
drawLine(x1,y1,x2,y2)
To draw line with mouse move you can also add mouse motion listener.

Related

Draw shapes in Java based off if/else statements and action listener

I'm trying to figure out if there's any way to draw images (drawRect(), drawOval(), etc.) based on if/else statements or by using an ActionListener.
I don't want to post the complete problem because this is for an assignment, but for my own scenario:
If I have a button on a JPanel named "draw rectangle" and I have the x, y, width, and height from user input, is there any way I can attach an actionListener to "draw rectangle" that could somehow draw the rectangle using those values (passed by reference?).
I know I can use paintComponent, but I can't put that into the ActionListener and it seems to do things of its own accord and not based on a specific user's actions.
I don't really have any code for this because I can't figure out how to do it at all.
If I have a button on a
JPanel named "draw rectangle" and I have the
x, y, width, and height from user input, is there any way I can attach
an actionListener to "draw rectangle" that could somehow draw the
rectangle using those values (passed by reference?).
The short answer is yes.
Generally, you'll need to save the rectangle instructions in a model, and have the JPanel redraw the model when any of the shape buttons are pressed.
Let's take your rectangle example. What do you need to know to draw a rectangle on a JPanel? You need a starting point (upper left) and an ending point (lower right). You can use a java.awt.Point to hold the starting and ending point. You can set the thickness of the line, in pixels. You can set the color of the rectangle, using a JColorChooser. You can also set the rectangle to be an outline or filled with the chosen color.
That description will be similar for a line and a triangle. A circle is a little different, with a center point and a radius. As you can see, we already have a lot of information to keep track of just with these simple geometric shapes.
Then there's the issue of the drawing surface itself. It's possible to have a drawing surface larger than your computer screen can show. You can put the drawing surface inside of a JScrollPane.
All of these things must be determined so you can build the model of your application. You do this before you build the view using Swing components and the controller using action listeners.

How to get circles to change colour with mouse over

I want to set up a grid of circles (non-overlapping) so that, when the mouse pointer is over one of them, that circle changes colour. I have experimented and so far have two options:
Use a container e.g. JPanel. Use MouseMotionListener.mouseMoved(MouseEvent e) to get the x and y coordinates of the mouse pointer at all times. Then, if the coordinates lie within one of the circles, use repaint() to repaint the whole container.
Set each circle as a container. Use MouseListener.mouseEntered(MouseEvent e) to detect when the mouse pointer moves over a circle. Then redraw that container only.
Is #2 the best approach? If so, how can I set up a circular container? Is there a better approach than either of the above?
If so, how can I set up a circular container?
Check out Playing With Shapes.
You can use the ShapeComponent to create a circles that act just like components. So you can build your grid just like you would with any other Swing component.

How to get mouse position and buffer?

How do I get the mouse position. I have tried:
int mouseX = MouseInfo.getPointerInfo().getLocation().x;
int mouseY = MouseInfo.getPointerInfo().getLocation().y;
But that does it for the whole screen. Anyway to do it relative to the JPanel/JFrame
If I'm only using Graphics JFrame and JPanel that is being repainted every millisecond, should I have buffers? Or will it be fine?
How do I add a mouseAcionEvent only to the frame so it gets X() and Y() of mouse but only in frame?
Use a MouseListener instead of MouseInfo. MouseListener will trigger events which are contextual to the component which raised them, which means you won't need to translate the events into the component space as the event will already be converted to within the component context.
See How to write a mouse listener for more details
How should I update my game rePaint() every millisecond or another way?
Use a javax.swing.Timer...
See How to use Swing Timers for more details...
Should I use buffers?
That will depend. Swing components are already double buffered, but if you use a more complex timing mechanism (AKA game loop), you might find it useful, even to roll your own.
I, personally, would start simple
How can I improve the way I thought out my code in the first place? Is it right having 10 loops or only all in 1 to reduce lag ect.
There are probably lots of things, but start with broader idea...
Breakdown entities to their own responsibilities, for example, the player should know where it is and how it should be painted. It could even know how it's suppose to move based on the current state of the game. This way you could create any number of entities, all with there own set of rules which are isolated and easily updated.
Devise a controller mechanism which is responsible for taking in keyboard and mouse events and simply updating the current state of the game model. That is, rather than going "the user pressed the 'left' key, move player to the left", it would simply raise a flag in the game model that the "left" state has been triggered (or untriggered) and the engine would, on the next update loop, ensure that each entity knew about the change
Don't use magic or hard coded numbers, instead provide some kind of ability to scale the scene. For example, you could decide what is shown on the screen based on the size of the window...

How to make vector line selectable?

I'm making a project for college, where I have to make my own primitive vector editor, and I have two questions:
Is it right to make vector line object by saving it's start point coordinates, end point coordinates, color and width of points, which it will consist of? Point is also my class, which is drawn on JPanel.
If it is right, how can I make this line selectable? The only thing I can think of is to check mouse coordinates to be inside of line width.
I also have a restriction not to use any standard functions for drawing lines, splines, etc.
Yes that's right. Or you could represent it in polar coordinates
the best thing to do is actually turn your line into an Area, which implements Shape and thus contains, which is the method you want. Area is a great abstraction because it can represent any shape but everything gets manipulated in the same way.
You can use Line2D Shape. To check selection you can gt stroked Shape from BasicStroke and check whether the stroked Shape contains clicked point.
To Point 1: You also need to save the direction of the vector.
To Point 2: There are some frameworks like GEF which do the job for you. Here you have to change your model. You need two classes: Point and Connection
You can use a class Vector if you have one with start and end Point for do it if you want.
You can have a method like that:
private static Shape generateVector(Point start, Point end)
In this method you can use one object of ´Area´ for build the vector, with Line2D. Tree lines if you want an arrow.
Or you can use a GeneralPath for build it.
For select a particular vector with the mouse, you can get the coordinates, with getX() and getY() on the MouseEvent and ask in the shape object with method contains and repaint with other color.
Good luck!

Java swing editable line drawing

I am writing a zigzag drawer as my school assignment. Basically what is expected is to be able to draw zigzags on a canvas, to be able to move vertices of the zigzags and to be able to move the entire zigzag. Also we can change the color and thickness of the zigzags.
I could manage to draw zigzags, a left click starts and subsequent left clicks continues the zigzag, and a right click finishes it. In this way i can draw several zigzags.
What i can not do is how i can make the vertices of the zigzags movable? I am keeping the point coordinates in an arraylist of type mypoint which consists of x, y and depth values. I am drawing all the painting on a canvas which is an extended class of JPanel. in the paintcomponent method i call drawline methode for every vertex in the list. As these are just paintings i cannot figure out how i will detect that the user is clicking on the vertex. Can i have little button like controllers when clicked will do the job i want. i tried to use labels and standard buttons, but neither can i position them appropriately nor are they too large to be just handlers for vertices.
Do you have suggestions on these?
You could have two modes of operations, which must be chosen by the user by selecting a radio button, for example: one for drawing zigzags, and the other one for selecting vertices.
While the chosen mode is "zigzag", the mouse clicks allow drawing zigzags as you have already implemented. When the chosen mode is "vertex selection", then a mouse click could find a vertex whose distance from the clicked point is less than 3 pixels, and the dragging of the mouse could move the vertex from its original position, following the mouse pointer.
You could inform the user about the selected vertex by displaying a small squere around the vertex.

Categories

Resources