How can I add mouseListener to a MapMarker (MepMarkerDot or MapMarkerCircle) that makes it like button?
I tried this soloution but it makes whole map clickable (mouse Event works on all the map).
You're on the right path to start with TrashGod's MouseListener solution, but you need to add a little more code, the key part being, that you need to get the Point location of where the user pressed, something the MouseEvent#getPoint() method will tell you, and then based on that information, and the bounds of the "active" area of the component decide whether to respond. Something like:
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint(); // this is where the user pressed
if (isPointValid(p)) {
// do something
}
System.out.println(map.getPosition(e.getPoint()));
}
private boolean isPointValid(Point p) {
// here you have code to decide if the point was pressed in the area of interest.
}
Note that if your code uses Shape derived objects, such as Ellipse2D or Rectangle2D, you can use their contains(Point p) method to easily tell you if the point press was within the Shape or not. Or if there are several locations that you want to check, you may have a collection of Shapes, iterate through them within your mousePressed or (if you have it) isPointValid method, and check containment within the for loop.
I found this nice example:
https://www.programcreek.com/java-api-examples/index.php?source_dir=netention-old1-master/swing/automenta/netention/swing/map/Map2DPanel.java
It has an interface MarkerClickable and its own LabeledMarker which implements MapMarker and MarkerClickable:
public boolean onClick(final Coordinate p, final MouseEvent e) {
for (final MapMarker x : getMap().getMapMarkerList()) {
if (x instanceof MarkerClickable) {
final MarkerClickable mc = (MarkerClickable)x;
final Rectangle a = mc.getClickableArea();
if (a == null)
continue;
if (a.contains(e.getPoint())) {
mc.onClicked(e.getPoint(), e.getButton());
return false;
}
}
}
return true;
}
Related
I don't know if I am asking the right question. I am creating a paint-like application in which the user selects a shape and then draws it on the canvas with mouse drag. I have created a superclass GeometricObject and the sub-classes Line, Rectangle and Eclipse extend it. I declared a variable "go" of type GeometricObject. Based on which button is pressed, a new object of a different sub-class is created and stored in go. For example, if Eclipse button is pressed, a new object of type Eclipse is created and so on. In the dragHandler, if go variable stores a reference to object of type Eclipse, then go is casted to type eclipse and draw method of eclipse is called. But in my case this logic does not work.
GeometricObject go;
public void dragHandler(MouseEvent mouseEvent){
/// transgc is graphicsContext2D
transgc.clearRect(0,0,screenWidth,screenHeight);
ex=mouseEvent.getX();
ey=mouseEvent.getY();
GeometricObject go=new Rectangle(sx,sy,ex,ey,colorPicker.getValue());
if(go instanceof Lines)
((Lines)go).draw(transgc);
else if(go instanceof Eclipse)
((Eclipse)go).draw(transgc);
else if(go instanceof Rectangle)
((Rectangle)go).draw(transgc);
}
public void eclipseHandler(ActionEvent e){
go=new Eclipse(sx,sy,ex,ey,colorPicker.getValue());
}
public void rectangleHandler(ActionEvent e){
go=new Rectangle(sx,sy,ex,ey,colorPicker.getValue());
}
public void linesHandler(ActionEvent e){
go=new Lines(sx,sy,ex,ey,colorPicker.getValue());
}
Expected output - different shape is drawn when different button is pressed and then mouse is dragged
Actual output - nothing is getting drawn while the mouse is dragged
GeometricObject go=new Rectangle(sx,sy,ex,ey,colorPicker.getValue());
if(go instanceof Lines)
((Lines)go).draw(transgc);
else if(go instanceof Eclipse)
((Eclipse)go).draw(transgc);
else if(go instanceof Rectangle)
((Rectangle)go).draw(transgc);
Here you are always creating a Rectangle object 'go'. It should be omitted.
I'm trying to add a ToolTip to a custom MapMarker on JMapViewer. But repeaded searches on are not helping me solve this.
The custom MapMarker is:
public class MapMarkerUnit extends MapObjectImpl implements MapMarker
and the Paint Method overide is
public void paint(Graphics g, Point position, int radio) {
String filename = "marker.png";
//System.out.print(filename);
BufferedImage x = null;
try {
x = ImageIO.read(getClass().getResource(filename));
} catch (IOException ex) {
Logger.getLogger(MapMarkerUnit.class.getName()).log(Level.SEVERE, null, ex);
}
g.drawImage(x, position.x-16, position.y-37,null);
//if(getLayer()==null||getLayer().isVisibleTexts()) paintText(g, new Point(position.x+20,position.y));
}
Thanks for any help your able to offer.
Override the getToolTipText() method of JMapViewer. In your implementation, use getPosition() to convert the MouseEvent coordinates into geodetic coordinates. The example below simply displays the unformatted coordinates; you'll want to find the nearest MapMarker and return the appropriate text.
JMapViewer map = new JMapViewer() {
#Override
public String getToolTipText(MouseEvent e) {
Coordinate c = getPosition(e.getX(), e.getY());
return c.getLat() + " " + c.getLon();
}
};
map.setToolTipText(""); // initialize
Addendum: Is there a way of adding a tooltip directly to an image?
No; JMapViewer is the enclosing JComponent that handles tool tips.
I have about 50 markers on the map…that's a lot of iterations.
You definitely can't load images in your MapMarker implementation; use a SWingWorker to load images in the background, for example.
As a concrete iteration example, JFreeChart easily handles tool tips for scores of entities in this way. Here's the enclosing panel's getToolTipText() implementation, and here's the loop that invokes Shape#contains(). A simplified example that illustrates the approach is seen here.
I'm working on a project for a simple game where you can go to different rooms by using buttons (north, east, west, south). Within the makeFrame() method of my gui I'm creating the panel, buttons etc. I then set the default room to "hall" for example and the actionlistener calls the method goRoom and passing the direction and currentRoom to that method. The goRoom method change the currentRoom to another room depending on the currentRoom. I included print statements to see if it works and so far it works fine.
Everytime the game starts the default room is the hall.
So when you click a button to go for example "North", the northButton is called in which then we call the goRoom method passing the direction (north) and the default room "hall" (as the game just starts and uses the default room).
Then the room changes from hall to state room (within the method goRoom). When I try to press another button the currentRoom reset to the default value (hall).
I think the action listener get the value from the makeFrame() method instead of the updated value from the goRoom method. The code is below:
public class StoreGUI extends JFrame
{
public String currentRoom;
public StoreGUI()
{
makeFrame();
}
private void makeFrame()
{
currentRoom = "hall";
....
northButton = new JButton("Go North");
northButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
direction = "north";
goRoom(direction, currentRoom); }
});
toolbar.add(northButton);
westButton ....
southButton ....
eastButton ....
picture.setIcon(new ImageIcon("image/hall.png"));
frame.getContentPane().add(picture);
frame.pack();
frame.setVisible(true);
}
private void goRoom(String direction, String currentRoom)
{
// get current room and check which direction button the user has pressed
if (direction == "north"){
if(currentRoom == "hall"){
// Inserts the image icon and change currentRoom
imgageTitle = "image/stateRoom.png";
currentRoom = "stateRoom";
}
....
}
What the problem could be? How can I fix that? I'm pretty sure it's something really simple but I'm stack.
String comparison in Java is done with String#equals not ==. This will compare the actual text of the String and not its memory reference...
For example, instead of
if (direction == "north") {....
Use
if ("north".equals(direction)) {...
If you don't care about the case, you could use...
if ("north".equalsIgnoreCase(direction)) {...
Having said all that, you could actually use a enum to represent the directions, which restricts what values you can actually pass to the goRoom.
You could also use a Action to define each button's actions, which also means you could use them Key Bindings or menus without having to duplicate any code...but that's just me...
Updated
You're also shadowing your values...
private void goRoom(String direction, String currentRoom)
{
//...
currentRoom = "stateRoom";
Changing the value of currentRoom will have no effect beyond the scope of the method. This is because you're not actually changing the content of the String object, but changing it's memory reference.
Instead, either change the name of the parameter or, simply don't bother passing, as you already have access to the instance field of the same name...
private void goRoom(String direction)
{
//...
currentRoom = "stateRoom";
Hi I want to build on java mouse click logger. I need to print the coordinates of mouse clicks in a file. Can you tell me how I can make this. Which APIs to use some examples or links. I need to get all the mouse clicks not only in one window.
you could implement the MouseListener interface and overwrite the mouseClicked function:
public class MyMouseListener implements MouseListener {
// [...]
#Override
public void mouseClicked(MouseEvent e) {
System.out.println(e.getLocationOnScreen());
}
// [...]
}
Adapt that example to your needs. THe getLocationOnScreen Method returns a "Point" object which you can ask for x/y coordinates.
I have a WorldWind application build based on the Java SDK. It has a great event handler for detecting when you click on objects, but I've run into a snag. While I can click on and select individual objects, I can't determine if the user is pressing the control key while they click (if they want to select multiple objects). I can implement event handlers for both the mouse and the keyboard, but I can't for the life of me figure out how to tie the two together. How could I make my mouse listener poll the system for a list of currently depressed keys?
You can call getModifiers() and bitwise compare to see if the control key (or shift key was depressed during the event.
public void mouseClicked( MouseEvent e ) {
if( ( e.getModifiers() & ActionEvent.CTRL_MASK ) > 0 ) {
// Control key depressed
}
}
For a MouseEvent , you could just call the getModifiers() to get a mask of modifier keys(shift/control/alt etc.) keys that are pressed .
For the general case, use a variable to tie them together ?
Your keyhandler sets/clears the variable when it registers a keypress, your mouselistener checks that variable.
If you need to decople these a bit more, just create a instance that both your key listener and mouselistener accesses.
public class Pressedkeys {
private boolean shiftPressed = false;
private boolean controlPressed = false;
public void setShiftPressed(boolean pressed) {
this.shiftPressed = pressed;
}
public void setControlPressed (boolean pressed) {
this.shiftPressed = pressed;
}
public boolean isControlPresed() {
return controlPressed ;
}
...
}
Pressedkeys k = new PressedKeys();
MyMouseThing t = new MyMouseThing(k);
//your mousething mouse handler would check k.isControlPressed();
MyKeyboardThing t = new MyKeyboardThing (k);
//your KeyBoardThing - which has a key handler would set k.setControlPressed(..);