I need to draw a line in JPanel with mouse, clicking two points in panel. First click would be the start of the line, and second click would be the end of the line.
This is my programm
I have something like this:
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
Graphics g = this.jPanel1.getGraphics();
int x = evt.getX();
int y = evt.getY();
g.drawLine(x, y, x, y);
}
But it only draws pixel.
Line with coordinates
I need something like this, but just drawing it with mouse clicking.
You're drawing a line from (x, y) to (x, y) which is why you're getting just a single pixel. You need to capture the co-ordinates of the first click, and then draw the line on the second click.
private int startX = -1;
private int startY = -1;
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
if (startX == -1 && startY == -1) {
startX = evt.getX();
startY = evt.getY();
} else {
Graphics g = this.jPanel1.getGraphics();
g.drawLine(startX, startY,
evt.getX(), evt.getY());
// reset the start point
startX = -1;
startY = -1;
}
}
From the doc
Draws a line, using the current color, between the points (x1, y1) and (x2, y2) in this graphics context's coordinate system.
In your case x1=x2 and y1=y2, that's why your line is 1 pixel long. After each click you must record the coordinates of your click so that you can use them as the origin of the line for the next click.
Related
I am trying to make a image that was loaded into processing be able to move along with the click of the mouse, and dropped when the mouse is let go.
I am new to Processing and am learning everything I can off the Internet. I am trying to make a image, that was loaded into Processing, be able to move along with the click of the mouse and dropped when the mouse is let go.
I have done this with a shape, but I don't know the how to do it with images. I am completely new to java Processing so I don't really know what I am doing so if you go through each step individually please.
Here is the code. It is a mess:
PImage scene, can;
int can_x, can_y, can_count;
float squareX = 200;
float squareY = 200;
float squareWidth = 50;
float squareHeight = 50;
//keep track of when the mouse is inside the square
boolean mouseInSquare = false;
boolean mouseInCan = false;
void setup() {
size(800,600,P2D);
scene = loadImage("backround.png"); // load image and data into scene data structure
can = loadImage("can.png"); // load image of rain drop into the GPU
textureMode(NORMAL); // Scale texture Top right (0,0) to (1,1)
blendMode(BLEND); // States how to mix a new image with the one behind it
noStroke(); // Do not draw a line around objects
can_x=0+(int)random(800); // Choose drop starting position
can_y=0;
}
//check if the mouse is in the square
void mousePressed() {
if (mouseX > squareX && mouseX < squareX + squareWidth && mouseY > squareY && mouseY < squareY + squareHeight) {
mouseInSquare = true;
}
}
//void mousePressed() {
//if (mouseX > can_x && mouseX < can_x + mouseY > can_y && mouseY < can_y) {
// mouseInCan = true;
//}
//}
//if the mouse is in the square, then move it when the mouse is dragged
void mouseDragged() {
if (mouseInSquare) {
float deltaX = mouseX - pmouseX;
float deltaY = mouseY - pmouseY;
squareX += deltaX;
squareY += deltaY;
}
}
//when we let go of the mouse, stop dragging the square
void mouseReleased() {
mouseInSquare = false;
}
//draw the square
void draw() {
background(scene);
image(can, 0, 0);
rect(squareX, squareY, squareWidth, squareHeight);
pushMatrix(); // Store current location of origin (0,0)
translate(can_x,can_y); // Change origin (0,0) for drawing to (drop_x,drop_y)
beginShape(); // Open graphics pipeline
texture(can); // Tell GPU to use drop to texture the polygon
vertex( -20, -20, 0, 0); // Load vertex data (x,y) and (U,V) texture data into GPU
vertex(20, -20, 1, 0); // Square centred on (0,0) of width 40 and height 40
vertex(20, 20, 1, 1); // Textured with an image of a drop
vertex( -20, 20, 0, 1);
endShape(CLOSE); // Tell GPU you have loaded shape into memory.
popMatrix();
can_y+=1.5; // Make "drop" move down the screen (two pixels at a time)
if(can_y>600) // If y value is entering the bottom of screen
{
can_x=0+(int)random(800); // Restart the drop again in the cloud.
can_y=0;
}
}
I know it's not organized as I was just trying different ways of trying to get it to work.
I am making a game in Java (No Libraries).
It's a 2D top-down game where the player can walk and is faced towards the mouse cursor.
public Player(int x, int y, int health, int tileId) {
super(x, y, health);
tile = new Tile(tileId, false);
mouseInput = new MouseHandler(screen);
}
public void tick() { // Executed by game tick.
// x = playerX and y = playerY
int cursorX = mouseInput.getMousePos()[0];
int cursorY = mouseInput.getMousePos()[1];
float X = cursorX - x;
float Y = cursorY - y;
rotation = Math.atan2(Y, X);
}
It looks good as long the player is at (0,0)
If the player moves and the mouse coordinates become negative it begins to show strange behaviour (Look at video below)
Youtube: https://www.youtube.com/watch?v=M6ZHCrWvt3Y
The rotation of the sprite is done in another class 'Screen.java'
By using:
if (rotation < 360)
rotation++
else
rotation = 0
I verified that the rotation is working correctly.
EDIT:
public BufferedImage rotate(BufferedImage img, double degree) {
AffineTransform tx = new AffineTransform();
tx.rotate(degree, 4, 4);
AffineTransformOp op = new AffineTransformOp(tx,AffineTransformOp.TYPE_BILINEAR);
BufferedImage image = op.filter(img,null);
return image;
}
Okay i fixed it.
The problem was the game scale i am making an 2d game and set the width, height and the scale.
But i didn't divide the mouseX and mouseY by the scale.
public void mouseMoved(MouseEvent e) {
mouseX = e.getX() / game.getScale();
mouseY = e.getY() / game.getScale();
}
I found the problem by accident when messing with the gamescale.
I am writing a 2D program. On my paintComponent I created an arc.
public class Board extends Panel{
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D graphics2d = (Graphics2D)g;
int x = MouseInfo.getPointerInfo().getLocation().x;//set mouses current position
int y = MouseInfo.getPointerInfo().getLocation().y;
graphics2d.setStroke(wideStroke);
graphics2d.draw(new Arc2D.Double(200, 200, 100, 100, ?, 180, Arc2D.OPEN));
}
}
In my main I am using a Thread to update the graph. The position of the ? is the starting angle. Every time I change this the arc will move in a circle like half a car wheel. Is it possible to get the arc movement to follow the mouse? e.g. ? = 270
How will I do this? (Sorry for my bad paint skills!)
So based on the information from Java 2d rotation in direction mouse point
We need two things. We need the anchor point (which would be the centre point of the arc) and the target point, which would be the mouse point.
Using a MouseMotionListener, its possible to monitor the mouse movements within the component
// Reference to the last known position of the mouse...
private Point mousePoint;
//....
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
});
Next we need to calculate the angle between these two points...
if (mousePoint != null) {
// This represents the anchor point, in this case,
// the centre of the component...
int x = width / 2;
int y = height / 2;
// This is the difference between the anchor point
// and the mouse. Its important that this is done
// within the local coordinate space of the component,
// this means either the MouseMotionListener needs to
// be registered to the component itself (preferably)
// or the mouse coordinates need to be converted into
// local coordinate space
int deltaX = mousePoint.x - x;
int deltaY = mousePoint.y - y;
// Calculate the angle...
// This is our "0" or start angle..
rotation = -Math.atan2(deltaX, deltaY);
rotation = Math.toDegrees(rotation) + 180;
}
From here, you would need to subtract 90 degrees, which would give your arcs start angle and then use an extent of 180 degrees.
I'm programming a java applet.
In this applet I need to draw on an image some markers (as a red circle) and some lines.
I have succesfully implemented the markes, as an extension of JComponent, and I also put on this some mouse listeners.
I'm having big problems with the line object. I created another object extending JComponent, and, aside that I'm having some problems with the coordinates system, the setDimension creates troubles. For example it intercepts all the marker's click.
It isn't a method to make an object "dimension" more tight to the line, because I can't draw only verical or horizontal lines...
Thank to all of you.
EDIT
public class Path extends JComponent {
...
// stroke of the line
private Stroke spessore = new BasicStroke(SPESSORE);
// coordinates
private double x, y, x_2, y_2;
// ZoomManager is an object. In this project I can zoom in and zoom out the
// image, so this object convert coordinates get on the superior JPanel in
// coordinates on the image real-sized.
public Path(double x, double y, ZoomManager zoom) {//, double x_2, double y_2, ZoomManager zoom) {
super();
// this function return the coordinates on the real-sized image
Point a = DrawableObjects.getScaledCoordinates(x, y, zoom);
this.x = a.x;
this.y = a.y;
this.x_2 = a.x;
this.y_2 = a.y;
updateBoundsAndSize(zoom);
// this was only for test...
this.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("CLICK!");
}
...
});
}
// this function is called during the mouse dragging for drow the line.
// it gets the coordinates, convert them, save them and update the bounds and
// size of the object
public void setArrivePoint(Point a, ZoomManager zoom) {
Point p = DrawableObjects.getScaledCoordinates(a.x, a.y, zoom);
this.x_2 = p.x;
this.y_2 = p.y;
updateBoundsAndSize(zoom);
}
// update the bounds of the object, the origin point of the rectangle is the
// top-left coordinate build with the original coordinates. The width and height of the rectangle are obtained by subtraction.
private void updateBoundsAndSize(ZoomManager zoom) {
Point p = DrawableObjects.getPanelCoordinates(x, y, zoom);
Point a = DrawableObjects.getPanelCoordinates(x_2, y_2, zoom);
int min_x = (int)Math.min(p.x, a.x) - SPESSORE;
int min_y = (int)Math.min(p.y, a.y) - SPESSORE;
if (min_x < 0)
min_x =0;
if (min_y < 0)
min_y = 0;
int w = (int) (Math.max(a.x, p.x) - min_x) + SPESSORE;
int h = (int) (Math.max(a.y, p.y) - min_y) + SPESSORE;
setBounds(new Rectangle(min_x, min_y, w, h));
repaint();
}
// drawing function
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D antiAlias = (Graphics2D) g;
antiAlias.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// get ZoomManager from the superior object
ZoomManager zoom = ((JPanelImmagine)this.getParent()).zoom;
antiAlias.setColor(DEFAULT_COLOR);
antiAlias.setStroke(spessore);
Point[] coordinates = updateCoordinates(zoom);
Line2D line = new Line2D.Double(coordinates[0], coordinates[1]);
antiAlias.draw(line);
}
// translate coordinates from superior jpanel to this object
private Point[] updateCoordinates(ZoomManager zoom) {
Point[] output = new Point[2];
Point p = DrawableObjects.getScaledCoordinates(x, y, zoom);
Point a = DrawableObjects.getScaledCoordinates(x_2, y_2, zoom);
double o_x = this.getBounds().getCenterX();
double o_y = this.getBounds().getCenterY();
Point origin = new Point ((int)o_x, (int)o_y);
output[0] = calculateCoordinates(p, origin);
output[1] = calculateCoordinates(a, origin);
return output;
}
private Point calculateCoordinates(Point p, Point origin) {
double new_x = p.x - origin.x;
double new_y = p.y - origin.y;
return new Point((int)new_x, (int)new_y);
}
Resolved using this method!
I had to change totally approach to the problem.
I have another question, this is also extra credit and not homework. This time I need to create a border with out using java2d. The instructions are...
Write a method called drawRectangleBorder having six parameters which does not use the graphics package. It draws a rectangular border starting at the x and y coordinates given as the first two parameters, having a width and height given by the third and fourth parameters, the width of the border given by the fifth parameter in the color given by the sixth parameter. The parameter list is: x, y, width, height, borderWidth, color
I used a previous method I made to create a border around the outside of a picture but the best I can make it do now is a couple scattered boxes. The most recent version will not show anything
public void drawRectangleBorder(
int x, int y, int width, int height, int border, Color newColor) {
int startX = 0;
int startY = 0;
// top and bottom
for (startX = x; x < width; x++) {
for (startY = y; y < border; y++) {
// top pixel
this.getPixel(startX, startY).setColor(newColor);
// bottom pixel
this.getPixel(startX + width, startY + height).setColor(newColor);
} // for-y
} // for-x
// left and right
for (startX = x; x < border; x++) {
for (startY = y; y < height; y++) {
// left pixel
this.getPixel(startX, startY).setColor(newColor);
// right pixel
this.getPixel(startX + width, StartY + height).setColor(newColor);
} // for-y
} // for-x
return;
} // end drawRectangleBorder
Again I thank you for any input.
You can alter the pixels in a java.awt.BufferedImage as shown here.
I might be too sleepy but I think your forgetting to set the pixel back into this (whatever this is ^^)
I'm guessing this.getPixel sends your back a copy so you might want to do something like
Pixel p = this.getPixel( startX, startY );
p.setColor(newColor);
this.setPixel(startX, startY, p);