JAVA Saving Multiple X and Y Mouse Locations - java

Comparing Two Specific Pixels
I am trying to compare two specific pixel values by storing them both and eventually comparing the difference between them.
The code below shows what I currently have, (image_Display being my component) and then when the user clicks a location on the image the pixel location is stored. However, how do I do this if I want to collect numerous pixel values?
image_Display.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
x=e.getX();
y=e.getY();
System.out.println(x + "," + y);
}
Desired output:
Saving the location of 2 separate pixels. I'm sorry this is really obvious - I am new to event's.
How am I able to save the location of a location rather than overwriting it each time?
Thank you

If you need only previous coordinates then why don't keep them like this:
int previusX,previousY;
image_Display.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
previousX=x;
previousY=y;
x=e.getX();
y=e.getY();
System.out.println(x + "," + y+" ["+previousX+","+previousY+"]");
}
}
If you need more - use Collections and store few of MouseEvnets (as much as you need).

Related

How to properly "layer" images (and changing the source) without inheriting from Swing

I'm finishing my homework in OOP Java. The assignment is to load images on a JFrame, be able to move them around (top layer should be prioritized, it is currently not) and click them to "flip them" (change the source of the image essentially). I'm currently having trouble finding a solution on how to properly "layer" images that are visible on the screen and to prioritize the images on the top first (currently the bottom ones are being prioritized).
I also have issues finding a good way to change the source of the images, as our teacher has prohibited extending the Picture class with Swing.
My first attempt at solving this was saving the information of every individual "Picture" object in an ArrayList. This works to save the position of the images but does not solve my issue with the layering. I also wanted to use JLayeredPane but as I found out, it was harder than I thought as I have yet to find a viable solution this way (I might be missing some obvious facts about how it works).
I'm thinking what probably needs to happen is that I save the "position" of each image in some type of Array, then using this array to print out the images via paintComponent # ImagePanel. This is currently what I am doing but it does not act as I wish it to. I think my way of loading in the images in the "Picture" class might have something to do with it. I don't have a lot of experience in Java so all of this is new to me.
I don't want to print out all of my codes as I have 4 classes, so I'm going to print out what I feel are the essential methods in each class. If there's something missing that you guys need in order to guide me in the right direction I'll provide that aswell.
draw # Picture
public void draw(Graphics g, int i) {
try {
BufferedImage img = ImageIO.read(new File("images/icon_"+ i +".gif"));
g.drawImage(img, x, y, null);
} catch(IOException ie) {
System.out.println("Could not find images");
}
}
mousePressed & mouseDragged # MouseHandler
public void mousePressed (MouseEvent e) {
Point point = e.getPoint();
chosen = imagepanel.locateImage(point);
}
public void mouseDragged (MouseEvent e) {
int x = e.getX();
int y = e.getY();
if (chosen != null) {
imagepanel.moveImage(chosen, x, y);
}
}
loadImages & paintComponent # ImagePanel
private final static int IMAGES = 7;
private ArrayList <Picture> imageCollection = new ArrayList<>();
private Picture im;
Random rand = new Random();
public void loadImages() {
for(int i=0; i<IMAGES; i++) {
int x = rand.nextInt(400) + 40;
int y = rand.nextInt(400) + 60;
im = new Picture(x,y);
imageCollection.add(im);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int i = 0;
for (Picture im : imageCollection) {
i++;
im.draw(g, i);
}
}
I expect the images to stack on top of eachother whenever "flipped" (clicked) or moved (dragged). They do not currently do this as they just maintain their "depth" position. I've tried implementing an Image[] without success.
I also have a flip method where I tried using setIcon (I was using ImageIcon instead of Image previously) but this did not really work for some reason.
I also would love for any feedback on the code so far and any improvements that could be made as I always want to improve.
EDIT: I manage to solve my problems, however I'm sure there's a better way to do this.
public void placeFirst(Picture im) {
int pos = imageCollection.indexOf(im);
imageCollection.remove(pos);
imageCollection.add(0, im);
}
public void flipImage(Picture im) {
im.flip();
placeFirst(im);
repaint();
}
public void moveImage(Picture im, Point point) {
im.move(point.x-(im.getWidth(im)/2), point.y-(im.getHeight(im)/2));
placeFirst(im);
repaint();
}
public Picture locateImage(Point point) {
for (int i=0; i<imageCollection.size(); i++) {
Picture im = imageCollection.get(i);
if (im.fits(point)) {
return im;
}
}
return null;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// There probably exists a better and visually nicer way of doing this
for (int i=imageCollection.size()-1; i>=0; i--) {
Picture im = imageCollection.get(i);
im.draw(g);
}
}
chosen = imagepanel.locateImage(point);
Well, we don't know how the locateImage(...) method works, but I would guess you just iterate through the array until you find a match.
So you will always find the same match.
So if you want an image to stack on top you have two issues:
you need to modify the search order so that when you click on an image you move it to position 0 in the ArrayList so it is always found first
but know when you paint images you need to paint images from the end of the ArrayList to the beginning, so the first image in the ArrayList gets painted last.

2D arraylist to keep a point

i made a program that whenever i click my mouse, it draws a circle in the point that i clicked,
now i want it to check if there is already a circle in the point that i am clicking , and if there is then i want to delete that circle.
i thought to do it with a 2D arralist that will keep all the points already taken, can anyone show me how do i do it?
this is my code so far:
public class delta extends Applet implements MouseListener {
private Graphics globalg;
public void init(){
this.addMouseListener(this);
}
public void paint(Graphics g){
this.setSize(new Dimension (1000, 1000));
globalg = g.create();
}
public void draw(int x, int y , int width , int height){
globalg.setColor(getColor());
Ellipse2D circle = new Ellipse2D.Double((double) x , (double) y ,(double) width , (double) height);
Graphics2D g2 = (Graphics2D) globalg;
g2.fill(circle);
}
public Color getColor(){
int r = (int) (Math.random() * 256);
int g = (int) (Math.random() * 256);
int b = (int) (Math.random() * 256);
return new Color(r , g ,b);
}
#Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
draw(x , y , 20 , 20);
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
I won't be telling you exactly what to do, but I'll get you in the right direction.
Step one - Your Data Structure
Now, I can see why you wanted to use a nested ArrayList for this, but conceptually this isn't very nice. You can represent a matrix of values without a complex data structure by enclosing the relevant values inside an Object. Now, you could make your own object or you can use the Java Point class. For the purposes of this, we'll make your own object so you can easily add your own values (colour, size, etc).
public class MyCircle {
}
And in there, you can store your x and y positions. These can then be stored into a List, so your MyCircle objects will be accessed via something like:
private List<MyCircle> circles;
Step Two - Handling Mouse Clicks
You've already implemented the MouseListener interface, so we're in a good place to get building on that. Now, the way I see it, there are two possibilities that you need to account for when handling a mouse click.
No Circle exists and you need to draw one.
A Circle exists and you need to delete it.
No Circle Exists
If no circle exists, then you draw it. You seem to have got this bit handled so there's no sense explaining it.
A Circle Exists
This is where you've stopped. So, first things first, you'll need to traverse your data structure, which we've named circles..
for(MyCircle circle : circles) {
}
Now, I'll assume you've got something like x and y in here, a long with the relevant accessors and mutators. You then can check the co-ordinates..
if(circle.getX() == x && circle.getY() == y) {
// A circle was put at this point..
}
NOTE: This will make it quite hard to delete a circle. What you really want is to be able to check if the use has clicked inside a circle! How do you do this? Well, that's about comparing the values. You want to make sure that the user clicked at an x value that is larger than the x value of the circle, but smaller than x + width of the circle. Likewise, you want to make sure the user also clicked at a y value that is larger than the y value of the circle, but smaller than y + width of the circle.
if(x > circle.getX() && x < (circle.getX() + circle.getWidth())) {
// This was a click inside the circle on the X axis. Your turn to check the y!
}

Exact Positioning When using Drag and Drop in GUI

I'm trying to implement a drag and drop functionality for a GUI I'm creating using WindowBuilder/ SWT Designer. At present, in order to determine where exactly on the canvas the drop takes place, I use
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
int x = event.x - shell.getBounds().x - canvas.getBounds().x;
int y = event.y - shell.getBounds().y - canvas.getBounds().y;
e.gc.drawString(d, x, y);
}
});
But this is not an exact positioning at the mouse drop, instead it is very much further towards the right. How can I fix this? Thanks.
All you need is the very helpful function Control#toControl(int, int):
Returns a point which is the result of converting the argument, which is specified in display relative coordinates, to coordinates relative to the receiver.
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
Point point = canvas.toControl(event.x, event.y);
e.gc.drawString(d, point.x, point.y);
}
});
That'll do it.

