List of usage examples for javafx.stage Stage getIcons
public final ObservableList<Image> getIcons()
From source file:eu.over9000.skadi.ui.MainWindow.java
@Override public void start(final Stage stage) throws Exception { this.stage = stage; this.detailPane = new ChannelDetailPane(this); this.bp = new BorderPane(); this.sp = new SplitPane(); this.sb = new StatusBar(); this.setupTable(); this.setupToolbar(stage); this.sp.getItems().add(this.table); this.bp.setTop(this.tb); this.bp.setCenter(this.sp); this.bp.setBottom(this.sb); final Scene scene = new Scene(this.bp, 1280, 720); scene.getStylesheets().add(this.getClass().getResource("/styles/copyable-label.css").toExternalForm()); scene.setOnDragOver(event -> {/* w w w . ja va 2s . co m*/ final Dragboard d = event.getDragboard(); if (d.hasUrl() || d.hasString()) { event.acceptTransferModes(TransferMode.COPY); } else { event.consume(); } }); scene.setOnDragDropped(event -> { final Dragboard d = event.getDragboard(); boolean success = false; if (d.hasUrl()) { final String user = StringUtil.extractUsernameFromURL(d.getUrl()); if (user != null) { success = this.channelHandler.addChannel(user, this.sb); } else { this.sb.setText("dragged url is no twitch stream"); } } else if (d.hasString()) { success = this.channelHandler.addChannel(d.getString(), this.sb); } event.setDropCompleted(success); event.consume(); }); stage.setTitle("Skadi"); stage.getIcons().add(new Image(this.getClass().getResourceAsStream("/icons/skadi.png"))); stage.setScene(scene); stage.show(); stage.iconifiedProperty().addListener((obs, oldV, newV) -> { if (this.currentState.isMinimizeToTray()) { if (newV) { stage.hide(); } } }); stage.setOnCloseRequest(event -> Platform.exit()); this.bindColumnWidths(); }
From source file:com.github.vatbub.tictactoe.view.Main.java
/** * The main entry point for all JavaFX applications. * The start method is called after the init method has returned, * and after the system is ready for the application to begin running. * <p>/*from www . j av a 2 s. c om*/ * NOTE: This method is called on the JavaFX Application Thread. * </p> * * @param primaryStage the primary stage for this application, onto which * the application scene can be set. The primary stage will be embedded in * the browser if the application was launched as an applet. * Applications may create other stages, if needed, but they will not be * primary stages and will not be embedded in the browser. */ @Override public void start(Stage primaryStage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("View.fxml")); Scene scene = new Scene(root); stage = primaryStage; primaryStage.setMinWidth(scene.getRoot().minWidth(0) + 70); primaryStage.setMinHeight(scene.getRoot().minHeight(0) + 70); primaryStage.setScene(scene); // Set Icon primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("icon.png"))); primaryStage.setTitle(getWindowTitle()); primaryStage.show(); }
From source file:de.mirkosertic.desktopsearch.DesktopSearch.java
@Override public void start(Stage aStage) throws Exception { // This is our base directory File theBaseDirectory = new File(SystemUtils.getUserHome(), "FreeSearchIndexDir"); theBaseDirectory.mkdirs();/* w ww. java2s . c om*/ configurationManager = new ConfigurationManager(theBaseDirectory); Notifier theNotifier = new Notifier(); stage = aStage; // Create the known preview processors PreviewProcessor thePreviewProcessor = new PreviewProcessor(); try { // Boot the search backend and set it up for listening to configuration changes backend = new Backend(theNotifier, configurationManager.getConfiguration(), thePreviewProcessor); configurationManager.addChangeListener(backend); // Boot embedded JSP container embeddedWebServer = new FrontendEmbeddedWebServer(aStage, backend, thePreviewProcessor, configurationManager); embeddedWebServer.start(); } catch (BindException | LockReleaseFailedException | LockObtainFailedException e) { // In this case, there is already an instance of DesktopSearch running // Inform the instance to bring it to front end terminate the current process. URL theURL = new URL(FrontendEmbeddedWebServer.getBringToFrontUrl()); // Retrieve the content, but it can be safely ignored // There must only be the get request Object theContent = theURL.getContent(); // Terminate the JVM. The window of the running instance is visible now. System.exit(0); } aStage.setTitle("Free Desktop Search"); aStage.setWidth(800); aStage.setHeight(600); aStage.initStyle(StageStyle.TRANSPARENT); FXMLLoader theLoader = new FXMLLoader(getClass().getResource("/scenes/mainscreen.fxml")); AnchorPane theMainScene = theLoader.load(); final DesktopSearchController theController = theLoader.getController(); theController.configure(this, backend, FrontendEmbeddedWebServer.getSearchUrl(), stage.getOwner()); Undecorator theUndecorator = new Undecorator(stage, theMainScene); theUndecorator.getStylesheets().add("/skin/undecorator.css"); Scene theScene = new Scene(theUndecorator); // Hacky, but works... theUndecorator.setStyle("-fx-background-color: rgba(0, 0, 0, 0);"); theScene.setFill(Color.TRANSPARENT); aStage.setScene(theScene); aStage.getIcons().add(new Image(getClass().getResourceAsStream("/fds.png"))); if (SystemTray.isSupported()) { Platform.setImplicitExit(false); SystemTray theTray = SystemTray.getSystemTray(); // We need to reformat the icon according to the current tray icon dimensions // this depends on the underlying OS java.awt.Image theTrayIconImage = Toolkit.getDefaultToolkit() .getImage(getClass().getResource("/fds_small.png")); int trayIconWidth = new TrayIcon(theTrayIconImage).getSize().width; TrayIcon theTrayIcon = new TrayIcon( theTrayIconImage.getScaledInstance(trayIconWidth, -1, java.awt.Image.SCALE_SMOOTH), "Free Desktop Search"); theTrayIcon.setImageAutoSize(true); theTrayIcon.setToolTip("FXDesktopSearch"); theTrayIcon.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 1) { Platform.runLater(() -> { if (stage.isIconified()) { stage.setIconified(false); } stage.show(); stage.toFront(); }); } } }); theTray.add(theTrayIcon); aStage.setOnCloseRequest(aEvent -> stage.hide()); } else { aStage.setOnCloseRequest(aEvent -> shutdown()); } aStage.setMaximized(true); aStage.show(); }
From source file:org.jevis.jeconfig.JEConfig.java
/** * Build an new JEConfig Login and main frame/stage * * @param primaryStage//from w ww . ja v a 2s.co m */ //@AITBilal - Dieses Method wird nirgendwo aufgerufen! private void buildGUI(Stage primaryStage) { try { LoginDialog loginD = new LoginDialog(); // ds = loginD.showSQL(primaryStage, _config.get<LoginIcon()); ds = loginD.showSQL(primaryStage);//Default // ds = loginD.showSQL(primaryStage, _config.getLoginIcon(), _config.getEnabledSSL(), _config.getShowServer(), _config.getDefaultServer());//KAUST // ds = loginD.showSQL(primaryStage, _config.getLoginIcon(), _config.getEnabledSSL(), _config.getShowServer(), _config.getDefaultServer());//Coffee // while (ds == null) { // Thread.sleep(100); // } // if (ds == null) { // System.exit(0); // } // System.exit(1); // ds = new JEVisDataSourceSQL("192.168.2.55", "3306", "jevis", "jevis", "jevistest", "Sys Admin", "jevis"); // ds.connect("Sys Admin", "jevis"); } catch (Exception ex) { Logger.getLogger(JEConfig.class.getName()).log(Level.SEVERE, null, ex); ExceptionDialog dia = new ExceptionDialog(); dia.show(primaryStage, "Error", "Could not connect to Server", ex, PROGRAMM_INFO); } _mainDS = ds; JEConfig.PROGRAMM_INFO.setJEVisAPI(ds.getInfo()); JEConfig.PROGRAMM_INFO.addLibrary(org.jevis.commons.application.Info.INFO); JEConfig.PROGRAMM_INFO.addLibrary(org.jevis.application.Info.INFO); PluginManager pMan = new PluginManager(ds); GlobalToolBar toolbar = new GlobalToolBar(pMan); pMan.addPluginsByUserSetting(null); StackPane root = new StackPane(); root.setId("mainpane"); BorderPane border = new BorderPane(); VBox vbox = new VBox(); vbox.getChildren().addAll(new TopMenu(), toolbar.ToolBarFactory()); border.setTop(vbox); border.setCenter(pMan.getView()); Statusbar statusBar = new Statusbar(ds); border.setBottom(statusBar); root.getChildren().addAll(border); Scene scene = new Scene(root, 300, 250); scene.getStylesheets().add("/styles/Styles.css"); primaryStage.getIcons().add(getImage("1393354629_Config-Tools.png")); primaryStage.setTitle("JEConfig"); primaryStage.setScene(scene); maximize(primaryStage); primaryStage.show(); try { // WelcomePage welcome = new WelcomePage(primaryStage, new URI("http://coffee-project.eu/")); // WelcomePage welcome = new WelcomePage(primaryStage, new URI("http://openjevis.org/projects/openjevis/wiki/JEConfig3#JEConfig-Version-3")); WelcomePage welcome = new WelcomePage(primaryStage, _config.getWelcomeURL()); } catch (URISyntaxException ex) { Logger.getLogger(JEConfig.class.getName()).log(Level.SEVERE, null, ex); } catch (MalformedURLException ex) { Logger.getLogger(JEConfig.class.getName()).log(Level.SEVERE, null, ex); } //Disable GUI is StatusBar note an disconnect root.disableProperty().bind(statusBar.connectedProperty.not()); primaryStage.onCloseRequestProperty().addListener(new ChangeListener<EventHandler<WindowEvent>>() { @Override public void changed(ObservableValue<? extends EventHandler<WindowEvent>> ov, EventHandler<WindowEvent> t, EventHandler<WindowEvent> t1) { try { System.out.println("Disconnect"); ds.disconnect(); } catch (JEVisException ex) { Logger.getLogger(JEConfig.class.getName()).log(Level.SEVERE, null, ex); } } }); }
From source file:io.bitsquare.app.gui.BitsquareApp.java
@Override public void start(Stage primaryStage) throws IOException { bitsquareAppModule = new BitsquareAppModule(env, primaryStage); injector = Guice.createInjector(bitsquareAppModule); injector.getInstance(GuiceControllerFactory.class).setInjector(injector); // route uncaught exceptions to a user-facing dialog Thread.currentThread().setUncaughtExceptionHandler( (thread, throwable) -> Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable))); // initialize the application data directory (if necessary) initAppDir(env.getRequiredProperty(APP_DATA_DIR_KEY)); // load and apply any stored settings User user = injector.getInstance(User.class); AccountSettings accountSettings = injector.getInstance(AccountSettings.class); Persistence persistence = injector.getInstance(Persistence.class); persistence.init();/* w w w.j a v a 2 s . c o m*/ User persistedUser = (User) persistence.read(user); user.applyPersistedUser(persistedUser); accountSettings.applyPersistedAccountSettings( (AccountSettings) persistence.read(accountSettings.getClass().getName())); // load the main view and create the main scene ViewLoader viewLoader = injector.getInstance(ViewLoader.class); ViewLoader.Item loaded = viewLoader.load(Navigation.Item.MAIN.getFxmlUrl(), false); Scene scene = new Scene((Parent) loaded.view, 1000, 600); scene.getStylesheets().setAll("/io/bitsquare/gui/bitsquare.css", "/io/bitsquare/gui/images.css"); // configure the system tray SystemTray systemTray = new SystemTray(primaryStage, this::stop); primaryStage.setOnCloseRequest(e -> stop()); scene.setOnKeyReleased(keyEvent -> { // For now we exit when closing/quit the app. // Later we will only hide the window (systemTray.hideStage()) and use the exit item in the system tray for // shut down. if (new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN).match(keyEvent) || new KeyCodeCombination(KeyCode.Q, KeyCombination.SHORTCUT_DOWN).match(keyEvent)) stop(); }); // configure the primary stage primaryStage.setTitle(env.getRequiredProperty(APP_NAME_KEY)); primaryStage.setScene(scene); primaryStage.setMinWidth(75); primaryStage.setMinHeight(50); // on windows the title icon is also used as task bar icon in a larger size // on Linux no title icon is supported but also a large task bar icon is derived form that title icon String iconPath; if (Utilities.isOSX()) iconPath = ImageUtil.isRetina() ? "/images/window_icon@2x.png" : "/images/window_icon.png"; else if (Utilities.isWindows()) iconPath = "/images/task_bar_icon_windows.png"; else iconPath = "/images/task_bar_icon_linux.png"; if (iconPath != null) primaryStage.getIcons().add(new Image(getClass().getResourceAsStream(iconPath))); // make the UI visible primaryStage.show(); }
From source file:poe.trade.assist.Main.java
@Override public void start(Stage stage) { // try { // fh = new FileHandler("D:\\MxDownload\\POE\\poe.trade.assist\\assist.log"); // } catch (IOException e) { // e.printStackTrace(); // }/*from www. j a va 2s .co m*/ // logger.addHandler(fh); // SimpleFormatter formatter = new SimpleFormatter(); // fh.setFormatter(formatter); // logger.info("Init application."); BorderPane root = new BorderPane(); config = Config.load(); config.get(Config.SEARCH_FILE).ifPresent(searchFileTextField::setText); searchFileTextField.setPromptText("Search CSV File URL or blank"); searchFileTextField.setTooltip(new Tooltip( "Any url to a valid poe.trade.assist CSV search file. Can be googlespreadsheet URL. If left blank, will load search.csv file instead")); searchFileTextField.setMinWidth(330); HBox.setHgrow(searchFileTextField, Priority.ALWAYS); List<Search> searchList = loadSearchListFromFile(); AutoSearchService autoSearchService = new AutoSearchService( Boolean.parseBoolean(config.get(Config.AUTO_ENABLE).get()), Float.parseFloat(config.get(Config.SEARCH_MINUTES).get())); searchPane = new SearchPane(searchList); resultPane = new ResultPane(searchFileTextField, this); autoSearchService.searchesProperty().bind(searchPane.dataProperty()); EventHandler<ActionEvent> reloadAction = e -> { System.out.println("Loading search file: " + searchFileTextField.getText()); List<Search> newList = loadSearchListFromFile(); searchPane.dataProperty().clear(); searchPane.dataProperty().addAll(newList); autoSearchService.restart(); if (searchPane.dataProperty().size() > 0) searchPane.searchTable.getSelectionModel().select(0); }; searchFileTextField.setOnAction(reloadAction); resultPane.loadButton.setOnAction(reloadAction); resultPane.defaultButton.setOnAction(e -> { searchFileTextField.setText(DEFAULT_SEARCH_CSV_FILE); resultPane.loadButton.fire(); }); resultPane.runNowButton.setOnAction(e -> autoSearchService.restart()); // autoSearchService.minsToSleepProperty().bind(resultPane.noOfMinsTextField.textProperty()); setupResultPaneBinding(searchPane, resultPane, autoSearchService); if (searchList.size() > 0) searchPane.searchTable.getSelectionModel().select(0); stage.setOnCloseRequest(we -> { saveSearchList(searchPane); config.setProperty(Config.SEARCH_FILE, searchFileTextField.getText()); config.setProperty(Config.SOUND_FILE, resultPane.soundButton.getUserData().toString()); config.save(); }); config.get(Config.SOUND_FILE).ifPresent(resultPane.soundButton::setUserData); autoSearchService.restart(); // HBox container = new HBox(5, searchPane, resultPane); SplitPane container = new SplitPane(searchPane, resultPane); container.setDividerPositions(0.1); HBox.setHgrow(searchPane, Priority.ALWAYS); HBox.setHgrow(resultPane, Priority.ALWAYS); container.setMaxWidth(Double.MAX_VALUE); // root.getChildren().addAll(container); root.setCenter(container); Scene scene = new Scene(root); stage.getIcons().add(new Image("/48px-Durian.png")); stage.titleProperty().bind(new SimpleStringProperty("poe.trade.assist v5 (Durian) - ") .concat(autoSearchService.messageProperty())); // stage.setWidth(1200); // stage.setHeight(550); stage.setMaximized(true); stage.setScene(scene); stage.show(); searchPane.searchTable.requestFocus(); }
From source file:snpviewer.SnpViewer.java
public void removeSamples(ActionEvent event) { FXMLLoader loader = new FXMLLoader(getClass().getResource("RemoveSamplesInterface.fxml")); try {/*from w w w. ja v a 2s . c o m*/ Pane pane = (Pane) loader.load(); RemoveSamplesInterfaceController removeController = (RemoveSamplesInterfaceController) loader .getController(); Scene scene = new Scene(pane); Stage stage = new Stage(); stage.setScene(scene); scene.getStylesheets().add(SnpViewer.class.getResource("SnpViewerStyleSheet.css").toExternalForm()); stage.getIcons().add(new Image(this.getClass().getResourceAsStream("icon.png"))); stage.setTitle("Remove Samples"); removeController.setSamples(affObserve, unObserve); stage.initModality(Modality.APPLICATION_MODAL); stage.showAndWait(); List<Integer> indicesToRemove = removeController.getSamplesToRemove(); //System.out.println(indicesToRemove.toString()); if (indicesToRemove.isEmpty()) { return; } ArrayList<Integer> affsToRemove = new ArrayList<>(); ArrayList<Integer> unsToRemove = new ArrayList<>(); for (Integer r : indicesToRemove) { if (r < affObserve.size()) {//index corresponds to affFiles affsToRemove.add(r); } else {//index corresponds to unFiles r -= affObserve.size(); unsToRemove.add(r); } } ArrayList<File> dirsToDelete = new ArrayList<>(); if (!affsToRemove.isEmpty()) { Collections.sort(affsToRemove, Collections.reverseOrder()); for (int i : affsToRemove) { dirsToDelete.add(affObserve.get(i).getOutputDirectory()); affObserve.remove(i); } } if (!unsToRemove.isEmpty()) { Collections.sort(unsToRemove, Collections.reverseOrder()); for (int i : unsToRemove) { dirsToDelete.add(unObserve.get(i).getOutputDirectory()); unObserve.remove(i); } } if (affObserve.isEmpty() && unObserve.isEmpty()) { resetView(); } else { refreshView(null, false); } saveProject(); for (File dir : dirsToDelete) { FileUtils.deleteDirectory(dir); } } catch (Exception ex) { Dialogs.showErrorDialog(null, "Sample removal failed - please see " + "details for stack trace and report this error.", "Remove Samples Failed!", "SnpViewer", ex); } }
From source file:snpviewer.SnpViewer.java
public void showSavedRegionsTable() { if (savedRegions.size() > 0) { FXMLLoader tableLoader = new FXMLLoader(getClass().getResource("MultiRegionReporter.fxml")); try {/*from w ww. j a va 2 s . c om*/ Pane tablePane = (Pane) tableLoader.load(); MultiRegionReporterController multiReg = (MultiRegionReporterController) tableLoader .getController(); Scene tableScene = new Scene(tablePane); Stage tableStage = new Stage(); tableStage.setScene(tableScene); tableScene.getStylesheets() .add(SnpViewer.class.getResource("SnpViewerStyleSheet.css").toExternalForm()); tableStage.getIcons().add(new Image(this.getClass().getResourceAsStream("icon.png"))); multiReg.displayData(savedRegions); tableStage.setTitle("Saved Regions"); tableStage.initModality(Modality.NONE); tableStage.show(); } catch (Exception ex) { Dialogs.showErrorDialog(null, "Error displaying" + " Saved Regions - see Details for stack trace.", "Saved Regions Display Error!", "SnpViewer", ex); } } else { Dialogs.showInformationDialog(null, "No regions " + "found.", "Saved Regions", "SnpViewer"); } }
From source file:snpviewer.SnpViewer.java
public void displayFlankingSnpIDs(final String chrom, final double start, final double end) { final Task<List<String>> displayTask = new Task<List<String>>() { @Override/*from w ww . j ava2s .c o m*/ protected List<String> call() { updateProgress(-1, -1); updateTitle("Finding flanking SNPs"); updateMessage("Searching for nearest SNP in all files..."); //work out coordinates based on chromosome and pane sizes /* read SnpFiles to find closest SNPs - use binary search * to find nearby SNP and refine to closest */ List<SnpFile.SnpLine> startAndEndSnps = searchCoordinate(chrom, (int) start, (int) end); if (startAndEndSnps == null) { //DISPLAY ERROR HERE? return null; } String coordResult = "chr" + chrom + ":" + nf.format(startAndEndSnps.get(0).getPosition()) + "-" + nf.format(startAndEndSnps.get(1).getPosition()); String idResult = startAndEndSnps.get(0).getId() + ";" + startAndEndSnps.get(1).getId(); List<String> result = new ArrayList(); result.add(coordResult); result.add(idResult); return result; } }; setProgressMode(true); progressBar.progressProperty().bind(displayTask.progressProperty()); progressMessage.textProperty().unbind(); progressMessage.textProperty().bind(displayTask.messageProperty()); progressTitle.textProperty().unbind(); progressTitle.textProperty().bind(displayTask.titleProperty()); displayTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() { @Override public void handle(WorkerStateEvent e) { setProgressMode(false); progressBar.progressProperty().unbind(); progressBar.progressProperty().set(0); progressTitle.textProperty().unbind(); progressMessage.textProperty().unbind(); progressTitle.setText(""); progressMessage.setText(""); } }); displayTask.setOnFailed(new EventHandler<WorkerStateEvent>() { @Override public void handle(WorkerStateEvent e) { setProgressMode(false); progressBar.progressProperty().unbind(); progressBar.progressProperty().set(0); progressTitle.textProperty().unbind(); progressMessage.textProperty().unbind(); progressTitle.setText(""); progressMessage.setText(""); Dialogs.showErrorDialog(null, "Error displaying flanking SNPs\n", "Display error", "SNP Viewer", displayTask.getException()); } }); displayTask.setOnCancelled(new EventHandler<WorkerStateEvent>() { @Override public void handle(WorkerStateEvent e) { progressMessage.setText("Display flanking SNPs cancelled"); setProgressMode(false); progressBar.progressProperty().unbind(); progressBar.progressProperty().set(0); progressTitle.textProperty().unbind(); progressMessage.textProperty().unbind(); progressTitle.setText(""); progressMessage.setText(""); Dialogs.showErrorDialog(null, "User cancelled display.", "Display error", "SNP Viewer", displayTask.getException()); } }); cancelButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent actionEvent) { displayTask.cancel(); } }); new Thread(displayTask).start(); try { List<String> result = displayTask.get(); FXMLLoader loader = new FXMLLoader(getClass().getResource("RegionReporter.fxml")); Stage stage = new Stage(); Pane page = (Pane) loader.load(); Scene scene = new Scene(page); stage.setScene(scene); stage.setTitle("SNP Viewer Region Summary"); stage.getIcons().add(new Image(this.getClass().getResourceAsStream("icon.png"))); RegionReporterController regionReporter = loader.<RegionReporterController>getController(); if (result == null) { regionReporter.setCoordinates("Error!"); regionReporter.setIds("Error!"); } else { regionReporter.setCoordinates(result.get(0)); regionReporter.setIds(result.get(1)); } scene.getStylesheets().add(SnpViewer.class.getResource("SnpViewerStyleSheet.css").toExternalForm()); stage.setResizable(false); stage.initModality(Modality.NONE); stage.show(); } catch (InterruptedException | ExecutionException | IOException ex) { Dialogs.showErrorDialog(null, "Can't display flanking SNP IDs" + " - exception caught!\n\nPlease report this error.", "Error!", "SNP Viewer", ex); } }
From source file:snpviewer.SnpViewer.java
public void showAbout(ActionEvent ev) { try {//from w w w .java2 s . co m FXMLLoader loader = new FXMLLoader(getClass().getResource("about.fxml")); Pane page = (Pane) loader.load(); Scene scene = new Scene(page); Stage stage = new Stage(); stage.setScene(scene); scene.getStylesheets().add(SnpViewer.class.getResource("SnpViewerStyleSheet.css").toExternalForm()); AboutController controller = loader.getController(); controller.setVersion(VERSION); stage.initModality(Modality.APPLICATION_MODAL); stage.getIcons().add(new Image(this.getClass().getResourceAsStream("icon.png"))); stage.setTitle("About SnpViewer"); stage.show(); } catch (Exception ex) { Dialogs.showErrorDialog(null, "Error showing about information - see" + " details for stack trace", "ERROR!", "SnpViewer", ex); } }