/** * Displays an information bubble pointing to an operator to indicate a {@link UserError} was * thrown by that operator. * * @param error the error instance * @param i18nKey the i18n key which defines the title, text and button label for the bubble. * Format is "gui.bubble.{i18nKey}.title", "gui.bubble.{i18nKey}.body" and * "gui.bubble.{i18nKey}.button.label". * @return the {@link OperatorInfoBubble} instance, never {@code null} */ private static OperatorInfoBubble displayGenericUserError( final UserError error, final String i18nKey) { final JButton ackButton = new JButton(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.label")); ackButton.setToolTipText(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.tip")); final BubbleDelegator bubbleDelegator = new BubbleDelegator(); final String message = removeTerminationCharacters(error.getMessage()); final JPanel linkPanel = new JPanel(); LinkButton showDetailsButton = new LinkButton( new ResourceAction(i18nKey + ".button_show_details") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(final ActionEvent e) { BubbleWindow bubble = bubbleDelegator.getBubble(); if (bubble != null) { String text = I18N.getMessage( I18N.getGUIBundle(), "gui.bubble." + i18nKey + ".body", message, error.getDetails()); bubble.setMainText(text); linkPanel.removeAll(); bubble.pack(); } } }); showDetailsButton.setToolTipText( I18N.getGUIMessage("gui.action." + i18nKey + ".button_show_details.tip")); linkPanel.add(showDetailsButton); OperatorBubbleBuilder builder = new OperatorBubbleBuilder( RapidMinerGUI.getMainFrame(), error.getOperator(), i18nKey, message, ""); // if no operator or root operator, show in middle, otherwise below AlignedSide prefSide = error.getOperator() == null || error.getOperator() instanceof ProcessRootOperator ? AlignedSide.MIDDLE : AlignedSide.BOTTOM; final OperatorInfoBubble userErrorBubble = builder .setHideOnDisable(true) .setAlignment(prefSide) .setStyle(BubbleStyle.ERROR) .setEnsureVisible(true) .hideCloseButton() .setHideOnProcessRun(true) .setAdditionalComponents(new JComponent[] {ackButton, linkPanel}) .build(); ackButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { userErrorBubble.killBubble(true); } }); bubbleDelegator.setBubbleWindow(userErrorBubble); userErrorBubble.setVisible(true); return userErrorBubble; }
/** * Displays a warning bubble that alerts the user that an input port of an operator expected input * but that there was a problem. The bubble is located at the port and the process view will * change to said port. execution. * * @param port the port for which to display the warning * @param i18nKey the i18n key which defines the title, text and button label for the bubble. * Format is "gui.bubble.{i18nKey}.title", "gui.bubble.{i18nKey}.body" and * "gui.bubble.{i18nKey}.button.label". * @param hideOnConnection if {@code true}, the bubble will be hidden once the port is connected * @param isError if {@code true}, an error bubble will be shown; otherwise a warning bubble is * displayed * @param arguments optional i18n arguments * @return the {@link PortInfoBubble} instance, never {@code null} */ private static PortInfoBubble displayPrecheckMissingInputPortWarning( final Port port, final boolean hideOnConnection, final boolean isError, final String i18nKey, final Object... arguments) { final BubbleDelegator bubbleDelegator = new BubbleDelegator(); ResourceAction runAnywayAction = new ResourceAction(i18nKey + ".button_run_anyway", "F11") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(final ActionEvent e) { BubbleWindow bubble = bubbleDelegator.getBubble(); if (bubble != null) { bubble.killBubble(true); } // run process without checking for problems RapidMinerGUI.getMainFrame().runProcess(false); } }; LinkButton runAnywayButton = new LinkButton(runAnywayAction); runAnywayButton.setToolTipText( I18N.getGUIMessage("gui.bubble." + i18nKey + ".button_run_anyway.tip")); runAnywayButton.registerKeyboardAction( runAnywayAction, KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); final JButton ackButton = new JButton(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.label", arguments)); ackButton.setToolTipText(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.tip")); PortBubbleBuilder builder = new PortBubbleBuilder(RapidMinerGUI.getMainFrame(), port, i18nKey, arguments); final PortInfoBubble missingInputBubble = builder .setHideOnConnection(hideOnConnection) .setHideOnDisable(true) .setAlignment(AlignedSide.LEFT) .setStyle(isError ? BubbleStyle.ERROR : BubbleStyle.WARNING) .setEnsureVisible(true) .hideCloseButton() .setHideOnProcessRun(true) .setAdditionalComponents(new JComponent[] {ackButton, runAnywayButton}) .build(); ackButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { missingInputBubble.killBubble(true); } }); bubbleDelegator.setBubbleWindow(missingInputBubble); missingInputBubble.setVisible(true); return missingInputBubble; }
/** * Displays an information bubble pointing to an ExecuteProcess operator to indicate a {@link * UserError} occurred inside the process executed by the operator. * * @param error the error instance * @param i18nKey the i18n key which defines the title, text and button label for the bubble. * Format is "gui.bubble.{i18nKey}.title", "gui.bubble.{i18nKey}.body" and * "gui.bubble.{i18nKey}.button.label". * @param arguments optional i18n arguments * @return the {@link OperatorInfoBubble} instance, never {@code null} */ private static OperatorInfoBubble displayUserErrorInExecutedProcess( final ProcessExecutionUserErrorError error, final String i18nKey, final Object... arguments) { final JButton ackButton = new JButton(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.label", arguments)); ackButton.setToolTipText(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.tip")); final BubbleDelegator bubbleDelegator = new BubbleDelegator(); LinkButton showDetailsButton = new LinkButton( new ResourceAction(i18nKey + ".button_show_details") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(final ActionEvent e) { if (RapidMinerGUI.getMainFrame().close(true)) { // kill bubble BubbleWindow bubble = bubbleDelegator.getBubble(); if (bubble != null) { bubble.killBubble(true); } // open process which caused the error Operator op = error.getUserError().getOperator(); final Process causingProcess = op.getProcess(); RapidMinerGUI.getMainFrame() .setOpenedProcess( causingProcess, false, causingProcess.getProcessLocation().toString()); // show new error bubble in the newly opened process displayBubbleForUserError(error.getUserError()); } } }); showDetailsButton.setToolTipText( I18N.getGUIMessage("gui.action." + i18nKey + ".button_show_details.tip")); OperatorBubbleBuilder builder = new OperatorBubbleBuilder( RapidMinerGUI.getMainFrame(), error.getOperator(), i18nKey, arguments); final OperatorInfoBubble userErrorBubble = builder .setHideOnDisable(true) .setHideOnProcessRun(true) .setAlignment(AlignedSide.BOTTOM) .setStyle(BubbleStyle.ERROR) .setEnsureVisible(true) .hideCloseButton() .setHideOnProcessRun(true) .setAdditionalComponents(new JComponent[] {ackButton, showDetailsButton}) .build(); ackButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { userErrorBubble.killBubble(true); } }); bubbleDelegator.setBubbleWindow(userErrorBubble); userErrorBubble.setVisible(true); return userErrorBubble; }
/** * Displays a warning bubble that alerts the user that he failed to connect any of the process * result ports. * * <p>The bubble is located at the first result port of the outermost process and the process view * will change to said port. The {@link ResultWarningPreventionRegistry} contains a list with * Operators which can suppress this warning. * * @param process the process in question * @return the {@link PortInfoBubble} instance, never {@code null} */ public static PortInfoBubble displayPrecheckNoResultPortInformation(final Process process) { if (process == null) { throw new IllegalArgumentException("port must not be null!"); } Port firstResultPort = process.getRootOperator().getSubprocess(0).getInnerSinks().getPortByIndex(0); JButton ackButton = new JButton(I18N.getGUIMessage("gui.bubble.process_unconnected_result_port.button.label")); ackButton.setToolTipText( I18N.getGUIMessage("gui.bubble.process_unconnected_result_port.button.tip")); final BubbleDelegator bubbleDelegator = new BubbleDelegator(); ResourceAction runAnywayAction = new ResourceAction("process_unconnected_result_port.button_run_anyway", "F11") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(final ActionEvent e) { BubbleWindow bubble = bubbleDelegator.getBubble(); if (bubble != null) { bubble.killBubble(true); } // run process without checking for problems RapidMinerGUI.getMainFrame().runProcess(false); } }; LinkButton runAnywayButton = new LinkButton(runAnywayAction); runAnywayButton.setToolTipText( I18N.getGUIMessage("gui.bubble.process_unconnected_result_port.button_run_anyway.tip")); runAnywayButton.registerKeyboardAction( runAnywayAction, KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); PortBubbleBuilder builder = new PortBubbleBuilder( RapidMinerGUI.getMainFrame(), firstResultPort, "process_unconnected_result_port"); final PortInfoBubble noResultConnectionBubble = builder .setHideOnConnection(true) .setAlignment(AlignedSide.LEFT) .setStyle(BubbleStyle.WARNING) .setHideOnProcessRun(false) .setEnsureVisible(true) .hideCloseButton() .setAdditionalComponents(new JComponent[] {ackButton, runAnywayButton}) .build(); ackButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { noResultConnectionBubble.killBubble(true); } }); bubbleDelegator.setBubbleWindow(noResultConnectionBubble); noResultConnectionBubble.setVisible(true); return noResultConnectionBubble; }
/** * Displays an information bubble pointing to a port to indicate a {@link PortUserError} was * thrown. * * @param error the error instance * @param i18nKey the i18n key which defines the title, text and button label for the bubble. * Format is "gui.bubble.{i18nKey}.title", "gui.bubble.{i18nKey}.body" and * "gui.bubble.{i18nKey}.button.label". * @return the {@link PortInfoBubble} instance, never {@code null} */ private static PortInfoBubble displayGenericPortError( final PortUserError error, final String i18nKey) { final JButton ackButton = new JButton(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.label")); ackButton.setToolTipText(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.tip")); final BubbleDelegator bubbleDelegator = new BubbleDelegator(); final String message = removeTerminationCharacters(error.getMessage()); final JPanel linkPanel = new JPanel(); LinkButton showDetailsButton = new LinkButton( new ResourceAction(i18nKey + ".button_show_details") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(final ActionEvent e) { BubbleWindow bubble = bubbleDelegator.getBubble(); if (bubble != null) { String text = I18N.getMessage( I18N.getGUIBundle(), "gui.bubble." + i18nKey + ".body", message, error.getDetails()); bubble.setMainText(text); linkPanel.removeAll(); bubble.pack(); } } }); showDetailsButton.setToolTipText( I18N.getGUIMessage("gui.action." + i18nKey + ".button_show_details.tip")); linkPanel.add(showDetailsButton); // input ports (located left) show the "hook" of the bubble on the left and vice versa AlignedSide prefSide = error.getPort() instanceof InputPort ? AlignedSide.LEFT : AlignedSide.RIGHT; PortBubbleBuilder builder = new PortBubbleBuilder(RapidMinerGUI.getMainFrame(), error.getPort(), i18nKey, message, ""); final PortInfoBubble portErrorBubble = builder .setHideOnDisable(true) .setAlignment(prefSide) .setStyle(BubbleStyle.ERROR) .setEnsureVisible(true) .hideCloseButton() .setHideOnProcessRun(true) .setAdditionalComponents(new JComponent[] {ackButton, linkPanel}) .build(); ackButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { portErrorBubble.killBubble(true); } }); bubbleDelegator.setBubbleWindow(portErrorBubble); portErrorBubble.setVisible(true); return portErrorBubble; }