How can I read coordinates from a graph in Java?

My aim is to read coordinate point values from a graph in a Java program. I don't know if it even needs to be a graph. The user clicks on various parts of a plane, and I need to know which places were clicked pixel-wise so that I can find the distances between those points. Are there any simple Java libraries for accomplishing this task?
Just add a mouse listener to a JPanel.
In the mouse listener, you can do something like the following:
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse clicked at (" + e.getX() +"," +
+ e.getY + ")");
}

Has anyone done crosshairs that follow the mouse in JFreeChart?

We are using JFreeChart to make XY plots and we have a feature request to do a crosshair that moves along with the mouse and highlights the data point that most closely maps to the x-value of the mouse. You can see a similar example at Google Finance - http://www.google.com/finance?q=INDEXDJX:.DJI,INDEXSP:.INX,INDEXNASDAQ:.IXIC.
Those Google charts only highlight the current value (we want to do that and also show crosshairs), but they show the live mouse interaction we are looking for.
Anyone have any elegant suggestions?
Thanks.
I got this working using a mouse listener and the CrosshairOverlay class. After I get back from holiday travel, I will post my code. It ended up being not too difficult.
Sorry, I forgot about this!
First, you want to calculate the x, y values for where you want your crosshair. For me, I wanted it to move along the points of our line, so I calculated the closest x value and used that data pair for x, y.
Then I call this method:
protected void setCrosshairLocation(double x, Double y) {
Crosshair domainCrosshair;
List domainCrosshairs = crosshairOverlay.getDomainCrosshairs();
if (domainCrosshairs.isEmpty()) {
domainCrosshair = new Crosshair();
domainCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0);
crosshairOverlay.addDomainCrosshair(domainCrosshair);
}
else {
// We only have one at a time
domainCrosshair = (Crosshair) domainCrosshairs.get(0);
}
domainCrosshair.setValue(x);
if (y != null) {
Crosshair rangeCrosshair;
List rangeCrosshairs = crosshairOverlay.getRangeCrosshairs();
if (rangeCrosshairs.isEmpty()) {
rangeCrosshair = new Crosshair();
rangeCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0);
crosshairOverlay.addRangeCrosshair(rangeCrosshair);
}
else {
// We only have one at a time
rangeCrosshair = (Crosshair) rangeCrosshairs.get(0);
}
rangeCrosshair.setValue(y);
}
}
Note that crosshairOverlay is an instance of CrosshairOverlay.
JFreeChart can't render a sub-section of a chart, so you'll want to do something that doesn't require repainting the chart. You could write your chart to a BufferedImage and store that in memory, then have a custom component which uses the buffered chart as the background image, and draws crosshairs and other popup windows over it.
There are methods in JFreeChart to get the data point for a given coordinate on a rendered chart. Don't recall what these are off the top of my head. Depending on your needs, you might consider rendering your own chart data, it's not as hard as you'd think.
The first thing that comes to my mind would be to write a custom Cursor and set it on your chart. It can have a reference to the chart and highlight the x value that's consistent with the Cursor's x/y location.
This worked for me. I set the
chartPanel.addChartMouseListener(new ChartMouseListener() {
public void chartMouseMoved(ChartMouseEvent event)
{
try
{
double[] values = getCrossHairValue(event);
plot.clearRangeMarkers();
plot.clearDomainMarkers();
Marker yMarker = new ValueMarker(values[1]);
yMarker.setPaint(Color.darkGray);
plot.addRangeMarker(yMarker);
Marker xMarker = new ValueMarker(values[0]);
xMarker.setPaint(Color.darkGray);
plot.addDomainMarker(xMarker);
chartPanel.repaint();
} catch (Exception e)
{
}
}
}

Categories