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