Java drag image better & Overlapping image detection - java

I have two questions for you:
[SOLVED] - In java, I have the ability to move around an image using the mouse listeners. Instead of moving the image exactly where my pointer is, how do I make it so if I click and move up the mouse, it just moves the image up. Not make the image jump to where my mouse pointer is.
[SOLVED] - Since I am building an editor, If I have multiple images on the window that you can move around, if there is two overlapping images, how do I detect which image I should actually move. What happens If I want to move the one behind the image instead of the front one or vice versa. What is the best method that you guys have done here.
Some code that relates to both of these questions
addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
//use this
if(curObj != null){
Point p = arg0.getPoint();
curObj.pos.x = p.x;
curObj.pos.y = p.y;
......
}
}
});
addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
//right now find the first one that contains the mouse.
//later we can make it so they have an option to pick on that overlaps.
Point p = arg0.getPoint();
SwingUtilities.convertPoint(Main.gui, p, instance);
....
//this is the code to detect which image to use
curObj = null;
for(int i = 0; i < objects.size(); i++){
StepObject obj = objects.get(i);
if(obj.isDraggable()){
if(p.x >= obj.pos.x && p.y >= obj.pos.y &&
p.x <= (obj.pos.x + obj.getWidth()) && p.y <= (obj.pos.y + obj.getHeight())){
curObj = obj;
break;
}
}
}
.....
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
Any feedback is appreciated.
Thanks.

I am actually using Graphics to draw an image.
This has been a user interface problem going back to the earliest, widely-available object drawing programs. The common approach is to implement two basic operations that enable the user to expose a hidden object by changing it's rendering order:
Move backward: move the selection one step back in z-order.
Move to back: move the selection to the back of the z-order.
The two complementary operations are usually included:
Move forward: move the selection one step forward in z-order.
Move to front: move the selection to the front of the z-order.
GraphPanel illustrates several techniques for hit-testing and handling multiple selection in Java 2D. It illustrates the simpler case in which at least some of the object is visible. Its rendering order is defined by a simple List<Node> model using ArrayList, which is not ideal for re-ordering; consider LinkedList as an alternative implementation of the List interface.

One type of solution is how I've solved this for a chess board. The board is composed of a grid of JPanels that each can hold one or 0 JLabels (that hold the chess piece with an image). If I click on a JPanel that holds a JLabel, the JLabel is kicked up onto the top level window's glasspane and then dragged with the mouse. When the mouse is released, the MouseListener detects what JPanel of the grid I'm over, the chess engine determines if this is a valid move, and if so, the JLabel is added to the JPanel that the mouse cursor is over. If not, the JLabel goes back to its original JPanel. The JPanels use GridBagLayout, and so if a JLabel is added to it, it is displayed centrally in the JPanel cell.

Related

Java, If a draggable object touches other object

I have a code for dragging a label width mouse.
lbl_banner.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e) {
//catching the current values for x,y coordinates on screen
x_pressed = e.getX();
y_pressed = e.getY();
}
});
lbl_banner.addMouseMotionListener(new MouseMotionAdapter(){
#Override
public void mouseDragged(MouseEvent e){
//and when the Jlabel is dragged
setLocation(e.getXOnScreen() - x_pressed, e.getYOnScreen() - y_pressed);
}
});
Now, how do I make a function: While I'm dragging this label around the Screen, If the Label by dragging touches other object (label, button,...) to do something.
if(//labelTouchesSomething){//do something}
While this is not technically a dragging but the dynamic move of a component (dragging is the transfer of contents in between components), you can compute the intersection of the current moving component against other components (this may need some navigation inside your hierarchy). May be this can help you: How do I detect the collison of components?. You can also use the methods contains of Component to determine if some coordinates are inside a component or not.

JFrame Selecting Multiple Objects

I would like to know if the multiple selections function used in list, will be workable too in the object?
The example I found was working on the list as provided from the link.
https://stackoverflow.com/questions/25691623/jlist-listselectionlistener-multiple-interval-selection-that-waits-for-cntrl-or
The current project I'm working on is to draw different shapes which is an object. After done drawing, I shall be able to select more than 1 object by holding the SHIFT key.
How can I do that?
you can not re-use the List-Selection-Model in a simple way - i really recommend to use your own implemention instead.
To do so you must add a KeyListener and a MouseListener on your Panel in order to check for Shift pressed or not.
private boolean isShiftDown = false;
KeyAdapter ka = new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if(e.getKeyCode() == KeyEvent.VK_SHIFT){
isShiftDown=false;
}
}
#Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
if(e.getKeyCode() == KeyEvent.VK_SHIFT){
isShiftDown=true;
}
}
};
use your own selection 'model' which will be a simple list (java.util.List)
private List<Shape> selectionList = new ArrayList();
MouseAdapter ma = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
Shape shape = findShapeAt(e.getX(), e.getY() ); //i guessed you had a methode like that
if (shape != null){
//check is your shift key is down
if (isShiftDown){
//add or remove on click
if (selectionList.contains(shape) ){
selectionList.remove(shape);
}else{
selectionList.add(shape);
}
}else{
//if shift is NOT down, clear the list before adding
selectionList.clear();
selectionList.add(shape);
}
}
//show the selection in your gui();
updateSelection(); //that's your part - draw a nice border around all Shapes from the selectionList
}
};
don't forget to add both keyListener(KeyAdapter) and MouseListener(MouseAdapter) to your panel...
NOTE
i would really use the ctrl-key (KeyEvent.VK_CONTROL) instead of the shift-key to add/remove shapes by single-mouse-klick...

KeyListener - do I need to call the keyPressed Method in my main?

