How to handle the mouse wheel scrolling event using JavaFX? - javafx

Just need to get some numeric equivalent, which will show how much the wheel is scrolled.
I managed to find an example only using awt/swing: Java Docs
P.S. Sorry for my English.

{
...
sceneChart.setOnScroll(event -> print(event));
}
public void print (ScrollEvent event) {
System.out.println(event.getDeltaY());
}

add onScroll to your javafx element to handle scroll event
for example here add onScroll to ImageView
<ImageView onScroll="#onScrollImageView" .........../>
and handle that in fxml controller like here:
public void onScrollImageView(ScrollEvent scrollEvent) {
double deltaY = scrollEvent.getDeltaY();
if(deltaY<0)
//scroll up
if(deltaY>0)
//scroll down
}
getDeltaY() return the vertical scroll amount.
and negative value of getDeltaY() or positive value means scroll direction

Related

Zoom in / Zoom out in QT without using scroll button

I want to zoom in/out a part in openGL using mouse. Now I can do it well using the scroll button in mouse. But my goal is now to perform the same operation by holding the left mouse button and moving the mouse to and fro in the screen.
I don't know how to perform the zooming action by detecting the to and fro motion of mouse.
// function for mouse scroll events
void VDUI_GLWidget::wheelEvent (QWheelEvent * e) {
// here comes the code for zoom in / out based on the scrolling
MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
updateGL();
}
Now I want to perform the same using mouse move and mouse press events. I'm unable to pick the event which detects the to and fro motion
Now I have found the solution. Finding the difference between the current & previous Y axis position, I can zoom in / out the Please refer this below mentioned code.
// function for mouse move events
void GLWidget::mouseMoveEvent (QMouseEvent * e) {
static int curY = 0, prevY = 0;
if (e->buttons()) {
curY = e->y(); // current position of Y
if( (curY - prevY) > 0 ) // call zoom in function
else // call zoom out function
updateGL();
}
prevY = curY;
}

Javafx Jfoenix Drawer is blocking the nodes behind the Overlay

I am new to Javafx and after some readings on the subject I decided to start building my first application.
My application has a main page and an hamburgerDrawer on left side panel. The trouble I am having is that when I load the application, the drawer overlay is blocking the nodes beneath it. I tried to use the method SetDefaultDrawerSize() to 0 when I close the drawer, and to a specific size, say SetDefaultDrawerSize(900), with no success, the drawer is still blocking the content beneath.
#Override
public void initialize(URL url, ResourceBundle rb) {
try {
AnchorPane drawerContent = FXMLLoader.load(getClass().getResource("/materialitemtracker/view/AnchorPaneHamburgerDrawerView.fxml"));
hamburgerDrawer.setSidePane(drawerContent);
hamburgerDrawer.setOverLayVisible(true);
hamburgerDrawer.setResizableOnDrag(true);
HamburgerBackArrowBasicTransition burgerTask = new HamburgerBackArrowBasicTransition(hamburger);
burgerTask.setRate(-1);
hamburger.addEventHandler(MouseEvent.MOUSE_PRESSED, (e) -> {
burgerTask.setRate(burgerTask.getRate() * -1);
burgerTask.play();
if (hamburgerDrawer.isShown()) {
hamburgerDrawer.close();
// hamburgerDrawer.setDefaultDrawerSize(0);
} else {
hamburgerDrawer.open();
// hamburgerDrawer.setDefaultDrawerSize(900);
}
});
} catch (IOException ex) {
Logger.getLogger(AnchorPaneMainController.class.getName()).log(Level.SEVERE, null, ex);
}
Sample images:
Application Main Page
Drawer content
I had a similar issue to the one you describe. However in my case it wasn't the overlay but the drawer itself. The overlay when visible would encompass the entire UI when visible so I quickly determined that this wasn't my issue since it was only the buttons on the left of the UI which were not receiving events. Instead it seemed the area affected was limited the default drawer size I had set.
There are two solutions i could see:
Move the buttons above the drawer in the UI structure. This didn't work for me since the buttons would then overlap the expanded drawer in my UI.
Give the drawer a negative offset and change the constraints depending on the drawer state at runtime. My drawer resides on the left of the UI inside an AnchorPane so set a negative left anchor value to begin with (-255 for this example). Then depending on the state I do as follows.
drawer.setOnDrawerOpening(event ->
{
AnchorPane.setRightAnchor(drawer, 0.0);
AnchorPane.setLeftAnchor(drawer, 0.0);
AnchorPane.setTopAnchor(drawer, 0.0);
AnchorPane.setBottomAnchor(drawer, 0.0);
});
drawer.setOnDrawerClosed(event ->
{
AnchorPane.clearConstraints(drawer);
AnchorPane.setLeftAnchor(drawer, -255.0);
AnchorPane.setTopAnchor(drawer, 0.0);
AnchorPane.setBottomAnchor(drawer, 0.0);
});
Try the following code:
if (drawer.isOpened()) {
drawer.close();
drawer.setVisible(false);
} else {
drawer.setVisible(true);
drawer.open();
}

Resize a Button JavaFX

i have a question about a JavaFx Button.
In the following code i add a Button into a HBox.
ivTriangleImg.setFitHeight(16);
ivTriangleImg.setFitWidth(16);
ivTriangleImg.setRotate(iRotateCoord1);
btnTriangle.setGraphic(ivTriangleImg);
btnTriangle.setStyle("-fx-background-color:green;");
addComponentToBox(btnTriangle);
The Button gets a Graphic -> The Graphic is a transparent triangle with the Size of 16x16 pixels.
The Problem is, that the Button doesn't have the Size 16x16 it is so much more. How can i get the Button smaller and the Pictur must have the same size?
For JavaFX 8 use
btnTriangle.setPadding(Insets.EMPTY);
For JavaFX 2 use
btnTriangle.setStyle("-fx-padding: 0;");
However you can directly put the image view to the scene rather than setting it to the button's graphic, and add listeners you want:
ivTriangleImg.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
// do something
}
});
I added your Code, it works very fine. I made it a little bit different:
btnTriangle.setStyle("-fx-background-color:transparent;-fx-padding:0;-fx-background-size:0;");

