/** * 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; }