java - Is it possible to use to use a path transition on a dialog box in javafx? -
so i'm running little test application see if possible , move main project. main idea dialog box come top of screen center , waits response the user. if click no, program terminates. if click yes, dialog box goes center top screen , out of sight user.
package test; import java.util.optional; import javafx.animation.pathtransition; import javafx.application.application; import javafx.fxml.fxmlloader; import javafx.scene.scene; import javafx.scene.control.alert; import javafx.scene.control.alert.alerttype; import javafx.scene.control.buttontype; import javafx.scene.layout.vbox; import javafx.scene.shape.moveto; import javafx.scene.shape.path; import javafx.scene.shape.vlineto; import javafx.stage.stage; import javafx.util.duration; public class test extends application { @override public void start(stage stage) throws exception { vbox root = fxmlloader.load(getclass().getresource("fxmldocument.fxml")); alert alert = new alert(alerttype.confirmation); alert.settitle("confirmation dialog"); alert.setheadertext("look, confirmation dialog"); alert.setcontenttext("are ok this?"); path path = new path(); path.getelements().add(new moveto(300, -25)); path.getelements().add(new vlineto(200)); pathtransition pathtransition = new pathtransition(); pathtransition.setduration(duration.millis(1500)); pathtransition.setpath(path); pathtransition.setnode(alert); // problem lies. pathtransition.setcyclecount(1); pathtransition.play(); scene scene = new scene(root, 640, 480); stage.setscene(scene); stage.show(); optional<buttontype> result = alert.showandwait(); if (result.get() == buttontype.ok) { path path2 = new path(); path2.getelements().add(new moveto(300, 200)); path2.getelements().add(new vlineto(-25)); pathtransition pathtransition2 = new pathtransition(); pathtransition.setduration(duration.millis(1500)); pathtransition.setpath(path); pathtransition.setnode(alert); pathtransition.setcyclecount(1); pathtransition.play(); } else { stage.close(); } } public static void main(string[] args) { launch(args); } }
there's way can move alert dialog, means of yproperty()
. instead of path transition we'll use timeline set property. since read property, havet use doubleproperty
within transition instead , use alert.sety()
.
the first part of question, sliding in dialog, easy. second, sliding out, more complex, since dialog closed inmediately once button clicked.
solution 1. sliding in
we need dialog dimensions , position, , need show it. means shown, , inmediately moved top of screen.
so i'll change alert.showandwait()
alert.show()
.
@override public void start(stage primarystage) { button btn = new button(); btn.settext("show sliding in alert dialog"); btn.setonaction(event -> { alert alert = new alert(alerttype.confirmation); alert.settitle("confirmation dialog"); alert.setheadertext("look, confirmation dialog"); alert.setcontenttext("are ok this?"); buttonbar buttonbar=(buttonbar)alert.getdialogpane().lookup(".button-bar"); buttonbar.setdisable(true); alert.initmodality(modality.application_modal); alert.show(); // can retrive alert bounds: double yini=-alert.getheight(); double yend=alert.gety(); // , move alert top of screen alert.sety(yini); final doubleproperty yproperty = new simpledoubleproperty(); yproperty.addlistener((ob,n,n1)->alert.sety(n1.doublevalue())); timeline timein = new timeline(); timein.getkeyframes().add( new keyframe(duration.seconds(1.5), e->buttonbar.setdisable(false), new keyvalue(yproperty, yend,interpolator.ease_both))); timein.play(); alert.resultproperty().addlistener((ob,r,r1)->{ if (r1 == buttontype.ok){ // alert closed , hidden in final position } else{ primarystage.close(); } }); }); stackpane root = new stackpane(); root.getchildren().add(btn); scene scene = new scene(root, 300, 250); primarystage.settitle("hello world!"); primarystage.setscene(scene); primarystage.show(); }
the listener in yproperty()
allow set position dialog within different positions interpolated during transition.
solution 2. slide in , out
this bit of dirty solution, since involves using second alert
dialog, given original 1 closed once buttons clicked. we'll add second dialog behind first one, , use create slide out effect once first 1 closed.
the side effect notice fast blink in phase of showing second , putting first 1 on top of it.
@override public void start(stage primarystage) { button btn = new button(); btn.settext("show sliding in alert dialog"); btn.setonaction(event -> { alert alert = new alert(alerttype.confirmation); alert.settitle("confirmation dialog"); alert.setheadertext("look, confirmation dialog"); alert.setcontenttext("are ok this?"); alert alertout = new alert(alerttype.confirmation); alertout.settitle("confirmation dialog"); alertout.setheadertext("look, confirmation dialog"); alertout.setcontenttext("are ok this?"); alertout.initmodality(modality.none); ((stage)alertout.getdialogpane().getscene().getwindow()).setopacity(0); buttonbar buttonbar=(buttonbar)alert.getdialogpane().lookup(".button-bar"); buttonbar.setdisable(true); alert.initmodality(modality.application_modal); alert.show(); // can retrive alert bounds: double yini=-alert.getheight(); double yend=alert.gety(); // , move alert top of screen alert.sety(yini); final doubleproperty yproperty = new simpledoubleproperty(); yproperty.addlistener((ob,n,n1)->alert.sety(n1.doublevalue())); timeline timein = new timeline(); timein.getkeyframes().add( new keyframe(duration.seconds(1.5), e->{ buttonbar.setdisable(false); // show second dialog alertout.show(); // move front first 1 ((stage)alert.getdialogpane().getscene(). getwindow()).tofront(); }, new keyvalue(yproperty, yend,interpolator.ease_both))); timein.play(); alert.resultproperty().addlistener((ob,r,r1)->{ if (r1 == buttontype.ok){ // show second dialog ((stage)alertout.getdialogpane().getscene().getwindow()).setopacity(1); buttonbar buttonbarout=(buttonbar)alertout.getdialogpane().lookup(".button-bar"); buttonbarout.setdisable(true); final doubleproperty ypropertyout = new simpledoubleproperty(yend); ypropertyout.addlistener((ov,n,n1)->alertout.sety(n1.doublevalue())); // create slide out transition timeline timeout = new timeline(); timeout.getkeyframes().add( new keyframe(duration.seconds(1.5), e->alertout.close(), new keyvalue(ypropertyout, yini,interpolator.ease_both))); timeout.play(); } else{ alertout.close(); primarystage.close(); } }); }); stackpane root = new stackpane(); root.getchildren().add(btn); scene scene = new scene(root, 300, 250); primarystage.settitle("hello world!"); primarystage.setscene(scene); primarystage.show(); }
edit
solution 2. improved slide in , out
i've found way use 1 single dialog, , provide slide out effect too.
all takes trap click action on selected button, consume event, add slide out transition there, , hide dialog on finished.
@override public void start(stage primarystage) { button btn = new button(); btn.settext("show sliding in alert dialog"); btn.setonaction(event -> { alert alert = new alert(alerttype.confirmation); alert.settitle("confirmation dialog"); alert.setheadertext("look, confirmation dialog"); alert.setcontenttext("are ok this?"); buttonbar buttonbar=(buttonbar)alert.getdialogpane().lookup(".button-bar"); buttonbar.setdisable(true); alert.initmodality(modality.application_modal); alert.show(); // can retrive alert bounds: double yini=-alert.getheight(); double yend=alert.gety(); // , move alert top of screen alert.sety(yini); buttonbar.getbuttons().stream().filter(b->((button)b).isdefaultbutton()).findfirst() .ifpresent(b->((button)b).addeventfilter(eventtype.root, e->{ if(e.geteventtype().equals(actionevent.action)){ e.consume(); final doubleproperty ypropertyout = new simpledoubleproperty(yend); ypropertyout.addlistener((ov,n,n1)->alert.sety(n1.doublevalue())); timeline timeout = new timeline(); timeout.getkeyframes().add(new keyframe(duration.seconds(1.5), t->alert.close(), new keyvalue(ypropertyout, yini,interpolator.ease_both))); timeout.play(); } })); final doubleproperty yproperty = new simpledoubleproperty(); yproperty.addlistener((ob,n,n1)->alert.sety(n1.doublevalue())); timeline timein = new timeline(); timein.getkeyframes().add(new keyframe(duration.seconds(1.5), e->{ buttonbar.setdisable(false); },new keyvalue(yproperty, yend,interpolator.ease_both))); timein.play(); }); stackpane root = new stackpane(); root.getchildren().add(btn); scene scene = new scene(root, 300, 250); primarystage.settitle("hello world!"); primarystage.setscene(scene); primarystage.show(); }
Comments
Post a Comment