hide QLabel based on text-size

I would like to write a custom QLabel subclass with some more features for responsive design. In thisexample, I want to write a QLabel which scales the text based on the useable space. This is quite easy but also has some problems because of Qt-intern stuff. (I have to scale the text to 0.9 of the useable space, otherwise resizing the window / widget gets buggy)
Now I wan't to add a way to hide the label completely when the font size is bellow a specific threshold. However, this seems to be quite a complex task.
Here is what I have sofar in the classes resizeEvent(QResizeEvent *event) function.
Right now, my function only sets the text to "" when the size would be bellow the threshold.
void CustomLabel::resizeEvent (QResizeEvent * event ) {
if(autoFontResize) {
this->setSilentText(labelText); // just the normal setText function, I overwrote it for the subclass
QFont f = this->font();
int flags = Qt::TextDontClip|Qt::TextWordWrap;
QRect fontBoundRect = this->fontMetrics().boundingRect(this->rect(), flags, this->text());
float xFactor = (float)event->size().width() / (float)fontBoundRect.width();
float yFactor = (float)event->size().height() / (float)fontBoundRect.height();
float factor = xFactor < yFactor ? xFactor : yFactor;
f.setPointSizeF(f.pointSize()*factor*0.9); //
if(minimumFontSize != 0) { // 0 = no minimum Size for the font
if(f.pointSize() < minimumFontSize) {
if(hideFontOnMinimum) { // either Hide or set to the limit size
this->setSilentText(""); //replace text
} else {
f.setPointSizeF(minimumFontSize);
}
}
}
this->setFont(f);
}
QLabel::resizeEvent(event);
}
By the way, some parts of the code are found on stackoverflow, not mine. ;)
What I would like to do is to completely hide() the label. However the label doesn't know when It can show() again since the resizeEvent doesn't seem to be called after that.
Any ideas?
Thanks!
As you've noticed, if you call hide() on the widget it fails to receive a resize event. Since you're customising the class anyway, rather than calling hide(), you could just set a class variable to note that it's hidden and overload the paintEvent function, not to draw the widget if the variable is set: -
void CustomLabel::paintEvent(QPaintEvent * event)
{
if(m_hideOnMinimum)
return;
QLabel::paintEvent(event);
}
Note that by not painting the label, it will be hidden, but the user may still be able to interact with it, so you will need to disable it or overload keyboard / mouse events too.

How can I automatically scroll a VBox when an item is drug near the top or bottom edge?

I have a VBox containing a bunch of panels. I have implemented dragging and dropping but I need to be able to scroll automatically when the item is drug near the edge. I am having mixed results. I can get it to work, but not well. My example is below. It works if the user bounces their mouse around a little near the top or bottom edge, but I want it to work if they just hold the mouse there. Any suggestions?
On Mouse down (I'm doing several other things but this is one of them):
VBox(di.parent).addEventListener(MouseEvent.MOUSE_MOVE,autoScrollSection,true,500);
On dragDrop
VBox(evt.currentTarget.parent).removeEventListener(MouseEvent.MOUSE_MOVE, autoScrollSection,true);
Here is the autoScroll function:
private function autoScrollSection(evt:MouseEvent):void{
var tempVBox:VBox = VBox(evt.currentTarget);
if(tempVBox.mouseY<50){
tempVBox.verticalScrollPosition += -50;
}
if(tempVBox.mouseY> int(tempVBox.height-50)){
tempVBox.verticalScrollPosition += +50;
}
}
So if they are within 50px of an edge then it should scroll by 50px. I've exaggerated the numbers just to get an affect.
Heres how I solved it:
[Bindable] public var timer:Timer = new Timer(50);
private function autoScrollSection(active:Boolean,cont:VBox):void{
if(active){
timer.addEventListener(TimerEvent.TIMER,function():void{
if(cont.mouseY<50){
cont.verticalScrollPosition += -20;
}
if(cont.mouseY> int(cont.height-50)){
cont.verticalScrollPosition += +20;
}
})
timer.start();
}else{
timer.stop();
}
}
Then changed the calls in mouse down and drag drop to this respectively
autoScrollSection(true,VBox(di.parent));
autoScrollSection(false,VBox(evt.currentTarget.parent));
It works but feels like a bit of a hack. I welcome any better suggestions.

Resources