/* Ċ Ġ* ĠCopyright Ġ 2 0 0 0 - 2 0 1 9 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . intellij . data vis . r . in lay s . components Ċ Ċ import Ġcom . intellij . openapi . ui . popup . JB Popup Factory Ċ import Ġcom . intellij . ui . Document Adapter Ċ import Ġcom . intellij . util . ui . J BU I Ċ import Ġorg . intellij . data vis . r . in lay s . components . Histogram Slider . Companion . show Ċ import Ġjava . awt .* Ċ import Ġjava . awt . event . Mouse Adapter Ċ import Ġjava . awt . event . MouseEvent Ċ import Ġjavax . swing . J Component Ċ import Ġjavax . swing . JLabel Ċ import Ġjavax . swing . JPanel Ċ import Ġjavax . swing . JTextField Ċ import Ġjavax . swing . event . Document Event Ċ import Ġkotlin . math . ceil Ċ import Ġkotlin . math . floor Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ Ċ /** Ċ Ġ* ĠMagic Ġdistribution Ġhistogram Ġslider . Ċ Ġ* ĠProvide d Ġ[ on User Input ] Ġhandler Ġwill Ġbe Ġtriggered Ġeach Ġtime Ċ Ġ* Ġuser Ġspecifies Ġselection Ġrange Ġwith Ġeither Ġtext Ġinput Ġfields Ċ Ġ* Ġor Ġmouse Ġdrag Ġn Ġdropping . Ċ Ġ* ĠIt 's Ġ** not ** Ġguaranteed Ġthat Ġtwo Ġsequential Ġcalls Ġof Ġthis Ġhandler Ċ Ġ* Ġwill Ġpass Ġdifferent Ġranges . Ċ Ġ* Ċ Ġ* Ġ** Note :** Ġit Ġcan Ġbe Ġeasily Ġinstantiated Ġat Ġdesired Ġposition Ġwith Ġutility Ġmethod Ġ[ show ] Ċ Ġ*/ Ċ class ĠHistogram Slider ( ĊĠ Ġhistogram : ĠHistogram , ĊĠ Ġdrawing Style : ĠDraw ing Style ? Ġ= Ġnull , ĊĠ Ġprivate Ġval Ġon User Input : Ġ(( Closed Range < Double > ?) Ġ-> ĠUnit )? Ġ= Ġnull Ċ ) Ġ{ ĊĊĠ Ġprivate Ġvar Ġx First Ġ= Ġ- 1 ĊĠ Ġprivate Ġvar Ġx Second Ġ= Ġ- 1 ĊĠ Ġprivate Ġvar Ġbacking Selection Range : ĠClosed Range < Double >? Ġ= Ġnull ĊĠĠĠ Ġset ( range ) Ġ{ ĊĠĠĠĠĠ Ġfield Ġ= Ġrange ĊĠĠĠĠĠ Ġif Ġ( range Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfrom Input Field . sil ently Change Value ( range . start ) ĊĠĠĠĠĠĠĠ Ġto Input Field . sil ently Change Value ( range . end Inclusive ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġprivate Ġval Ġfrequencies Ġ= Ġhistogram . frequ encies ĊĠ Ġprivate Ġval Ġhistogram Start Ġ= Ġhistogram . values . start ĊĠ Ġprivate Ġval Ġhistogram End Ġ= Ġhistogram . values . end Inclusive ĊĠ Ġprivate Ġval Ġhistogram Step Ġ= Ġ( histogram End Ġ- Ġhistogram Start ) Ġ/ Ġhistogram . frequ encies . size ĊĊĠ Ġprivate Ġval Ġhistogram Panel Ġ= ĠHistogram Panel ( frequ encies , Ġdrawing Style Ġ?: ĠDEFAULT _ DRAW ING _ STYLE ). apply Ġ{ ĊĠĠĠ Ġadd Mouse Listener ( object Ġ: ĠMouse Adapter () Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġmouse Pressed ( e : ĠMouseEvent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( e Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġx First Ġ= Ġe . x ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun Ġmouse Released ( e : ĠMouseEvent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( e Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġx Second Ġ= Ġe . x ĊĠĠĠĠĠĠĠĠĠ Ġupdate Selection Range () ĊĠĠĠĠĠĠĠĠĠ Ġnotify Range Changed () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠĠĠ Ġadd Mouse Motion Listener ( object Ġ: ĠMouse Adapter () Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġmouse Drag ged ( e : ĠMouseEvent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( e Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġx Second Ġ= Ġe . x ĊĠĠĠĠĠĠĠĠĠ Ġupdate Selection Range () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġfrom Input Field : ĠSwitch able Number Field Ġ= ĠSwitch able Number Field Ġ{ Ġnew From Ġ-> ĊĠĠĠ Ġselection Range Ġ= Ġmake Range ( new From , Ġto Input Field . value ) ĊĠĠĠ Ġnotify Range Changed () ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġto Input Field : ĠSwitch able Number Field Ġ= ĠSwitch able Number Field Ġ{ Ġnew To Ġ-> ĊĠĠĠ Ġselection Range Ġ= Ġmake Range ( from Input Field . value , Ġnew To ) ĊĠĠĠ Ġnotify Range Changed () ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġroot Panel Ġ= ĠJPanel ( Grid BagLayout ()). apply Ġ{ ĊĠĠĠ Ġadd With Constraints ( histogram Panel , Ġ 0 , Ġ 0 , Ġwidth Ġ= Ġ 3 , Ġy Weight Ġ= Ġ 1 . 0 ) ĊĠĠĠ Ġadd With Constraints ( from Input Field , Ġ 0 , Ġ 1 , Ġx Weight Ġ= Ġ 0 . 5 , Ġy Weight Ġ= Ġ 0 . 0 ) ĊĠĠĠ Ġadd With Constraints ( JLabel ("- ", ĠJLabel . CENTER ), Ġ 1 , Ġ 1 , Ġx Weight Ġ= Ġ 0 . 0 , Ġy Weight Ġ= Ġ 0 . 0 ) ĊĠĠĠ Ġadd With Constraints ( to Input Field , Ġ 2 , Ġ 1 , Ġx Weight Ġ= Ġ 0 . 5 , Ġy Weight Ġ= Ġ 0 . 0 ) ĊĠ Ġ} ĊĊĠ Ġval Ġcomponent : ĠJ Component ĊĠĠĠ Ġget () Ġ= Ġroot Panel ĊĊĠ Ġvar Ġselection Range : ĠClosed Range < Double >? ĊĠĠĠ Ġget () Ġ= Ġbacking Selection Range ĊĠĠĠ Ġset ( range ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( range Ġ!= Ġbacking Selection Range ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbacking Selection Range Ġ= Ġrange ĊĠĠĠĠĠĠĠ Ġval Ġselected Indices Ġ= Ġconvert Values To Indices ( range ) ĊĠĠĠĠĠĠĠ Ġupdate Histogram Panel ( selected Indices ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġnotify Range Changed () Ġ{ ĊĠĠĠ Ġon User Input ?. invoke ( back ing Selection Range ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġconvert Values To Indices ( values : ĠClosed Range < Double >? ): ĠInt Range ? Ġ{ ĊĠĠĠ Ġreturn Ġvalues ?. let Ġ{ Ġrange Ġ-> ĊĠĠĠĠĠ Ġval ĠstartIndex Ġ= Ġconvert Value To Index ( range . start ) Ġ{ Ġfloor ( it ) Ġ} ĊĠĠĠĠĠ Ġval Ġend Index Ġ= Ġconvert Value To Index ( range . end Inclusive ) Ġ{ Ġceil ( it ) Ġ} ĊĠĠĠĠĠ ĠInt Range ( startIndex , Ġend Index ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġconvert Value To Index ( value : ĠDouble , Ġrounding : Ġ( Double ) Ġ-> ĠDouble ): ĠInt Ġ{ ĊĠĠĠ Ġval Ġfraction al Ġ= Ġ( value Ġ- Ġhistogram Start ) Ġ/ Ġhistogram Step ĊĠĠĠ Ġreturn Ġrounding ( fraction al ). toInt () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġconvert Indices To Values ( indices : ĠInt Range ?): ĠClosed Range < Double >? Ġ{ ĊĠĠĠ Ġreturn Ġindices ?. let Ġ{ Ġrange Ġ-> ĊĠĠĠĠĠ Ġval Ġfrom Ġ= Ġconvert Index To Value ( range . first ) ĊĠĠĠĠĠ Ġval Ġto Ġ= Ġconvert Index To Value ( range . last ) ĊĠĠĠĠĠ Ġfrom . range To ( to ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġconvert Index To Value ( index : ĠInt ): ĠDouble Ġ{ ĊĠĠĠ Ġreturn Ġindex Ġ* Ġhistogram Step Ġ+ Ġhistogram Start ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġconvert Coordinate To Value ( coordinate : ĠInt ): ĠDouble Ġ{ ĊĠĠĠ Ġval Ġwidth Ġ= Ġhistogram Panel . width ĊĠĠĠ Ġval Ġratio Ġ= Ġcoordinate . toDouble () Ġ/ Ġwidth . toDouble () ĊĠĠĠ Ġreturn Ġfloor (( frequ encies . size Ġ* Ġhistogram Step Ġ* Ġratio ) Ġ+ Ġhistogram Start ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġupdate Selection Range () Ġ{ ĊĠĠĠ Ġval Ġwidth Ġ= Ġhistogram Panel . width ĊĠĠĠ Ġval Ġx From Ġ= Ġmin ( x First , Ġx Second ). coerce In ( 1 , Ġwidth Ġ- Ġ 1 ) ĊĠĠĠ Ġval Ġx To Ġ= Ġmax ( x First , Ġx Second ). coerce In ( 1 , Ġwidth Ġ- Ġ 1 ) ĊĠĠĠ Ġval Ġvalue From Ġ= Ġconvert Coordinate To Value ( x From ) ĊĠĠĠ Ġval Ġvalue To Ġ= Ġconvert Coordinate To Value ( x To ) ĊĠĠĠ Ġselection Range Ġ= Ġvalue From . range To ( value To ) ĊĠĠĠ Ġbacking Selection Range Ġ= Ġconvert Indices To Values ( histogram Panel . selected Indices ) Ġ Ġ// ĠNote : Ġauto Ġround Ġselection Ġrange Ġto Ġclosest Ġticks ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġupdate Histogram Panel ( new Selected Indices : ĠInt Range ?) Ġ{ ĊĠĠĠ Ġif Ġ( histogram Panel . selected Indices Ġ!= Ġnew Selected Indices ) Ġ{ ĊĠĠĠĠĠ Ġhistogram Panel . selected Indices Ġ= Ġnew Selected Indices ĊĠĠĠĠĠ Ġcomponent . rep aint () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġdata Ġclass ĠHistogram ( ĊĠĠĠ Ġ/** ĠOb servations Ġfor Ġy - axis , Ġmust Ġfall Ġin Ġrange Ġ[ 0 . 0 , Ġ 1 . 0 ] Ġ*/ ĊĠĠĠ Ġval Ġfrequencies : ĠList < Double >, ĊĊĠĠĠ Ġ/** ĠRange Ġof Ġx - axis Ġcovered Ġby Ġhistogram Ġ*/ ĊĠĠĠ Ġval Ġvalues : ĠClosed Range < Double > ĊĠ Ġ) ĊĊĠ Ġdata Ġclass ĠDraw ing Style ( ĊĠĠĠ Ġval Ġhistogram Color : ĠColor , ĊĠĠĠ Ġval Ġselection Color : ĠColor , ĊĠĠĠ Ġval ĠbackgroundColor : ĠColor ? ĊĠ Ġ) ĊĊĠ Ġprivate Ġclass ĠHistogram Panel ( ĊĠĠĠ Ġprivate Ġval Ġfrequencies : ĠList < Double >, ĊĠĠĠ Ġprivate Ġval Ġdrawing Style : ĠDraw ing Style , ĊĠĠĠ Ġvar Ġselected Indices : ĠInt Range ? Ġ= Ġnull ĊĠ Ġ) Ġ: ĠJPanel () Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġpaint Component ( g : ĠGraphics ) Ġ{ ĊĠĠĠĠĠ Ġdrawing Style . backgroundColor ?. let Ġ{ Ġcolor Ġ-> ĊĠĠĠĠĠĠĠ Ġg . color Ġ= Ġcolor ĊĠĠĠĠĠĠĠ Ġg . fillRect ( 0 , Ġ 0 , Ġwidth , Ġheight ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġcolumn Width Ġ= Ġwidth Ġ/ Ġfrequencies . size ĊĠĠĠĠĠ Ġg . color Ġ= Ġdrawing Style . histogram Color ĊĠĠĠĠĠ Ġfor Ġ(( index , Ġvalue ) Ġin Ġfrequencies . with Index ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġclamp ed Ġ= Ġvalue . coerce In ( 0 . 0 , Ġ 1 . 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġcolumn Height Ġ= Ġ( height Ġ* Ġclamp ed ). toInt () ĊĠĠĠĠĠĠĠ Ġg . fillRect ( index Ġ* Ġcolumn Width , Ġheight Ġ- Ġcolumn Height , Ġcolumn Width , Ġcolumn Height ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġselected Indices ?. let Ġ{ Ġindices Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġindices . first . coerce In ( 0 , Ġfrequencies . size ) ĊĠĠĠĠĠĠĠ Ġval Ġlast Ġ= Ġindices . last . coerce In ( 0 , Ġfrequencies . size ) ĊĠĠĠĠĠĠĠ Ġval Ġfrom Ġ= Ġfirst Ġ* Ġcolumn Width ĊĠĠĠĠĠĠĠ Ġval Ġselection Width Ġ= Ġ( last Ġ- Ġfirst ) Ġ* Ġcolumn Width ĊĠĠĠĠĠĠĠ Ġg . color Ġ= Ġdrawing Style . selection Color ĊĠĠĠĠĠĠĠ Ġg . fillRect ( from , Ġ 0 , Ġselection Width , Ġheight ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġclass ĠSwitch able Number Field ( on ValueChanged : Ġ( Double ?) Ġ-> ĠUnit ) Ġ: ĠJTextField () Ġ{ ĊĠĠĠ Ġprivate Ġvar ĠisActive Ġ= Ġtrue ĊĊĠĠĠ Ġvar Ġvalue : ĠDouble ? ĊĠĠĠĠĠ Ġget () Ġ= Ġtext . toDouble OrNull () ĊĠĠĠĠĠ Ġset ( newValue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtext Ġ= ĠnewValue ?. toString () ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠ Ġdocument . add Document Listener ( object Ġ: ĠDocument Adapter () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġtext Changed ( e : ĠDocument Event ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( isActive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġtext . toDouble OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon ValueChanged ( newValue ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsilently Change Value ( newValue : ĠDouble ?) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( value Ġ!= ĠnewValue ) Ġ{ ĊĠĠĠĠĠĠĠ ĠisActive Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvalue Ġ= ĠnewValue ĊĠĠĠĠĠĠĠ ĠisActive Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval ĠDEFAULT _ DRAW ING _ STYLE Ġ= ĠDraw ing Style ( ĊĠĠĠĠĠ ĠColor ( 9 6 , Ġ 1 6 0 , Ġ 2 5 5 ), ĊĠĠĠĠĠ ĠColor ( 2 5 5 , Ġ 0 , Ġ 0 , Ġ 9 6 ), ĊĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġfun Ġshow ( ĊĠĠĠĠĠ Ġowner : ĠJ Component , ĊĠĠĠĠĠ Ġpoint : ĠPoint , ĊĠĠĠĠĠ Ġpreferred Size : ĠDimension , ĊĠĠĠĠĠ Ġhistogram : ĠHistogram , ĊĠĠĠĠĠ Ġselected Values : ĠClosed Range < Double >, ĊĠĠĠĠĠ Ġdrawing Style : ĠDraw ing Style ? Ġ= Ġnull , ĊĠĠĠĠĠ Ġon User Input : Ġ( Closed Range < Double > ?) Ġ-> ĠUnit ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠ Ġval Ġslider Ġ= ĠHistogram Slider ( histogram , Ġdrawing Style , Ġon User Input ). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġcomponent . preferred Size Ġ= Ġpreferred Size ĊĠĠĠĠĠĠĠ Ġselection Range Ġ= Ġselected Values ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġpopup Builder Ġ= ĠJ B Popup Factory . getInstance (). create Component Popup Builder ( slider . component , Ġnull ). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġset Focus able ( true ) ĊĠĠĠĠĠĠĠ Ġset Request Focus ( true ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġpopup Ġ= Ġpopup Builder . create Popup () ĊĠĠĠĠĠ Ġpopup . show In Screen Coordinates ( owner , Ġpoint ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠJPanel . add With Constraints ( component : ĠJ Component , Ġx : ĠInt , Ġy : ĠInt , Ġwidth : ĠInt Ġ= Ġ 1 , Ġx Weight : ĠDouble ? Ġ= Ġnull , Ġy Weight : ĠDouble ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġval Ġconstraints Ġ= ĠGridBagConstraints (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġfill Ġ= ĠGridBagConstraints . BOTH ĊĠĠĠĠĠĠĠ Ġin sets Ġ= ĠJ BU I . in sets ( 2 Ġ* Ġwidth ) ĊĠĠĠĠĠĠĠ Ġgrid x Ġ= Ġx ĊĠĠĠĠĠĠĠ Ġgrid y Ġ= Ġy ĊĠĠĠĠĠĠĠ Ġgrid width Ġ= Ġwidth ĊĠĠĠĠĠĠĠ Ġif Ġ( x Weight Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġweight x Ġ= Ġx Weight ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( y Weight Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġweight y Ġ= Ġy Weight ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġadd ( component , Ġconstraints ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmake Range ( from : ĠDouble ?, Ġto : ĠDouble ?): ĠClosed Range < Double >? Ġ{ ĊĠĠĠĠĠ Ġreturn Ġfrom ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġto ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( from Ġ<= Ġto ) Ġfrom . range To ( to ) Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