I have this picture and I wish to be able to read each individual picture, load it up into a paint method and add Mouse Listeners to each spot of color but not any of the black background. I do not wish to include ANY of the black background as a "button" and only have the colored spots have mouselisteners of their own so I can distinguish which color spot I have pressed. Does anyone have any ideas? Thanks!
I suppose you could approach it this way:
List<Shape> buttons = ...
for each pixel in the picture, top left to bottom right {
if the pixel is not black {
if the pixel is not already contained in one of the buttons {
iterate over every pixel towards the right until you reach a different color
iterate over every pixel towards the bottom until you reach a different color
// now you have the bounds of your button
// create a new Rectangle and add it to your list.
}
}
}
I've never attempted something like this, nor have I tested the above method, but to me it seems like it should work.
Why can't you just duplicate the picture with JButtons and JPanels and simplify your life?
The mouseListener returns a location, so I would use that location to inspect the image at the corresponding pixel, then branch to do the required action. If the pixel turns out to be black, you simple do nothing.
The image can be inspected via a BufferedImage object and a Raster.
Alternatively, one could inspect the image via BufferedImage and a Raster, and create corresponding Objects for each color square located, printing and handling each one separately.
Related
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.
I want to create a clickable image, my image has some different clickable parts in it, like this one:
I want to draw a custom shape like :
A,B,C,D,E,F
and make sure when user click on of this something happen.
the problem is I don't have any kind of idea to, how create shapes like the shapes in the image make sure it just fix on the image and in different screen size don't see a massed up thing.
Will there be more than many of such images?
If no I suggest you to create mask image for each region where black part of image represents the region and white part excludes rest.
To draw image:
create custom View
in constructor don't forget to use setWillNotDraw to true so you can do custom drawing
override View.onDraw method where you can draw main image and all others with some filters via setColorFilter.
To handle click events:
override onTouchEvent method
get touch position
compare touch position with point color in mask image
To optimise:
create mask image downscaled by some scale factor
during comparison divide touch position by scale factor
This is not ideal, but solution with vectors is non trivial I think
Take it as image and setOnclickListner for that image
What's the best way to associate an image that's in a JPanel to a mouseclick in order to do something? I mean, is there any function in API that can do that? If not, what's the best solution?
By the way, for you who may be wondering why I'm asking for help in this matter is because I'm doing a Sudoku game, and my code already generates randomly all the numbers in the matrix, checks if the solution is correct, the only thing that's not done yet is the interface(the user choosing a square in order to select a number in there).
Thank you.
The "best" way? Use a JLabel
A different way, use a custom JPanel which is responsible for rendering a single image and paint it via the paintComponent method of the panel
A "interesting" way, use a custom JPanel to paint all the images, maintain in some kind of List where each image is associated with a Rectangle that describes the location and size of the image. When the panel is clicked, loop through the Rectangle List and use the contains method of the Rectangle to determine if the mouse event occurred within it, use the index of the Rectangle to loop up the image (or use some kind of Map to maintain a link between the two)
Which you do depends on how much work you want to do and what functionality you intend to implement.
Take a close look at:
How to Use Labels
Performing Custom Painting
How to Write a Mouse Listener
Would a clickable image help you?
ImageView clickableImg = new ImageView(new Image(getClass().getResourceAsStream("graphics/image.png")));
Tooltip image_tooltip = new Tooltip("Maybe add a tooltip to it, as well");
Tooltip.install(clickableImg, image_tooltip);
//Turn the cursor into a hand when hovering over it, too
about.setStyle("-fx-cursor: hand;");
about.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
System.out.println("The image was clicked!");
}
});
Well, you could do something like this to determine if a mouse click is inside a certain region(the image's bounds):
public boolean isIn(int x,int y,int width,int height,int thex,int they){
boolean b=
thex>=x
&&thex<=(x+width)
&&they>=y&&
they<=(y+height);
//b=true;
return b;
}
where:
x is the x-coordinate of the top left corner
y is the y-coordinate of the top left corner
width is the width of the image
height is the height of the image
and x and y are the x and y-coordinates of the mouse click.
After determining which square the mouse's click is inside, you can then make a pop up to get the number to place.
From the above image if I want a portion behind the RED Rectangle I can easily get it,
but the issue I cannot get the portion behind the Yellow Rectangle because it is rotated.
So how can I get a portion of an image from a rotated shape on it?
For example my goal is to get a portion of an Image where the rectangle is located on the image. if someone rotates this rectangle by an x degree [in whatever direction] then it is getting difficult to extract the exact portion of an image after applying rotation.
Any suggestions?
Here a more lengthy description of a possible approach. I do not know the Java2D drawing API very well but if I remember correctly it has the capabilities to do what is required.
First you have to figure out the translation and rotation of the subregion you want compared to an equally size rectangle located straight in the upper left corner in the image. Then invert this transformation.
Make a graphics context which is backed by a bitmap in memory. This one should have the size of the subimage you want. Setup the inverse transformation you calculated earlier on the context and draw your image at position 0,0. As Java2D will take the transformation into account you should now get the sub image you want in the memory bitmap.
Mihir, I think you might be getting distracted by the rotation/AffineTransform aspects of this challenge and it is leading you down the wrong road. Also keep in mind that I don't totally know what you mean by "get" here -- do you want to save out the highlighted region to an image? Do you want to render it as a watermark on another image? etc... I'll just try and answer in the general case to get you down the right track.
What you want is the content from the image defined by the polygon in yellow in your image above; ignoring the fact that it looks like a rotated rectangle.
It is late and I am missing a step in here, but I think this will get you 90% of the way there and clarify the last piece (Graphics2D.setClip) that you need.
Create a java.awt.Polygon that defines the region around the area you want.
Use getBounds() or getBounds2D() to get the width/height of the bounding box required to hold this Polygon when rendered out into a rectangle. (e.g. boundingBox)
Create a new BufferedImage with these width/height values.
Get the Graphics2D from the new BufferedImage (e.g. newG2)
newG2.drawImage(originalImage, boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height)
NOTE This is where my memory is failing me; at some point you need to set the clip on newG2 (newG2.setClip(someShape)) so when the bounding box is rendered into it, you don't get the full bounding box of graphics rendered in, but instead some subset as defined by the yellow outline.
One easy way to do this is to create two Polygon's:
poly1 = a java.awt.Polygon that defines the yellow selection in the ORIGINAL image.
poly2 = a java.awt.Polygon that defines the exact same shape of Polygon, but shifted to a 0,0 origin point.
poly1 is used to get the bounding box to copy out the full bounding box that encompasses the content selected in yellow (and extra content around it)
poly2 is used to set the clip on the target Graphics2D (newG2) so when the bounding box is rendered into it, we clip back out everything outside of that Yellow shape so we just get the content in Yellow. You'll likely want to use an ARGB image type and set the background of the target image as transparent otherwise you'll get a black fill color.
I think this is the right direction for the clips; I was up to my eyeballs in Java2D for years and years but have been out of it for a while and forget if this will give you exactly what you want or not; you might need to tweak it around, but these are all the tools you need.
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.