Here is what's inside my keyPressed:
public class Movie extends JFrame implements KeyListener {
public static Sprite star1 = new Sprite("Assets/star1.png");
public static Sprite star2 = new Sprite("Assets/star2.png");
public static Sprite star3 = new Sprite("Assets/star3.png");
public void init(){
this.addKeyListener(this);
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyPressed(KeyEvent e) {
System.out.println("KEY PRESSED: " + e.getKeyChar());
animation window = new animation(500, 450); //length , height
if (e.getKeyCode() == KeyEvent.VK_DOWN)
{
setFocusable(true);
Movie.star1.setPosition( Movie.star1.getXposition() -100, 0);
window.frameFinished();
}
else if (e.getKeyCode() == KeyEvent.VK_UP)
{
setFocusable(true);
Movie.star1.setPosition( Movie.star1.getXposition() +100, 0);
window.repaint();
}
}
My object does not move when the arrow keys are pressed.
All I want to know is - is this because I need to call the keyPressed(KeyEvent e) method in my main? When I do call it, I get an error that states:
cannot be resolved in a variable
The objects that I want to move are in a giant loop.
If you never add the key listener to some Swing component, then it will never receive events.
KeyListener itself isn't magical and doesn't listen for keypresses. What you do with a KeyListener is: you tell some other Swing component (like a window or a textbox) to call your KeyListener when a key is pressed. The component is what looks for keypresses, not the listener.
In your case, it looks like you meant to add the key listener to the window, with this.addKeyListener(this); (since in your case this is both a KeyListener and a JFrame).
However, if nothing calls your init method, then the code inside your init method (like any method) never runs, so the key listener doesn't get added to the window, so the window doesn't call it when a key is pressed!
One possible solution would be to make sure to call init after creating a new Movie (you haven't shown the code where that happens).
Another solution would be to use a constructor, instead of a method, like this:
public Movie() {
this.addKeyListener(this);
}
- constructors run when the object is created, so that way, addKeyListener will be called whenever a Movie object is created, without the creator having to remember to call init.

Dynamic Line between two points, click, move mouse, then click

I have to draw a Line in Java. I click one point, then release the mouse key, move the mouse (the end of the line should be where the mouse cursor is (a dynamic preview)) then click the mouse key again to make the line.
I see various questions on here, but most deal with holding a mouse button and dragging the mouse.
My question is, how can I draw a line dynamically using the method above. I am concerned about repainting. I had code earlier and it drew all the lines as I moved the mouse. Is there a way to just have a preview.
You need need to create a application implementing both a MouseEventListener and a MouseMotionListener. Use the MouseEventListener method mouseClicked to check whether the mouse has been clicked and subsequently the MouseMotionListener method MouseMoved to update the other end of the line to your mouse's position. Finally you use the MouseEventListener again to pinpoint the end location of the line.
I hope this helps.
Take a look at:
http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html and http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html.
There's a lot of information missing in your post, so it will be difficult to offer an exact solution, but here is the general idea. Assuming that you need a transparent JComponent that receive mouse events and paint your line preview, the code would look something like this.
public class MyLinePreviewComponent extends JComponent {
Point sourcePoint;
Point destinationPoint;
pubic MyLinePreviewComponent() {
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (sourcePoint == null)
sourcePoint = e.getPoint();
else
sourcePoint = null;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (sourcePoint != null)
targetPoint = e.getPoint();
repaint();
}
});
}
public void paintComponent(Graphics g) {
if (sourcePoint != null && destinationPoint != null) {
g.setColor(Color.red);
g.drawLine(sourcePoint.x, sourcePoint.y, destinationPoint.x, destinationPoint.y);
}
}
}
Note that I did not run this code.
If the line preview feature has to be added to an existing component, then you will have to repaint the regular content in paintComponent() before paiting the line.

How to implement shape manipulation on a drawing canvas?

I have a vector (_storedShapes) to store the painted rectangles (_rect). I also plan on adding ellipses. What I am trying to do is add a shape to the spot on the screen that I click and be able to resize it. Here is a website with a demo of what I am trying to do http://code.google.com/p/tangram-canvas/downloads/detail?name=TangramCanvas-1.2.zip.
The only difference from this demo is that I want my shape to expand on all sides from its center as I drag it.
From my code right now, a pre-sized rectangle pops up on the canvas where I click and then when I drag, just follows the cursor on the screen.
private class DrawSListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
_preX = (int) (_rect.getX() - e.getX());
_preY = (int) (_rect.getY() - e.getY());
DrawingPanel dp = new DrawingPanel();
_rect = new SketchyRectangle(dp);
System.out.println("new rec");
// if (_rect.contains(e.getPoint())) {
_rect.setLocation(e.getX(), e.getY());
System.out.println("setLocation");
repaint();
System.out.println("paint");
//}
}
}
/**
* Private class DrawListener is called when the DrawEllipse or DrawRectangle radio buttons are selected.
*
*/
private class DrawListener implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
if (_rect.contains(e.getPoint())) {
_rect.setLocation(_preX, _preY);
_storedShapes.add(_rect);
repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
}
I would keep two coordinates in the object (or wherever makes sense): prevDragCoord, shapeCenter. On mouse click store the coordinate of the event in both members. On mouse drag, update the rectangle size by adding to it the difference of the current event coordinate minus the coordinate stored in the object. Set the rectangle's location by setting the difference between the shapeCenter member and the rectangle size divided by 2 (e.g. shapeCenter.x - rect.xLength/2). Store the current coordinate in the object's coordinate member so it's ready to update on any subsequent calls to your handler.
I'll leave the implementation up to you. Maybe you can do it with only one variable, or maybe no variables because the event object has some sort of awesome data in it to get this done. This should be the general idea anyway.

Categories

Resources