Skip to main content

Using the self: var

4 replies [Last post]
jiyuu
Offline
Joined: 2008-10-13

Im learning JavaFX in a school course and my purpose is to create a photo gallery.

Im reading the JavaFX book by James Weaver but the code in it is a litle bit old. I have added an image to my stage, and added an onMouseDragged() event. The book is using a var (self:) in the event. But in netbeans 1.6 this var gives an error.

Why can't I use it? I want to move my image on mouse move, but can't understand how. Some tutorials are using localDragTranslation, but this function doesn't work for me.

Here is my code:
var hellojfxModel =
HelloJFXModel {
outputtext: "Are you a ninja?"
};

var hellojfxModel2 =
HelloJFXModel {
outputtext: "I don't think so.."
};

var self:javafx.scene.Node;

Frame {
title: "Two textlines at the same stage"
width: 1024 height: 768
visible: true

stage: Stage {
content:
[
// First we add an background image at the stage
ImageView {
image: Image {
url: "{__DIR__}/njlb.jpg"
height: 768
width: 1024
}

},
Text {
// Add a text to content
font: Font {
name: "Arial"
size: 28
style: FontStyle.ITALIC
}
x: 40
y: 50
fill: Color.WHITE
stroke: Color.WHITE
content: bind hellojfxModel.outputtext
},
Line {
// Write a line under text
startX: 38, startY: 52
endX: 240, endY: 52
strokeWidth: 1
stroke: Color.WHITE
},
Text {
// Add another text to the content
font: Font {
name: "Arial"
size: 28
style: FontStyle.ITALIC
}
x: 40
y: 150
fill: Color.WHITE
stroke: Color.WHITE
content: bind hellojfxModel2.outputtext
},
// using self var as an ImageView
self = ImageView {

// Image coordinates
var x1 = 800
var y1 = 2

// Image scale
var s1 = 1
var s2 = 1

// Bind translate options to image
transform: bind [
Translate.translate(x1, y1), Translate.scale(s1, s2)
]

// Swith cursor on mouse over
cursor: javafx.scene.Cursor.MOVE;

onMouseDragged: function( e: MouseEvent ):Void {
// want to use "e" or "self" to move image etc
x1 += e.localDragTranslation.x;
}

// just a test with the image
onMouseClicked: function( e: MouseEvent ):Void {
//y1 = y1 + 10;
//x1 = x1 - 10;
}

// Bind image url in a var
var ninja:String = bind "{__DIR__}/njlb.jpg"

// Add image to scene
image: Image { url: bind ninja }

}

]
}

}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jimthev
Offline
Joined: 2003-08-27

Most tutorials are old but there are plenty of simple working samples inside Netbeans itself. Go to 'New Project' then open samples, then open JavaFX, then open Best Practices, then pick a project to test out. I haven't seen a lot of people reference those examples, but they are often good starting points.

jimthev
Offline
Joined: 2003-08-27

Replace localDragTranslation.x; with getX();

Then either change x1 to be a Number rather than an Integer (var x1 = 800.;) or

convert the result of getX() to an Integer (x1 += e.getX().intValue();)

The problem isn't related to the var self. It is that localDragTranslation isn't a field/attribute of MouseEvent. To find what you could have used from MouseEvent, you could look it up in preview api at http://javafx.com/releases/preview1/docs/api/javafx.input/javafx.input.M...
From what I can gather the parameter of onMouseDragged used to be a CanvasMouseEvent and in the compiled version it is now a MouseEvent so all the examples for the interpreted version won't work without the above type of conversion.

jiyuu
Offline
Joined: 2008-10-13

Thanks a lot. Didn't thought it was that easy, and when I read tutorials they are most of the time written in an old version =(

But still, the var self: is now removed? Can I use the event argument (e) to get the trigged object?

I also saw that when I move my object now, the cursor moves to the left corner in top of my image. Why?

jimthev
Offline
Joined: 2003-08-27

In your code, 'self' is just the name being used, it isn't a key word. It has nothing to do with JavaFX itself. You could replace all the usages of 'self' with 'mainNode' or 'myRootNode' or 'n' or whatever. It isn't any different than the names used for other the other var definitions like 'hellojfxModel' or 'hellojfxModel2'. It is poorly named in my view because it causes confusion with things that are keywords like 'this' or 'super'.

The image is getting reset to the lower right of the cursor because you are translating it to that location. What happens when you drag on the image is

1. An event goes to the onMouseDragged for the ImageView you defined (which has the variable name 'self').
2. You then get the x,y location of the ending point of the drag in coordinates based on the ImageView.
3. You add that location to the original location of the ImageView which resets the upper left of the image to the new point.
4. This resets the coordinate system of the ImageView so the next x,y from the next mouse event is now in the new coordinate system.

This effect wasn't obvious to me when I first saw the way x1 was being modified, but it makes sense if you think about it. For example say there is a 200x200 image at 100,0 on the screen. If you drag the mouse on the image to 150,150 on the screen, the getX/getY of the event are based on the image so they are 50,150. The code then changes the image location to 150,150 (which is the upper left of the image). If you were to somehow drag to exactly the same location again (150,150 on the screen), the new getX/getY would be 0,0 since they are based on the image location. So the image wouldn't change.

If you want the image to be dragged based on the point you click on rather than the upper left, you need to change the getX/getY to be based off of the location you put the mouse down upon. So you'd change your code to be something like:

var s1 = 1
var s2 = 1

var dragOffsetX = 0;
var dragOffsetY = 0;

onMousePressed: function( e: MouseEvent ):Void {
dragOffsetX = e.getX().intValue();
dragOffsetY = e.getY().intValue();
}

// Bind translate options to image
transform: bind [
Translate.translate(x1, y1), Translate.scale(s1, s2)
]

// Swith cursor on mouse over
cursor: javafx.scene.Cursor.MOVE;

onMouseDragged: function( e: MouseEvent ):Void {
x1 += e.getX().intValue() - dragOffsetX;
y1 += e.getY().intValue() - dragOffsetY;
}

Here, you are storing the mouse down location and readjusting the getX/getY to be based off of that location.