def __init__(self): self._editor = MyCodeArea() borderPane = BorderPane() self._editor.setParagraphGraphicFactory(LineNumberFactory.get(self._editor)) self._editor.richChanges().filter(jp(lambda ch: not ch.getInserted().equals(ch.getRemoved()))).subscribe(jc(lambda change: self._editor.setStyleSpans(0, computeHighlighting(self._editor.getText())))) borderPane.setCenter(VirtualizedScrollPane(self._editor)) scene = Scene(borderPane) scene.getStylesheets().add(ASLANPP_SYNTAX_HIGHLIGHT); self.setScene(scene)
def initializeInterface(self): """Initialize the graphical user interface using JavaFX.""" fxml = File(self.resourcePath + "ExtensionTab.fxml") root = FXMLLoader.load(fxml.toURL()) self._scene = Scene(root) self._layout.setScene(self._scene) Platform.runLater(ExtensionRunnable(self.initializeElements))
def start(self, primaryStage): primaryStage.setTitle('Hello World!') from javafx.scene import Scene from javafx.scene.layout import StackPane primaryStage.setScene(Scene(StackPane(), 320, 240)) primaryStage.show()
def createStage(self): stage = Stage() bPane = BorderPane() scene = Scene(bpane) stage.setScene(scene) stage.show() return bPane
def __init__(self): self._editor = MyCodeArea() borderPane = BorderPane() self._editor.setParagraphGraphicFactory( LineNumberFactory.get(self._editor)) borderPane.setCenter(VirtualizedScrollPane(self._editor)) scene = Scene(borderPane) #scene.getStylesheets().add(ASLANPP_SYNTAX_HIGHLIGHT); self.setScene(scene)
def load(self, urlString): url = ClassLoader.getSystemClassLoader().getResource(urlString) #url = URL(urlString) loader = FXMLLoader(url) root = loader.load() self.controller = loader.getController() self.scene = Scene(root) self.stage.setScene(self.scene) self.stage.show()
def createChart(fxCanvas): pieChartData = FXCollections.observableArrayList( PieChart.Data('Grapefruit', 13), PieChart.Data('Oranges', 25), PieChart.Data('Plums', 10), PieChart.Data('Pears', 22), PieChart.Data('Apples', 30)) chart = PieChart(pieChartData) chart.setTitle('Imported Fruits') group = Group() group.getChildren().add(chart) scene = Scene(group) fxCanvas.setScene(scene)
def start(self, stage): root = GridPane() l = javafx.scene.control.Label("Talha") b = javafx.scene.control.Button("Press Me!") root.setAlignment(Pos.CENTER) root.addRow(0,l) root.addRow(1,b) scene = Scene( root, 640, 480 ) stage.setScene( scene ) stage.setTitle( "Hello, World" ) stage.show() b.setOnAction (self.buttonPressed)
def start(self, stage): from javafx.application import Platform self.ctrl = _window__ctrl_table self.stage = stage self.stage.setTitle("FxApp Example") if self.title: self.stage.setTitle(self.title) if self.icon: self.stage.getIcons().add(Image(FileInputStream(self.icon))) if self.closeHandler: self.stage.setOnCloseRequest(self.closeHandler) Platform.setImplicitExit(True) pane = EzBorderPane(self) self.scene = Scene(pane.ctrl, 640, 400) self.stage.setScene(self.scene) if self.createdHandler: self.createdHandler() self.stage.show()
def createAnimation(fxCanvas): circle = Circle(20, Color.CRIMSON) circle.setEffect(Lighting()) circle.setTranslateX(20) circle.setTranslateY(20) group = Group() group.getChildren().add(circle) translateTransition = TranslateTransitionBuilder.create()\ .duration(Duration.seconds(4)).node(circle).fromX(20).toX(380)\ .cycleCount(Timeline.INDEFINITE).autoReverse(True).build() translateTransition.play() scene = Scene(group) fxCanvas.setScene(scene)
def start(self, stage): stage.title = "Mosaiken" stage.width = 3 * self.size*self.stone_size stage.height = 3 * self.size*self.stone_size + 20 grid_pane = GridPane() for i in range(0, 9): self.graphics_canvas.append( Canvas(self.size, self.size) ) for i in range(0, 9): self.draw_Mosaic(self.decide_color_functions[i], i) grid_pane.add(self.graphics_canvas[i], i % 3, i//3) stage.setScene(Scene(grid_pane, 3 * self.size, 3 * self.size)) stage.show()
def start(self, stage): print('EzWindow.start()'); from javafx.application import Platform __vars.ctrl = _window__ctrl_table __vars.stage = stage if __vars.title: __vars.stage.setTitle(__vars.title) if __vars.icon: __vars.stage.getIcons().add(Image(FileInputStream(__vars.icon))) if __vars.closeHandler: __vars.stage.setOnCloseRequest(__vars.closeHandler) Platform.setImplicitExit(True) vbox = EzVBox() if __vars.menu: vbox.addItem(EzMenuBar(__vars.menu)) for m in __vars.tool: vbox.addItem(EzToolBar(m)) pane = EzBorderPane() if __vars.content: pane.setCenter(EzLayout(__vars.content,pane.ctrl)) pane.setTop(vbox.ctrl) pane.setBottom(EzStatusBar(__vars.status)) __vars.scene = Scene(pane.ctrl, __vars.width, __vars.height) __vars.stage.setScene(__vars.scene) if __vars.createdHandler: __vars.createdHandler() __vars.stage.show()
def start(self, primaryStage): primaryStage.setTitle("JythonFX Draw") root = StackPane() screen = javafx.stage.Screen.getPrimary() rect = screen.visualBounds canvas = Canvas(rect.width/2 + 50, rect.height/2 + 300) graphics_context = canvas.graphicsContext2D def resetAction(event): graphics_context.clearRect(1,1, graphics_context.canvas.width-2, graphics_context.canvas.height-2) def colorAction(newval): idx = newval.value if idx == 0: new_color = Color.BLACK elif idx == 1: new_color = Color.BLUE elif idx == 2: new_color = Color.RED elif idx == 3: new_color = Color.GREEN elif idx == 4: new_color = Color.BROWN elif idx == 5: new_color = Color.ORANGE else: new_color = Color.BLACK graphics_context.setStroke(new_color) def sizeAction(newval): idx = newval.value if idx == 0: graphics_context.lineWidth = 1 elif idx == 1: graphics_context.lineWidth = 2 elif idx == 2: graphics_context.lineWidth = 3 elif idx == 3: graphics_context.lineWidth = 4 elif idx == 4: graphics_context.lineWidth = 5 else: graphics_context.lineWidth = 1 resetButton = javafx.scene.control.Button( "Reset", onAction=resetAction) resetButton.translateX = 10 colorChooser = javafx.scene.control.ChoiceBox( FXCollections.observableArrayList( "Black", "Blue", "Red", "Green", "Brown", "Orange" )) cssm = colorChooser.selectionModel cssm.selectedIndexProperty().addListener(colorAction) sizeChooser = javafx.scene.control.ChoiceBox( FXCollections.observableArrayList ("1", "2", "3", "4", "5") ) scsm = sizeChooser.selectionModel scsm.selectedIndexProperty().addListener(sizeAction) def mouse_pressed(event): graphics_context.beginPath() graphics_context.moveTo(event.x, event.y) graphics_context.stroke() def mouse_dragged(event): graphics_context.lineTo(event.x, event.y) graphics_context.stroke() canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, mouse_pressed) canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, mouse_dragged) buttonBox = HBox() buttonBox.children.addAll(colorChooser, sizeChooser, resetButton) self.init_draw(graphics_context, canvas.layoutX, canvas.layoutY) container = BorderPane() container.top = buttonBox container.center = canvas root.children.add(container) scene = Scene(root, rect.height, rect.width) primaryStage.title = "JythonFX Draw" primaryStage.scene = scene primaryStage.show()
class BurpExtender(ITab, IBurpExtender): """The BurpExtender class which loads the extension into Burp Suite. Attributes: resourcePath (str): The absolute path to the `Resources` directory. elements dict(obj): All the initialized elements in the GUI. _listener (:class:`GraphWaveHttpListener`): The Burp Suite HTTP listener. _scene (:class:`javafx.scene.Scene`): The JavaFX scene loaded into the Burp Suite tab. shouldLoadConfigFromJson (bool): If the config should be loaded into Burp Suite (from the main thread). shouldRefreshInterface (bool): If the GUI should be updated using the currenct config (from the main thread). sliders list(obj): All the configurable options for the graph. """ resourcePath = os.path.dirname(os.path.abspath('__file__')) + "/Resources/" elements = {} _listener = None _scene = None shouldLoadConfigFromJson = False shouldRefreshInterface = False sliders = { "met": { "title": "Minimum edge threshold", "default": 15.0, "decimals": 0 }, "mct": { "title": "Matching points threshold", "default": 0.90, "decimals": 2 }, "mst": { "title": "Matching stylometry threshold", "default": 0.50, "decimals": 2 }, "upExactMatch": { "title": "Exact match (e.g. /*/somefolder/*/)", "default": 0.15, "decimals": 2 }, "upNumberMatch": { "title": "Number match (e.g. /*/[0-9]+/*/)", "default": 0.15, "decimals": 2 }, "upWordMatch": { "title": "Word match (e.g. /*/[A-Za-z]+/*/))", "default": 0.05, "decimals": 2 }, "upSlugMatch": { "title": "Slug match (e.g. /*/[A-Za-z0-9-_]+/*/)", "default": 0.02, "decimals": 2 }, "uqExactMatch": { "title": "Exact match (e.g. ?*=somematch)", "default": 0.05, "decimals": 2 }, "uqNumberMatch": { "title": "Number match (e.g. ?*=[0-9])", "default": 0.05, "decimals": 2 }, "uqWordMatch": { "title": "Word match (e.g. ?*=[A-Za-z])", "default": 0.05, "decimals": 2 }, "uqSlugMatch": { "title": "Slug match (e.g. ?*=[A-Za-z0-9-_])", "default": 0.02, "decimals": 2 } } def registerExtenderCallbacks(self, callbacks): """Register the Burp Suite extension. Args: callbacks (obj): The Burp Suite callbacks. """ ExtensionDetails.initialize() self._layout = JFXPanel() self._graph = GraphWave() self._config = GraphWaveConfig(callbacks) self._loadConfig = callbacks.loadConfigFromJson self._listener = GraphWaveHttpListener( self._config, self._graph, self.refreshInterface, callbacks.getHelpers() ) self.initializeInterface() self.burpThreadLooper() callbacks.addSuiteTab(self) callbacks.setExtensionName(ExtensionDetails.TITLE) callbacks.registerHttpListener(self._listener) def getTabCaption(self): """Get the title of the new tab in Burp Suite. Returns: (str): The title of our tab in Burp Suite. """ return ExtensionDetails.TITLE def getUiComponent(self): """Get the Java layout component for the tab (this is basically just the interface). Returns: (obj): Our JavaFX layout. """ return self._layout def burpThreadLooper(self): """This method runs every 0.5 seconds on the main Burp Suite thread and executes certain methods if the corresponding atomic booleans are positive.""" if self.shouldLoadConfigFromJson: self.shouldLoadConfigFromJson = False self._loadConfig(json.dumps(self._config.data)) if self.shouldRefreshInterface: self.shouldRefreshInterface = False Platform.runLater(ExtensionRunnable(self.refreshInterfaceFunc)) threading.Timer(0.5, self.burpThreadLooper).start() def loadConfigFromJson(self): """Start loading config from JSON in the main thread.""" self.shouldLoadConfigFromJson = True def refreshInterface(self): """Start refreshing the interface in the main thread.""" self.shouldRefreshInterface = True def refreshInterfaceFunc(self): """Show the current GraphWave config in the interface.""" if self._config.excludeList: similarText = "Similar: " + "\nSimilar: ".join(self._config.excludeList) self.elements["log"].setText(similarText) else: self.elements["log"].setText("") def initializeInterface(self): """Initialize the graphical user interface using JavaFX.""" fxml = File(self.resourcePath + "ExtensionTab.fxml") root = FXMLLoader.load(fxml.toURL()) self._scene = Scene(root) self._layout.setScene(self._scene) Platform.runLater(ExtensionRunnable(self.initializeElements)) def initializeElements(self): """Initialize all the elements in the interface with their default values and add listeners so they can be used by the user.""" self.elements["log"] = self._scene.lookup("#log") self.elements["logo"] = self._scene.lookup("#logo") self.elements["version"] = self._scene.lookup("#version") self.elements["status"] = self._scene.lookup("#status") self.elements["left"] = self._scene.lookup("#left") self.elements["right"] = self._scene.lookup("#right") self.elements["enabledCheckbox"] = self._scene.lookup("#enabledCheckbox") self.elements["enabledCheckboxLabel"] = self._scene.lookup("#enabledCheckboxLabel") # Menu self.initializeMenuElements() # Logo & version self.elements["logo"].setText(ExtensionDetails.TITLE) self.elements["version"].setText("Version " + ExtensionDetails.VERSION) # Status checkbox self.onEnabledChange("enabled", None, 0, False) self.elements["enabledCheckbox"].selectedProperty().addListener( ExtensionChangeListener(self.onEnabledChange, "enabled") ) # Sliders for key, value in self.sliders.items(): label = self._scene.lookup("#" + key + "Label") slider = self._scene.lookup("#" + key + "Slider") self.elements[key + "Label"] = label self.elements[key + "Slider"] = slider self.onSliderChange(key, None, 0, value["default"]) slider.valueProperty().setValue(value["default"]) slider.valueProperty().addListener( ExtensionChangeListener(self.onSliderChange, key) ) def onSliderChange(self, elementKey, observable, oldValue, newValue): """GUI slider change listener. Executed on the GUI thread. Args: elementKey (str): The name/key of the element that changed. observable (obj): The element that changed. oldValue (float): The previous slider value. newValue (float): The current slider value. """ label = self.elements[elementKey + "Label"] slider = self.elements[elementKey + "Slider"] title = self.sliders[elementKey]["title"] decimals = self.sliders[elementKey]["decimals"] value = ("{0:." + str(decimals) + "f}").format(newValue) label.setText(title + " (" + value + ")") self._graph.setOption(elementKey, newValue) def onEnabledChange(self, elementKey, observable, oldValue, isEnabled): """GUI slider change listener. Executed on the GUI thread. Args: elementKey (str): The name/key of the element that changed. observable (obj): The element that changed. oldValue (float): The previous checkbox value. newValue (float): The current checkbox value. """ self._listener.setEnabled(isEnabled) if isEnabled: self.elements["status"].setText("Status: " + ExtensionDetails.STATUS_ENABLED) self.elements["status"].setStyle("-fx-text-fill: #006600;") self.onResetClick(None) else: self.elements["status"].setText("Status: " + ExtensionDetails.STATUS_DISABLED) self.elements["status"].setStyle("-fx-text-fill: #cc0000;") self.shouldLoadConfigFromJson = True def initializeMenuElements(self): """Initialize the menu that is shown in the Burp Suite tab.""" from javafx.scene.control import Menu from javafx.scene.control import MenuBar from javafx.scene.control import MenuItem menuItems = {} # File menuFile = Menu("File") menuItems["ExportSimilar"] = MenuItem("Export similar URLs to file") menuItems["ExportUnique"] = MenuItem("Export unique URLs to file") menuFile.getItems().add(menuItems["ExportSimilar"]) menuFile.getItems().add(menuItems["ExportUnique"]) # Scope menuScope = Menu("Scope") menuItems["MarkOutOfScope"] = MenuItem("Mark similar requests as 'out of scope'") menuScope.getItems().add(menuItems["MarkOutOfScope"]) # Graph menuGraph = Menu("Graph") menuItems["Reset"] = MenuItem("Reset") menuGraph.getItems().add(menuItems["Reset"]) # Help menuHelp = Menu("Help") menuItems["Support"] = MenuItem("Support") menuItems["About"] = MenuItem("About") menuHelp.getItems().add(menuItems["Support"]) menuHelp.getItems().add(menuItems["About"]) menuBar = MenuBar() menuBar.getMenus().add(menuFile) menuBar.getMenus().add(menuScope) menuBar.getMenus().add(menuGraph) menuBar.getMenus().add(menuHelp) self.elements["right"].getChildren().add(0, menuBar) for (key, menuItem) in menuItems.items(): menuItem.setOnAction(getattr(self, "on" + key + "Click")) def onExportSimilarClick(self, event): """Export similar URLs to a TXT file. Args: event (obj): The Java on click event. """ fileChooser = FileChooser() fileChooser.getExtensionFilters().add( FileChooser.ExtensionFilter("TXT files (*.txt)", ["*.txt"]) ) chosenFile = fileChooser.showSaveDialog(None) if(chosenFile != None): chosenFile = open(chosenFile.getAbsolutePath(), "w") chosenFile.write("\n".join(self._config.excludeList)) chosenFile.close() def onExportUniqueClick(self, event): """Export unique URLs to a TXT file. Args: event (obj): The Java on click event. """ fileChooser = FileChooser() fileChooser.getExtensionFilters().add( FileChooser.ExtensionFilter("TXT files (*.txt)", ["*.txt"]) ) chosenFile = fileChooser.showSaveDialog(None) if(chosenFile != None): chosenFile = open(chosenFile.getAbsolutePath(), "w") chosenFile.write("\n".join(self._config.includeList)) chosenFile.close() def onMarkOutOfScopeClick(self, event): """Mark the similar URLs in the knowledge graph as 'out of scope' in Burp Suite. Args: event (obj): The Java on click event. """ self.shouldLoadConfigFromJson = True def onResetClick(self, event): """Reset the knowledge graph and reload the Burp Suite config into Python. Args: event (obj): The Java on click event. """ self._config.reset() self._graph.reset() self.shouldRefreshInterface = True def onSupportClick(self, event): """Open the support webpage of this extension. Args: event (obj): The Java on click event. """ Desktop.getDesktop().browse(URI("https://github.com/tijme/graphwave/issues")) def onAboutClick(self, event): """Open the about webpage of this extension. Args: event (obj): The Java on click event. """ Desktop.getDesktop().browse(URI("https://github.com/tijme/graphwave"))
def render(self): #Log print ("Log: Loading Flash Screen.....") #Add Splash to Collection of Stages self.browser.addStageToList(self.stage) #Consider Future Animation/Visual Effects, ie. Glow, Blur #Brighten Effect lighting = Lighting() light = Distant() light.setAzimuth(-135.0) lighting.setLight(light) lighting.setSurfaceScale(5.0) #Splash Stage Configuration self.stage.initStyle(StageStyle.UNDECORATED) self.stage.setAlwaysOnTop(True) self.stage.setResizable(False) self.stage.setTitle("Splash - EmeraldFX") #Splash Screen Root Pane SPLASH_ROOTP = VBox() SPLASH_SCENE_WIDTH = 633 SPLASH_SCENE_LENGTH = 240 SPLASH_ROOTP.setAlignment(Pos.CENTER) #Splash Screen's Scene SPLASH_SCENE = Scene(SPLASH_ROOTP, SPLASH_SCENE_WIDTH, SPLASH_SCENE_LENGTH) SPLASH_SCENE.setFill(Color.BLACK) self.stage.setScene(SPLASH_SCENE) ### Splash Screen's UI Elements ### #Set Effect on Splash Screen Image View self.SPLASH_IMAGE_VIEW.setEffect(lighting) #DropShadow shadow = DropShadow() shadow.setColor(Color.BLACK.saturate()) SPLASH_ROOTP.setEffect(shadow) #Fancy progress bar ;) self.progress_splash.setPrefWidth(SPLASH_SCENE_WIDTH-10) #Add UI Elements to Splash's Screen Root Pane SPLASH_ROOTP.getChildren().addAll(self.SPLASH_IMAGE_VIEW, self.progress_splash) #Splash Screen's Icon try: self.stage.getIcons().addAll(self.ICONS.get(0),self.ICONS.get(1),self.ICONS.get(2),self.ICONS.get(3),self.ICONS.get(4)) except NullPointerException: print("Log: The application's icon file could not be found.") #Fade Transition Configuration self.splash_fade.setNode(SPLASH_ROOTP) self.splash_fade2.setNode(SPLASH_ROOTP) self.splash_fade.setFromValue(0) self.splash_fade.setToValue(1.0) self.splash_fade2.setFromValue(1.0) self.splash_fade2.setToValue(0) #As soon as the stage pops up, play # splash.setOnShown(self.__CURRENT_TRACK.play() if self.__MUSIC_AUTO_PLAY else None) self.stage.setOnShown(lambda event: (self.CURRENT_TRACK.setAutoPlay(True) if self.MUSIC_AUTO_PLAY else None) )
def show(self): #Root Pane root = VBox() #FXML Loader fxmlLoader = FXMLLoader() #TextArea from javafx.scene.control import TextArea textArea = TextArea("Loading . . .") #Configure Text Area textArea.setEditable(False) textArea.setPrefHeight(600) #Bottom Bar, Current Stylesheet if self.app.getCurrentTheme() == "Dark": fxmlLoader.setLocation( File("../resources/fxml/history_url_tab_dark.fxml").toURI(). toURL()) #For some odd reason this is broken? bottom_bar = self.app.bottom_bar_dt elif self.app.getCurrentTheme() == "Light": fxmlLoader.setLocation( File("../resources/fxml/history_url_tab_light.fxml").toURI(). toURL()) bottom_bar = ImageView( Image( String( File('../resources/icons/bottom_bar_lt.png').toURI(). toString()), True)) #Think about future themes else: pass #URL Bar try: url_bar = fxmlLoader.load( ) #BROKEN - For some reason this breaks after a couple toggles. except LoadException as e: print('Log: Exception: An FXML Load Exception has occured.' + str(e.getCause())) #Add Children to root pane root.getChildren().addAll(url_bar, textArea, bottom_bar) #Fill Width, assume Theme of Main Stage root.setFillWidth(True) #Set scene, title scene = Scene(root, 1350, 625) #We are leaving the default controls for now. #Make sure the Text Area's scroll bar is always visible. scene.getStylesheets().add( File("../resources/themes/text-area_scroll-pane.css").toURI(). toString()) self.stage.setScene(scene) self.stage.setTitle("History - EmeraldFX") #Position History Stage self.stage.setX(self.app.getMainStage().getX()) self.stage.setY(self.app.getMainStage().getY() + 52) #Display History Stage self.stage.show() #It is CSV, let us display as plain text. history_csv = File("../resources/history/HISTORY.csv") history_txt = File("../resources/history/HISTORY.txt") #Delete text copy if it exists history_txt.delete() if history_txt.exists() else None #Copy Files.copy(history_csv.toPath(), history_txt.toPath()) #Prevent Resizing self.stage.setResizable(False) #Flush Stream self.BS.triggerHistoryWrite() #GetController instance controller = fxmlLoader.getController() ''' Failed Attempts ''' #WebView # webView = WebView() #Grab Web Engine # webEng = webView.getEngine() #Enable JS # webEng.setJavaScriptEnabled(True) #Attempt #1 - Start scrolling from the bottom - FAILED # webEng.executeScript("window.scrollTo(" + "0" + ", " + "600" + ");") #Attempt #2 - Scroll Pane - FAILED # from javafx.scene.control import ScrollPane # wv_scroll = ScrollPane() # wv_scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS) # wv_scroll.setContent(webView) # wv_scroll.setFitToWidth(True) # wv_scroll.setFitToHeight(True) # wv_scroll.setVvalue(wv_scroll.getVmin()) #Load History # try: # webEng.load(history_txt.toURI().toString()) # except Exception as e: # print ('Log: Load Exception: Error Loading History: ' + str(e.getCause())) # return #Attempt #3 - Execute Script for Scroll Bar - FAILD # webEng.executeScript( # "function scrollDown() { window.scrollTo(0,400); }" + # "scrollDown();" # ) #Set Position of Scroll Bar class AnonInnerCL_TA(ChangeListener): """Inner Class for Scrolling Down""" def __init__(self, textArea): self.textArea = textArea #@Override def changed(self, observable, old, new): if new > old: from java.lang import Double self.textArea.setScrollTop(Double.MAX_VALUE) else: pass textArea.textProperty().addListener(AnonInnerCL_TA(textArea)) #Show History after it is loaded if self.stage.isShowing( ): #May or may not be broken. If there is litle to no delay, "Loading . . ." will not be noticed. #Load History on separate thread. #Clear initial text: Loading . . . textArea.clear() #Instantate Service service = HistoryService(history_txt, textArea) #Algorithm improved. Start service service.start() '''Add resources to controller''' #Theme Resources controller.addThemeResources( self.app.getMainStage(), self.stage, self.app.getMainStage().getScene(), self.app.getCurrentTheme(), textArea ) #(Stage mainStage, Stage histStage, Scene scene, String theme, TextArea textArea) #Clear Resource controller.addClearResources(self.BS.isHistoryCleared()) #(boolean) #Quit Resources controller.addQuitResources( self.app.getAllStages(), self.BS.getHistoryWriter()) #(List<Stages>, PrintWriter) #Media Resources MMC = self.app.getMediaControls() controller.addMediaResources(MMC) #Create Bidirectional Bindings between Main Stage's media controls and history's controls from javafx.beans.binding import Bindings MMC_IT = MMC.listIterator() HMC = controller.getMediaControls() #Set history media controls to current state class HMCC(Consumer): def __init__(self, MMC_IT): self.MMC_IT = MMC_IT #@Override def accept(self, button): button.setDisabled(MMC_IT.next().isDisabled()) HMC.forEach(HMCC(MMC_IT)) #Fails - first arg cannot be coerced into Consumer? Odd. # history_media_controls.forEach(lambda button: button.setDisabled( main_media_controls.forEach(lambda button: button.isDisabled()) ) ) #Play #Won't work -- read only property does not inherit Property, seperate API. # Bindings.bindBidirectional(history_media_controls.get(0).disabledProperty(), main_media_controls[0].disabledProperty() ) #Stop # Bindings.bindBidirectional(history_media_controls.get(1).disabledProperty(), main_media_controls[1].disabledProperty() ) #Previous # Bindings.bindBidirectional(history_media_controls.get(2).disabledProperty(), main_media_controls[2].disabledProperty() ) #Next # Bindings.bindBidirectional(history_media_controls.get(3).disabledProperty(), main_media_controls[3].disabledProperty() ) #Shortcut Keys Allowed for History (CTRL + D, CTRL + Q, CTRL + T) scene.addEventFilter( KeyEvent.KEY_PRESSED, lambda event: self.handleHistoryShortcuts( event, self.BS, controller.getToggleTheme(), controller.getClearHistory())) #Python needs to fix lambdas so we don't have to resort to wrapping inner classes in collections. Yuck. class HistoryClosed: @staticmethod def printClosed(): print("Log: Quit Action: History just closed.") #Switch back to the main stage self.stage.setOnCloseRequest(lambda event: [ self.app.getMainStage().toFront(), self.stage.close(), HistoryClosed.printClosed() ]) #Log print('Log: History Notification: History data displayed @ ' + str(LocalDateTime.now()))
def show(self): from javafx.scene.control import CheckBox, Button #Make Stage always on top self.license_check_stage.setAlwaysOnTop(True) #Set Max Height/Width self.license_check_stage.setMaxWidth(900) self.license_check_stage.setMaxHeight(500) #Disallow resizing self.license_check_stage.setResizable(False) #Center on screen self.license_check_stage.centerOnScreen() #Get input focus self.license_check_stage.requestFocus() #Block Main Stage from recieving events! self.license_check_stage.initModality( Modality.APPLICATION_MODAL ) #Why is this not in setter bean notation? Hmm. #License Check self.license_check_stage.setTitle( "License Terms & Conditions - EmeraldFX") #License Answer Placeholder license_answer = str() #Buttons yes = CheckBox() no = CheckBox() enter = Button() #Grab, icon, graphics, button graphics try: self.license_check_stage.getIcons().addAll(self.icons.get(0), self.icons.get(1), self.icons.get(2), self.icons.get(3), self.icons.get(4)) license_graphic = ImageView( Image( String( File('../resources/icons/license.png').toURI(). toString()), True)) yes.setGraphic( ImageView( Image( String( File('../resources/icons/YES.png').toURI(). toString()), True))) no.setGraphic( ImageView( Image( String( File('../resources/icons/NO.png').toURI().toString( )), True))) enter.setGraphic( ImageView( Image( String( File('../resources/icons/GO.png').toURI().toString( )), True))) except NullPointerException: print( "Log: One or more Application resouce files could not be found." ) #Disallow Indeterminate yes.setAllowIndeterminate(False) no.setAllowIndeterminate(False) #Header if self.app.getCurrentTheme() == "Dark": top = ImageView( Image( File('../resources/icons/top_bar_license_dt.png').toURI(). toString())) elif self.app.getCurrentTheme() == "Light": top = ImageView( Image( File('../resources/icons/top_bar_license_lt.png').toURI(). toString())) #Middle middle = HBox(15) #Set up WebEngine license_webView = WebView() webEng = license_webView.getEngine() webEng.load(self.app._EmeraldFX__LICENSE) #License Image license_logo = VBox() license_logo.getChildren().add( ImageView( Image( String( File('../resources/icons/license.png').toURI(). toString()), True))) license_logo.setAlignment(Pos.CENTER) #Put it all together middle.getChildren().addAll(license_logo, license_webView) middle.setPadding(Insets(0, 10, 0, 10)) #CheckBox Grouping bottom = HBox() bottom.getChildren().addAll(yes, no, enter) bottom.setSpacing(50) bottom.setPadding(Insets(0, 0, 0, 200)) #Set Theme Accordingly try: if self.app.getCurrentTheme() == "Dark": BKG = File( '../resources/icons/bottom_bar_dt.png').toURI().toString() elif self.app.getCurrentTheme() == "Light": BKG = File( '../resources/icons/bottom_bar_lt.png').toURI().toString() else: pass except NullPointerException: print( "Log: One or more Application resouce files could not be found." ) #Footer background_bottom = Background( array(BackgroundImage, [ BackgroundImage(Image(BKG), BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT) ])) bottom.setBackground(background_bottom) bottom.setAlignment(Pos.CENTER) bottom.setPrefHeight(15) #Root Pane license_check_stage_root = VBox() license_check_stage_root.getChildren().addAll(top, middle, bottom) #Scene license_check_scene = Scene(license_check_stage_root, 895, 498) #Shortcuts not available for this scene. We will use defaults, for now. #Set Scene on Stage self.license_check_stage.setScene(license_check_scene) #Handle Selection class AnonInnerCL_E(EventHandler): def __init__(self, outer, yes, no): self.outer = outer self.app = outer.app self.BS = outer.BS self.YES = yes self.NO = no self.license_check_stage_json = self.app._EmeraldFX__config #@Override def handle(self, action): if (yes.isSelected()) ^ (no.isSelected()): if self.app._EmeraldFX__LICENSE_ACCEPTANCE == "YES": #We're done here self.outer.license_check_stage.close() #Update properties.json self.license_check_stage_json['license'][ 'value'] = "YES" #Write Data, close stream with open("../resources/config/properties.json", "w") as prop: json.dump(self.license_check_stage_json, prop) else: # checked == "NO": BrowserSession.closeHistoryWriter(self.BS) Thread.sleep(300) Platform.exit() class AnonInnerCL_Y(EventHandler): def __init__(self, YES, NO, ENTER, app): self.YES = YES self.NO = NO self.ENTER = ENTER self.app = app #@Override def handle(self, action): if self.YES.isSelected(): self.NO.setSelected(False) self.ENTER.setDisabled( False) if self.ENTER.isDisabled() else None self.app._EmeraldFX__LICENSE_ACCEPTANCE = "YES" elif not self.YES.isSelected() and not self.NO.isSelected(): self.ENTER.setDisabled(True) class AnonInnerCL_N(EventHandler): def __init__(self, NO, YES, ENTER, app): self.NO = NO self.YES = YES self.ENTER = ENTER self.app = app #@Override def handle(self, action): if self.NO.isSelected(): self.YES.setSelected(False) self.ENTER.setDisabled( False) if self.ENTER.isDisabled() else None self.app._EmeraldFX__LICENSE_ACCEPTANCE = "NO" elif not self.NO.isSelected() and not self.YES.isSelected(): self.ENTER.setDisabled(True) #Disable Enter by Default enter.setDisabled(True) #Enter hit enter.setOnAction(AnonInnerCL_E(self, yes, no)) #Yes Checked yes.setOnAction(AnonInnerCL_Y(yes, no, enter, self.app)) #No Checked no.setOnAction(AnonInnerCL_N(no, yes, enter, self.app)) #If they enter no selection, exit self.license_check_stage.setOnCloseRequest( lambda event: [BrowserSession.closeHistoryWriter(self.BS), Platform.exit()]) #Display stage self.license_check_stage.show()