12 novembro 2008

Creating a Scroller Panel in JavaFX

Today I've created an Scroller Panel in JavaFX. It was a good challenge.

Here is the code:
package brunogrossi.javafx.components;

import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;

/**
* @author Bruno Grossi
*/

private class Scroll extends CustomNode {
public attribute width:Integer;
public attribute height:Integer;
public attribute bodyHeight: Number;

private attribute position:Number;
private attribute barSizeMin:Number=30;
private attribute barSize:Number = 20;//bind if (height/(bodyHeight-height)< position="0"> maxPosition)
this.position=maxPosition
else
this.position=value;
}

postinit {
this.onMousePressed = function(e:javafx.input.MouseEvent):Void {
setPosition(e.getY() - (barSize / 2))
};

this.onMouseDragged = function(e:javafx.input.MouseEvent):Void {
setPosition(e.getY() - (barSize / 2))
};

this.onMouseWheelMoved = function(e:javafx.input.MouseEvent):Void {
setPosition(this.position + e.getWheelRotation())
};
}

protected function create():Node {
Group{
content: [
Rectangle {
width: bind width
height: bind height
fill: Color.WHITE
stroke: Color.WHITE
},
Line {
startX: bind width / 2
startY: bind 0
endX: bind width / 2
startY: bind height
stroke: Color.BLACK
strokeWidth: 1
effect: javafx.scene.effect.Shadow{radius:3}
},
Rectangle {
y: bind position
width: bind width
height: bind barSize
stroke: Color.BLACK
fill: Color.WHITESMOKE
arcWidth:10
arcHeight:20
smooth: true
effect: javafx.scene.effect.Lighting {
light: javafx.scene.effect.light.DistantLight{
azimuth: 60
elevation: 60
}
}
}
]
}

}
}

public class ScrollPanel extends CustomNode {
public attribute x:Integer;
public attribute y:Integer;
public attribute width:Integer;
public attribute height:Integer;

public attribute body: Node;
public attribute showScroll: Boolean = true;

private /*read-only*/ attribute scrollWidth = 15;
private /*read-only*/ attribute scroll:Scroll = Scroll{
translateX: bind width - scrollWidth - 1
width: scrollWidth
height: bind height
bodyHeight: bind body.getBoundsHeight()
};


postinit{
var onMouseWheelMovedOld = this.onMouseWheelMoved;
this.onMouseWheelMoved = function(e:javafx.input.MouseEvent):Void {
scroll.onMouseWheelMoved(e);
if (onMouseWheelMovedOld!=null)
onMouseWheelMovedOld(e);
};
}

protected function create():Node {
Group {
translateX: bind x
translateY: bind y
clip: Rectangle{width: bind width height: bind height}
content: [
Group{
clip: Rectangle{width: bind this.getInternalBoundsWidth() height: bind height}
content: Group{
content: body
translateY: bind -( scroll.position * (body.getBoundsHeight() - scroll.height)) / scroll.maxPosition
}
},
if (showScroll) scroll else null,
]
}
}

public function getInternalBoundsWidth(): Number {
if(showScroll) width - scrollWidth - 1 else width;
}
public function getInternalBoundsHeight(): Number {
height
}
}

/*This is for test */
var s = ScrollPanel {
width:100
height: 200
var colors = [Color.RED, Color.BLUE, Color.DARKGOLDENROD, Color.ALICEBLUE, Color.ANTIQUEWHITE, Color.AQUA, Color.AQUAMARINE, Color.AZURE, Color.BEIGE, Color.BISQUE, Color.CHOCOLATE]
body: Group{
content:
for(i in [0..30]) {[Rectangle{y: i * 10 width:99 height:10 fill:colors[
i mod sizeof colors] stroke:Color.BLACK},
javafx.scene.text.Text{y:i * 10 content:"{i}"}]
}
}
}

javafx.application.Frame {
visible: true
stage: javafx.application.Stage{
content: s
}
}

Nenhum comentário: