public ResourceCard(String key, String i18nKey) { this.key = key; String titleName = I18N.getGUIMessageOrNull("gui.cards." + i18nKey + ".title"); if (titleName != null) { this.title = "<html><div style=\"text-align: center;\"><body>" + titleName.replaceFirst(" ", "<br>") + "</html></body>"; this.tip = I18N.getGUIMessage("gui.cards." + i18nKey + ".tip"); } else { // default case if no name and icon are defined: key = key.replace("_", " "); char[] stringArray = key.toCharArray(); stringArray[0] = Character.toUpperCase(stringArray[0]); String defaultName = new String(stringArray); this.title = "<html><div style=\"text-align: center;\"><body>" + defaultName.replaceFirst(" ", "<br>") + "</html></body>"; this.tip = defaultName; } String iconName = I18N.getGUIMessageOrNull("gui.cards." + i18nKey + ".icon"); if (iconName != null) { this.icon = SwingTools.createIcon("32/" + iconName); } else { this.icon = SwingTools.createIcon("32/data_information.png"); // default icon } }
private void calculateANOVA() throws SignificanceCalculationException { double alpha = -1; String alphaString = alphaField.getText(); try { alpha = Double.parseDouble(alphaString); } catch (NumberFormatException e) { SwingTools.showVerySimpleErrorMessage("Significance level must be a number between 0 and 1."); } if ((alpha < 0) || (alpha > 1)) { SwingTools.showVerySimpleErrorMessage("Significance level must be a number between 0 and 1."); } else { this.calculator.clearGroups(); this.calculator.setAlpha(alpha); for (int i = 0; i < tableModel.getRowCount(); i++) { int number = ((Integer) tableModel.getValueAt(i, 2)).intValue(); double mean = ((Double) tableModel.getValueAt(i, 0)).doubleValue(); double variance = ((Double) tableModel.getValueAt(i, 1)).doubleValue(); calculator.addGroup(number, mean, variance); } if (tableModel.getRowCount() < 2) { SwingTools.showVerySimpleErrorMessage( "You need to add at least two rows in order to calculate an ANOVA test."); return; } SignificanceTestResult result = calculator.performSignificanceTest(); JOptionPane.showMessageDialog( this, result.getVisualizationComponent(null), "ANOVA result", JOptionPane.PLAIN_MESSAGE); } }
public void actionPerformed(ActionEvent e) { Operator selectedOperator = this.actions.getSelectedOperator(); if (selectedOperator != null) { NewBuildingBlockDialog dialog = new NewBuildingBlockDialog(); dialog.setVisible(true); if (dialog.isOk()) { try { BuildingBlock buildingBlock = dialog.getSelectedBuildingBlock(); if (buildingBlock != null) { String xmlDescription = buildingBlock.getXML(); try { InputSource source = new InputSource(new StringReader(xmlDescription)); Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); Element element = document.getDocumentElement(); Operator operator = Operator.createFromXML( element, actions.getProcess(), new LinkedList<UnknownParameterInformation>(), null, XMLImporter.CURRENT_VERSION); operator.setUserDescription(buildingBlock.getDescription()); actions.insert(Collections.singletonList(operator)); } catch (Exception ex) { SwingTools.showSimpleErrorMessage( "cannot_instantiate_building_block", ex, buildingBlock.getName()); } } } catch (Exception ex) { SwingTools.showSimpleErrorMessage("cannot_instantiate_building_block", ex); } } } }
@Override public void actionPerformed(ActionEvent e) { String loc = RepositoryLocationChooser.selectLocation( lastLocation, "", RapidMinerGUI.getMainFrame(), true, false, true, true, true); if (loc != null) { RepositoryLocation location; try { location = new RepositoryLocation(loc); } catch (Exception ex) { SwingTools.showSimpleErrorMessage("malformed_rep_location", ex, loc); return; } try { if (location.locateEntry() != null) { // overwrite? if (SwingTools.showConfirmDialog("overwrite", ConfirmDialog.YES_NO_OPTION, location) != ConfirmDialog.YES_OPTION) { return; } } RepositoryManager.getInstance(null).store(object, location, null); lastLocation = location; } catch (RepositoryException ex) { SwingTools.showSimpleErrorMessage("cannot_store_obj_at_location", ex, loc); } } }
private void load() { File file = SwingTools.chooseFile(null, null, true, "wgt", "attribute weight file"); try { AttributeWeights fileWeights = AttributeWeights.load(file); attributeTableModel.mergeWeights(fileWeights); } catch (IOException e) { SwingTools.showSimpleErrorMessage("cannot_load_attr_weights_from_file", e, file.getName()); } update(); }
private void save() { File file = SwingTools.chooseFile(null, null, true, "wgt", "attribute weight file"); try { attributeTableModel .getAttributeWeights() .writeAttributeWeights(file, Tools.getDefaultEncoding()); } catch (IOException e) { SwingTools.showSimpleErrorMessage("cannot_write_attr_weights_to_file", e, file.getName()); } }
/** @author Sebastian Land */ public class CollectionTreeCellRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = 1L; private final Icon ICON_FOLDER_OPEN = SwingTools.createIcon("16/folder.png"); private final Icon ICON_FOLDER_CLOSED = SwingTools.createIcon("16/folder_closed.png"); private final Map<IOObject, String> childNames = new HashMap<IOObject, String>(); public CollectionTreeCellRenderer(IOObject collection) { if (collection instanceof MetaModel) { MetaModel mm = (MetaModel) collection; for (int i = 0; i < mm.getModels().size(); i++) { childNames.put(mm.getModels().get(i), mm.getModelNames().get(i)); } } } @Override public Component getTreeCellRendererComponent( JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { JLabel label = (JLabel) super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, hasFocus); if (value instanceof ResultObject) { ResultObject ro = (ResultObject) value; String name = childNames.get(ro); if (name == null) { name = ro.getName(); } label.setText("<html>" + name + " (<small>" + ro.getSource() + "</small>)</html>"); if (ro instanceof IOObjectCollection) { label.setIcon(expanded ? ICON_FOLDER_OPEN : ICON_FOLDER_CLOSED); } else { Icon resultIcon = ro.getResultIcon(); label.setIcon(resultIcon); } } else if (value instanceof IOObject) { IOObject ioo = (IOObject) value; label.setText(ioo.getClass().getSimpleName()); } return label; } }
private void overwriteProcess(final ProcessEntry processEntry) { if (SwingTools.showConfirmDialog( "overwrite", ConfirmDialog.YES_NO_OPTION, processEntry.getLocation()) == ConfirmDialog.YES_OPTION) { ProgressThread storeProgressThread = new ProgressThread("store_process") { @Override public void run() { getProgressListener().setTotal(100); getProgressListener().setCompleted(10); try { Process process = RapidMinerGUI.getMainFrame().getProcess(); process.setProcessLocation( new RepositoryProcessLocation(processEntry.getLocation())); processEntry.storeXML(process.getRootOperator().getXML(false)); RapidMinerGUI.addToRecentFiles(process.getProcessLocation()); RapidMinerGUI.getMainFrame().processHasBeenSaved(); } catch (Exception e) { SwingTools.showSimpleErrorMessage( "cannot_store_process_in_repository", e, processEntry.getName()); } finally { getProgressListener().setCompleted(100); getProgressListener().complete(); } } }; storeProgressThread.start(); } }
@Override public void valueForPathChanged(TreePath path, Object newValue) { try { ((Entry) path.getLastPathComponent()).rename(newValue.toString()); } catch (Exception e) { SwingTools.showSimpleErrorMessage("error_rename", e, e.toString()); } }
@Override public void save(BlobEntry entry) { try { save(entry.openOutputStream(LIBRARY_MIME_TYPE)); } catch (RepositoryException e) { SwingTools.showSimpleErrorMessage("cannot_access_repository", e); } }
@Override protected void ok() { try { chooser.getRepositoryLocation(); super.ok(); } catch (MalformedRepositoryLocationException e) { SwingTools.showSimpleErrorMessage("malformed_repository_location", e, e.getMessage()); } }
@Override public void createConfigurationWizard(ParameterType type, ConfigurationListener listener) { ExcelExampleSource sourceOperator = (ExcelExampleSource) listener; try { new ExcelImportWizard(sourceOperator, listener, null).setVisible(true); } catch (OperatorException e) { SwingTools.showSimpleErrorMessage("importwizard.error_creating_wizard", e); } }
@Override public void performAction(OperatorDescription description) { try { Operator operator = OperatorService.createOperator(description); RapidMinerGUI.getMainFrame().getActions().insert(Collections.singletonList(operator)); } catch (Exception e) { SwingTools.showSimpleErrorMessage("cannot_instantiate", e, description.getName()); } }
@Override public void apply() { RepositoryLocation absLoc; try { absLoc = operator.getParameterAsRepositoryLocation(key); final RepositoryLocation processLoc = operator.getProcess().getRepositoryLocation().parent(); if (processLoc == null) { SwingTools.showVerySimpleErrorMessage( "quickfix_failed", "Process is not stored in repository."); } else { String relative = absLoc.makeRelative(processLoc); operator.setParameter(key, relative); } } catch (UserError e) { // Should not happen. Parameter should be set, otherwise we would not have created this // prefix. SwingTools.showVerySimpleErrorMessage("quickfix_failed", e.toString()); } }
/** * Enables and disables all actions according to the current state (process running, operator * selected... */ public void enableActions() { synchronized (process) { SwingTools.invokeLater( new Runnable() { @Override public void run() { enableActionsNow(); } }); } updateCheckboxStates(); }
public void drawOperator(Operator op, Graphics2D g) { Dimension d = getSize(op, g); g.setPaint(SwingTools.makeBluePaint(d.getWidth(), d.getHeight())); g.fillRect(0, 0, (int) d.getWidth(), (int) d.getHeight()); g.setPaint(Color.black); g.setStroke(new BasicStroke(3)); g.drawRect(0, 0, (int) d.getWidth(), (int) d.getHeight()); Graphics2D g2 = (Graphics2D) g.create(); g2.translate(BORDER, BORDER); drawName(op, g2); g2.dispose(); }
@Override public void actionPerformed(ActionEvent e) { File file = SwingTools.chooseFile( RapidMinerGUI.getMainFrame(), "export_process", null, false, false, new String[] {RapidMiner.PROCESS_FILE_EXTENSION, "xml"}, new String[] {"Process File", "Process File"}); if (file == null) { return; } try { new FileProcessLocation(file).store(RapidMinerGUI.getMainFrame().getProcess(), null); } catch (IOException e1) { SwingTools.showSimpleErrorMessage( "cannot_save_process", e1, RapidMinerGUI.getMainFrame().getProcess().getProcessLocation(), e1.getMessage()); } }
@Override public void actionPerformed(ActionEvent e) { File file = SwingTools.chooseFile( RapidMinerGUI.getMainFrame(), "import_process", null, true, false, new String[] {RapidMiner.PROCESS_FILE_EXTENSION, "xml"}, new String[] {"Process File", "Process File"}); if (file == null) { return; } open(file); }
/** * The given operators will be inserted at the last position of the currently selected operator * chain. */ public void insert(List<Operator> newOperators) { Object selectedNode = getSelectedOperator(); if (selectedNode == null) { SwingTools.showVerySimpleErrorMessage("cannot_insert_operator"); return; } else if (mainFrame.getProcessPanel().getProcessRenderer().getModel().getDisplayedChain() == selectedNode) { for (Operator newOperator : newOperators) { int index = mainFrame .getProcessPanel() .getProcessRenderer() .getProcessIndexUnder( mainFrame .getProcessPanel() .getProcessRenderer() .getModel() .getCurrentMousePosition()); if (index == -1) { index = 0; } ((OperatorChain) selectedNode).getSubprocess(index).addOperator(newOperator); } } else { int i = 0; Operator selectedOperator = (Operator) selectedNode; ExecutionUnit process = selectedOperator.getExecutionUnit(); int parentIndex = process.getOperators().indexOf(selectedOperator) + 1; for (Operator newOperator : newOperators) { process.addOperator(newOperator, parentIndex + i); i++; } } AutoWireThread.autoWireInBackground(newOperators, true); mainFrame.selectOperators(newOperators); }
@Override public String getVertexToolTip(String object) { Tree tree = vertexMap.get(object); if (tree != null) { StringBuffer result = new StringBuffer(); if (tree.isLeaf()) { String labelString = tree.getLabel(); if (labelString != null) { result.append("<html><b>Class:</b> " + labelString + "<br>"); result.append("<b>Size:</b> " + tree.getFrequencySum() + "<br>"); result.append( "<b>Class frequencies:</b> " + SwingTools.transformToolTipText(tree.getCounterMap().toString()) + "</html>"); } } else { result.append( "<html><b>Subtree Size:</b> " + tree.getSubtreeFrequencySum() + "</html>"); } return result.toString(); } else { return null; } }
/** * This class handles event hooks and draw decorators registered to the {@link ProcessRendererView} * for workflow annotations. * * @author Marco Boeck * @since 6.4.0 */ public final class AnnotationsDecorator { /** name of the paste action (context menu) */ private static final String PASTE_ACTION_NAME = "paste"; /** name of the paste from clipboard action (ctrl+v) */ private static final String PASTE_FROM_CLIPBOARD_ACTION_NAME = DefaultEditorKit.pasteAction; /** icon depicting annotations on an operator */ private static final ImageIcon IMAGE_ANNOTATION = SwingTools.createIcon("16/note_pinned.png"); /** the width of the edit panel above/below the annotation editor */ private static final int EDIT_PANEL_WIDTH = 190; /** the height of the edit panel above/below the annotation editor */ private static final int EDIT_PANEL_HEIGHT = 30; /** the width of the color panel above/below the annotation editor */ private static final int EDIT_COLOR_PANEL_WIDTH = 215; /** the height of the color panel above/below the annotation editor */ private static final int EDIT_COLOR_PANEL_HEIGHT = EDIT_PANEL_HEIGHT; /** the pane which can be used to edit the text */ private JEditorPane editPane; /** the panel which can be used to edit color and alignment during editing */ private JPanel editPanel; /** the dialog panel which can be used to edit color while editing */ private JDialog colorOverlay; /** the button opening the color overlay */ private JButton colorButton; /** the process renderer */ private final ProcessRendererView view; /** the process renderer model */ private final ProcessRendererModel rendererModel; /** the annotation visualizer instance */ private final AnnotationsVisualizer visualizer; /** the model backing this decorator */ private final AnnotationsModel model; /** the drawer for the annotations */ private final AnnotationDrawer drawer; /** the event handling for annotations */ private final AnnotationEventHook hook; /** draws process (free-flowing) annotations behind operators */ private ProcessDrawDecorator processAnnotationDrawer = new ProcessDrawDecorator() { @Override public void draw( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, false); } @Override public void print( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, true); } /** Draws the background annoations. */ private void draw( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel, final boolean printing) { if (!visualizer.isActive()) { return; } // background annotations WorkflowAnnotations annotations = rendererModel.getProcessAnnotations(process); if (annotations != null) { for (WorkflowAnnotation anno : annotations.getAnnotationsDrawOrder()) { // selected is drawn by highlight decorator if (anno.equals(model.getSelected())) { continue; } // paint the annotation itself Graphics2D g2P = (Graphics2D) g2.create(); drawer.drawAnnotation(anno, g2P, printing); g2P.dispose(); } } } }; /** draws operator annotations */ private ProcessDrawDecorator operatorAnnotationDrawer = new ProcessDrawDecorator() { @Override public void draw( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, false); } @Override public void print( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, true); } /** Draws the operator annoations. */ private void draw( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel, final boolean printing) { if (!visualizer.isActive()) { return; } // operator attached annotations List<Operator> selectedOperators = rendererModel.getSelectedOperators(); for (Operator operator : process.getOperators()) { if (selectedOperators.contains(operator)) { continue; } drawOpAnno(operator, g2, rendererModel, printing); } // selected operators annotations need to be drawn over non selected ones for (Operator selOp : selectedOperators) { if (process.equals(selOp.getExecutionUnit())) { drawOpAnno(selOp, g2, rendererModel, printing); } } } /** Draws the annotation for the given operator (if he has one). */ private void drawOpAnno( final Operator operator, final Graphics2D g2, final ProcessRendererModel rendererModel, final boolean printing) { WorkflowAnnotations annotations = rendererModel.getOperatorAnnotations(operator); if (annotations == null) { return; } for (WorkflowAnnotation anno : annotations.getAnnotationsDrawOrder()) { // selected is drawn by highlight decorator if (anno.equals(model.getSelected())) { continue; } // paint the annotation itself Graphics2D g2P = (Graphics2D) g2.create(); drawer.drawAnnotation(anno, g2P, printing); g2P.dispose(); } } }; /** draws process (free-flowing) annotations which are selected. Drawn over operators */ private ProcessDrawDecorator workflowAnnotationDrawerHighlight = new ProcessDrawDecorator() { @Override public void draw( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(process, g2, rendererModel, false); } @Override public void print(ExecutionUnit process, Graphics2D g2, ProcessRendererModel model) { draw(process, g2, rendererModel, true); } /** Draws the selected annotation. */ private void draw( final ExecutionUnit process, final Graphics2D g2, final ProcessRendererModel rendererModel, final boolean printing) { if (!visualizer.isActive()) { return; } // paint the selected annotation WorkflowAnnotation selected = model.getSelected(); if (selected != null) { // only draw in correct execution unit if (selected.getProcess().equals(process)) { // only paint annotation if not editing if (editPane == null) { // paint the annotation itself Graphics2D g2P = (Graphics2D) g2.create(); drawer.drawAnnotation(selected, g2P, printing); g2P.dispose(); } else { // only paint shadow Rectangle2D loc = selected.getLocation(); g2.draw( new Rectangle2D.Double( loc.getX() - 1, loc.getY() - 1, editPane.getBounds().getWidth() + 1, editPane.getBounds().getHeight() + 1)); Rectangle2D shadowFrameEditor = new Rectangle2D.Double( loc.getX(), loc.getY(), editPane.getBounds().getWidth() + 1, editPane.getBounds().getHeight() + 1); ProcessDrawUtils.drawShadow(shadowFrameEditor, g2); if (editPanel != null) { Point absolute = new Point(editPanel.getX(), editPanel.getY()); Point relative = ProcessDrawUtils.convertToRelativePoint( absolute, rendererModel.getProcessIndex(process), rendererModel); Rectangle2D shadowFramePanel = new Rectangle2D.Double( relative.getX(), relative.getY(), EDIT_PANEL_WIDTH, EDIT_PANEL_HEIGHT); ProcessDrawUtils.drawShadow(shadowFramePanel, g2); } } } } } }; /** draws annotation icons on operators */ private OperatorDrawDecorator opAnnotationIconDrawer = new OperatorDrawDecorator() { @Override public void draw( final Operator operator, final Graphics2D g2, final ProcessRendererModel rendererModel) { draw(operator, g2, rendererModel, true); } @Override public void print(Operator operator, Graphics2D g2, ProcessRendererModel model) { draw(operator, g2, rendererModel, true); } /** Draws the annotation icon on operators. */ private void draw( final Operator operator, final Graphics2D g2, final ProcessRendererModel rendererModel, final boolean printing) { // Draw annotation icons regardless of active state WorkflowAnnotations annotations = rendererModel.getOperatorAnnotations(operator); if (annotations == null || annotations.isEmpty()) { return; } Rectangle2D frame = rendererModel.getOperatorRect(operator); int xOffset = (IMAGE_ANNOTATION.getIconWidth() + 2) * 2; ProcessDrawUtils.getIcon(operator, IMAGE_ANNOTATION) .paintIcon( null, g2, (int) (frame.getX() + frame.getWidth() - xOffset), (int) (frame.getY() + frame.getHeight() - IMAGE_ANNOTATION.getIconHeight() - 1)); } }; /** listener which triggers color panel moving if required */ private ComponentListener colorPanelMover = new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { updateColorPanelPosition(); } @Override public void componentMoved(ComponentEvent e) { updateColorPanelPosition(); } }; /** * Creates a new workflow annotation decorator * * @param view the process renderer instance * @param visualizer the annotation visualizer instance * @param model the model backing this instance */ public AnnotationsDecorator( final ProcessRendererView view, final AnnotationsVisualizer visualizer, final AnnotationsModel model) { this.view = view; this.model = model; this.rendererModel = view.getModel(); this.drawer = new AnnotationDrawer(model, rendererModel); this.hook = new AnnotationEventHook(this, model, visualizer, drawer, view, rendererModel); this.visualizer = visualizer; } /** * Start inline editing of the selected annotation. If no annotation is selected, does nothing. */ public void editSelected() { if (model.getSelected() == null) { return; } // editor to actually edit comment string removeEditor(); createEditor(); // panel to edit alignment and color createEditPanel(); editPane.requestFocusInWindow(); view.repaint(); } /** Stop all editing and remove editors. */ public void reset() { drawer.reset(); removeEditor(); } /** Registers the event hooks and draw decorators to the process renderer. */ void registerEventHooks() { view.addDrawDecorator(processAnnotationDrawer, RenderPhase.ANNOTATIONS); view.addDrawDecorator(operatorAnnotationDrawer, RenderPhase.OPERATOR_ANNOTATIONS); view.addDrawDecorator(workflowAnnotationDrawerHighlight, RenderPhase.OVERLAY); view.addDrawDecorator(opAnnotationIconDrawer); view.getOverviewPanelDrawer().addDecorator(processAnnotationDrawer, RenderPhase.ANNOTATIONS); view.getOverviewPanelDrawer() .addDecorator(operatorAnnotationDrawer, RenderPhase.OPERATOR_ANNOTATIONS); hook.registerDecorators(); // this listener makes the color edit panel move when required view.addComponentListener(colorPanelMover); ApplicationFrame.getApplicationFrame().addComponentListener(colorPanelMover); } /** Removes the event hooks and draw decorators from the process renderer. */ void unregisterDecorators() { view.removeDrawDecorator(processAnnotationDrawer, RenderPhase.ANNOTATIONS); view.removeDrawDecorator(operatorAnnotationDrawer, RenderPhase.OPERATOR_ANNOTATIONS); view.removeDrawDecorator(workflowAnnotationDrawerHighlight, RenderPhase.OVERLAY); view.removeDrawDecorator(opAnnotationIconDrawer); view.getOverviewPanelDrawer().removeDecorator(processAnnotationDrawer, RenderPhase.ANNOTATIONS); view.getOverviewPanelDrawer() .removeDecorator(operatorAnnotationDrawer, RenderPhase.OPERATOR_ANNOTATIONS); hook.unregisterEventHooks(); view.removeComponentListener(colorPanelMover); ApplicationFrame.getApplicationFrame().removeComponentListener(colorPanelMover); } /** * Creates and adds the JEditorPane for the currently selected annotation to the process renderer. */ private void createEditor() { final WorkflowAnnotation selected = model.getSelected(); Rectangle2D loc = selected.getLocation(); // JEditorPane to edit the comment string editPane = new JEditorPane("text/html", ""); editPane.setBorder(null); int paneX = (int) loc.getX(); int paneY = (int) loc.getY(); int index = view.getModel().getProcessIndex(selected.getProcess()); Point absolute = ProcessDrawUtils.convertToAbsoluteProcessPoint( new Point(paneX, paneY), index, rendererModel); editPane.setBounds( (int) absolute.getX(), (int) absolute.getY(), (int) loc.getWidth(), (int) loc.getHeight()); editPane.setText(AnnotationDrawUtils.createStyledCommentString(selected)); // use proxy for paste actions to trigger reload of editor after paste Action pasteFromClipboard = editPane.getActionMap().get(PASTE_FROM_CLIPBOARD_ACTION_NAME); Action paste = editPane.getActionMap().get(PASTE_ACTION_NAME); if (pasteFromClipboard != null) { editPane .getActionMap() .put( PASTE_FROM_CLIPBOARD_ACTION_NAME, new PasteAnnotationProxyAction(pasteFromClipboard, this)); } if (paste != null) { editPane.getActionMap().put(PASTE_ACTION_NAME, new PasteAnnotationProxyAction(paste, this)); } // use proxy for transfer actions to convert e.g. HTML paste to plaintext paste editPane.setTransferHandler(new TransferHandlerAnnotationPlaintext(editPane)); // IMPORTANT: Linebreaks do not work without the following! // this filter inserts a \r every time the user enters a newline // this signal is later used to convert newline to <br/> ((HTMLDocument) editPane.getDocument()) .setDocumentFilter( new DocumentFilter() { @Override public void insertString( DocumentFilter.FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException { // this is never called.. super.insertString( fb, offs, str.replaceAll("\n", "\n" + AnnotationDrawUtils.ANNOTATION_HTML_NEWLINE_SIGNAL), a); } @Override public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException { if (selected instanceof OperatorAnnotation) { // operator annotations have a character limit, enforce here try { int existingLength = AnnotationDrawUtils.getPlaintextFromEditor(editPane, false).length() - length; if (existingLength + str.length() > OperatorAnnotation.MAX_CHARACTERS) { // insert at beginning or end is fine, cut off excess characters if (existingLength <= 0 || offs >= existingLength) { int acceptableLength = OperatorAnnotation.MAX_CHARACTERS - existingLength; int newLength = Math.max(acceptableLength, 0); str = str.substring(0, newLength); } else { // inserting into middle, do NOT paste at all return; } } } catch (IOException e) { // should not happen, if it does this is our smallest problem -> ignore } } super.replace( fb, offs, length, str.replaceAll("\n", "\n" + AnnotationDrawUtils.ANNOTATION_HTML_NEWLINE_SIGNAL), a); } }); // set background color if (selected.getStyle().getAnnotationColor() == AnnotationColor.TRANSPARENT) { editPane.setBackground(Color.WHITE); } else { editPane.setBackground(selected.getStyle().getAnnotationColor().getColorHighlight()); } editPane.addFocusListener( new FocusAdapter() { @Override public void focusLost(final FocusEvent e) { // right-click menu if (e.isTemporary()) { return; } if (editPane != null && e.getOppositeComponent() != null) { // style edit menu, no real focus loss if (SwingUtilities.isDescendingFrom(e.getOppositeComponent(), editPanel)) { return; } if (SwingUtilities.isDescendingFrom(e.getOppositeComponent(), colorOverlay)) { return; } if (colorOverlay.getParent() == e.getOppositeComponent()) { return; } saveEdit(selected); removeEditor(); } } }); editPane.addKeyListener( new KeyAdapter() { /** keep track of control down so Ctrl+Enter works but Enter+Ctrl not */ private boolean controlDown; @Override public void keyPressed(final KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_CONTROL) { controlDown = true; } // consume so undo/redo etc are not passed to the process if (SwingTools.isControlOrMetaDown(e) && e.getKeyCode() == KeyEvent.VK_Z || e.getKeyCode() == KeyEvent.VK_Y) { e.consume(); } } @Override public void keyReleased(final KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_CONTROL: controlDown = false; break; case KeyEvent.VK_ENTER: if (!controlDown) { updateEditorHeight(selected); } else { // if control was down before Enter was pressed, save & exit saveEdit(selected); removeEditor(); model.setSelected(null); } break; case KeyEvent.VK_ESCAPE: // ignore changes on escape removeEditor(); model.setSelected(null); break; default: break; } } }); editPane .getDocument() .addDocumentListener( new DocumentListener() { @Override public void removeUpdate(DocumentEvent e) { updateEditorHeight(selected); } @Override public void insertUpdate(DocumentEvent e) { updateEditorHeight(selected); } @Override public void changedUpdate(DocumentEvent e) { updateEditorHeight(selected); } }); view.add(editPane); editPane.selectAll(); } /** * Creates and adds the edit panel for the currently selected annotation to the process renderer. */ private void createEditPanel() { final WorkflowAnnotation selected = model.getSelected(); Rectangle2D loc = selected.getLocation(); // panel containing buttons editPanel = new JPanel(); editPanel.setCursor(Cursor.getDefaultCursor()); editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.LINE_AXIS)); updateEditPanelPosition(loc, false); editPanel.setOpaque(true); editPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); // consume mouse events so focus is not lost editPanel.addMouseListener( new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { e.consume(); } @Override public void mousePressed(MouseEvent e) { e.consume(); } @Override public void mouseClicked(MouseEvent e) { e.consume(); } }); // add alignment controls final List<JButton> alignmentButtonList = new LinkedList<JButton>(); for (AnnotationAlignment align : AnnotationAlignment.values()) { final Action action = align.makeAlignmentChangeAction(model, model.getSelected()); final JButton alignButton = new JButton(); alignButton.setIcon((Icon) action.getValue(Action.SMALL_ICON)); alignButton.setBorderPainted(false); alignButton.setBorder(null); alignButton.setFocusable(false); if (align == selected.getStyle().getAnnotationAlignment()) { alignButton.setBackground(Color.LIGHT_GRAY); } alignButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { removeColorPanel(); colorButton.setBackground(null); for (JButton button : alignmentButtonList) { button.setBackground(null); } alignButton.setBackground(Color.LIGHT_GRAY); int caretPos = editPane.getCaretPosition(); // remember if we were at last position because doc length can change after 1st // save boolean lastPos = caretPos == editPane.getDocument().getLength(); int selStart = editPane.getSelectionStart(); int selEnd = editPane.getSelectionEnd(); // change alignment and save current comment action.actionPerformed(e); saveEdit(selected); // reload edit pane with changes editPane.setText(AnnotationDrawUtils.createStyledCommentString(selected)); // special handling for documents of length 1 to avoid not being able to type if (editPane.getDocument().getLength() == 1) { caretPos = 1; } else if (lastPos) { caretPos = editPane.getDocument().getLength(); } else { caretPos = Math.min(editPane.getDocument().getLength(), caretPos); } editPane.setCaretPosition(caretPos); if (selEnd - selStart > 0) { editPane.setSelectionStart(selStart); editPane.setSelectionEnd(selEnd); } editPane.requestFocusInWindow(); } }); editPanel.add(alignButton); alignmentButtonList.add(alignButton); } // add small empty space editPanel.add(Box.createHorizontalStrut(2)); // add color controls colorOverlay = new JDialog(ApplicationFrame.getApplicationFrame()); colorOverlay.setCursor(Cursor.getDefaultCursor()); colorOverlay .getRootPane() .setLayout(new BoxLayout(colorOverlay.getRootPane(), BoxLayout.LINE_AXIS)); colorOverlay.setUndecorated(true); colorOverlay.getRootPane().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); colorOverlay.setFocusable(false); colorOverlay.setAutoRequestFocus(false); // consume mouse events so focus is not lost colorOverlay.addMouseListener( new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { e.consume(); } @Override public void mousePressed(MouseEvent e) { e.consume(); } @Override public void mouseClicked(MouseEvent e) { e.consume(); } }); for (final AnnotationColor color : AnnotationColor.values()) { final Action action = color.makeColorChangeAction(model, selected); JButton colChangeButton = new JButton(); colChangeButton.setText(null); colChangeButton.setBorderPainted(false); colChangeButton.setBorder(null); colChangeButton.setFocusable(false); final Icon icon = SwingTools.createIconFromColor( color.getColor(), Color.BLACK, 16, 16, new Rectangle2D.Double(1, 1, 14, 14)); colChangeButton.setIcon(icon); colChangeButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // change color and save current comment action.actionPerformed(e); saveEdit(selected); // set edit pane bg color editPane.requestFocusInWindow(); if (color == AnnotationColor.TRANSPARENT) { editPane.setBackground(Color.WHITE); } else { editPane.setBackground(color.getColorHighlight()); } // adapt color of main button, remove color panel colorButton.setIcon(icon); if (removeColorPanel()) { colorButton.setBackground(null); view.repaint(); } } }); colorOverlay.getRootPane().add(colChangeButton); } colorButton = new JButton("\u25BE"); colorButton.setBorderPainted(false); colorButton.setFocusable(false); AnnotationColor color = selected.getStyle().getAnnotationColor(); colorButton.setIcon( SwingTools.createIconFromColor( color.getColor(), Color.BLACK, 16, 16, new Rectangle2D.Double(1, 1, 14, 14))); colorButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (removeColorPanel()) { colorButton.setBackground(null); view.repaint(); return; } updateColorPanelPosition(); colorOverlay.setVisible(true); colorButton.setBackground(Color.LIGHT_GRAY); editPane.requestFocusInWindow(); view.repaint(); } }); editPanel.add(colorButton); // add separator JLabel separator = new JLabel() { private static final long serialVersionUID = 1L; @Override public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.LIGHT_GRAY); g2.drawLine(2, 0, 2, 20); } }; separator.setText(" "); // dummy text to show label editPanel.add(separator); // add delete button final JButton deleteButton = new JButton( I18N.getMessage(I18N.getGUIBundle(), "gui.action.workflow.annotation.delete.label")); deleteButton.setForeground(Color.RED); deleteButton.setContentAreaFilled(false); deleteButton.setFocusable(false); deleteButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { model.deleteAnnotation(selected); removeEditor(); } }); deleteButton.addMouseListener( new MouseAdapter() { @Override @SuppressWarnings({"unchecked", "rawtypes"}) public void mouseExited(MouseEvent e) { Font font = deleteButton.getFont(); Map attributes = font.getAttributes(); attributes.put(TextAttribute.UNDERLINE, -1); deleteButton.setFont(font.deriveFont(attributes)); } @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void mouseEntered(MouseEvent e) { Font font = deleteButton.getFont(); Map attributes = font.getAttributes(); attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); deleteButton.setFont(font.deriveFont(attributes)); } }); editPanel.add(deleteButton); // add panel to view view.add(editPanel); } /** * Saves the content of the comment editor as the new comment for the given {@link * WorkflowAnnotation}. * * @param selected the annotation for which the content of the editor pane should be saved as new * comment */ private void saveEdit(final WorkflowAnnotation selected) { if (editPane == null) { return; } HTMLDocument document = (HTMLDocument) editPane.getDocument(); StringWriter writer = new StringWriter(); try { editPane.getEditorKit().write(writer, document, 0, document.getLength()); } catch (IndexOutOfBoundsException | IOException | BadLocationException e1) { // should not happen LogService.getRoot() .log( Level.WARNING, "com.rapidminer.gui.flow.processrendering.annotations.AnnotationsDecorator.cannot_save"); } String comment = writer.toString(); comment = AnnotationDrawUtils.removeStyleFromComment(comment); Rectangle2D loc = selected.getLocation(); Rectangle2D newLoc = new Rectangle2D.Double( loc.getX(), loc.getY(), editPane.getBounds().getWidth(), editPane.getBounds().getHeight()); selected.setLocation(newLoc); boolean overflowing = false; int prefHeight = AnnotationDrawUtils.getContentHeight( AnnotationDrawUtils.createStyledCommentString(comment, selected.getStyle()), (int) newLoc.getWidth()); if (prefHeight > newLoc.getHeight()) { overflowing = true; } selected.setOverflowing(overflowing); model.setAnnotationComment(selected, comment); } /** * Reloads the editor pane content to match editor and annotation styling. After this call, the * editor pane displays the annotation in the same way as it is displayed in the process renderer. */ void updateEditorContent() { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { if (editPane == null || model.getSelected() == null) { return; } HTMLDocument document = (HTMLDocument) editPane.getDocument(); StringWriter writer = new StringWriter(); try { editPane.getEditorKit().write(writer, document, 0, document.getLength()); } catch (IndexOutOfBoundsException | IOException | BadLocationException e1) { // should not happen LogService.getRoot() .log( Level.WARNING, "com.rapidminer.gui.flow.processrendering.annotations.AnnotationsDecorator.cannot_save"); } String comment = writer.toString(); comment = AnnotationDrawUtils.removeStyleFromComment(comment); int caretPos = editPane.getCaretPosition(); boolean lastPos = caretPos == editPane.getDocument().getLength(); editPane.setText( AnnotationDrawUtils.createStyledCommentString( comment, model.getSelected().getStyle())); if (lastPos) { caretPos = editPane.getDocument().getLength(); } caretPos = Math.min(caretPos, editPane.getDocument().getLength()); editPane.setCaretPosition(caretPos); editPane.requestFocusInWindow(); } }); } /** Removes the annotation editor from the process renderer. */ private void removeEditor() { if (editPane != null) { view.remove(editPane); editPane = null; } if (editPanel != null) { view.remove(editPanel); editPanel = null; } removeColorPanel(); // this makes sure that pressing F2 afterwards works // otherwise nothing is focused until the next click view.requestFocusInWindow(); view.repaint(); } /** Tries to remove the color panel. If not found or not showing, does nothing. */ private boolean removeColorPanel() { if (colorOverlay != null && colorOverlay.isShowing()) { colorOverlay.dispose(); return true; } return false; } /** * Updates the position and size of the edit panel relative to the given location. * * @param loc the location the edit panel should be relative to * @param absolute if {@code true} the loc is treated as absolute position on the process * renderer; if {@code false} it is treated as relative to the current process */ private void updateEditPanelPosition(final Rectangle2D loc, final boolean absolute) { int panelX = (int) loc.getCenterX() - EDIT_PANEL_WIDTH / 2; int panelY = (int) loc.getY() - EDIT_PANEL_HEIGHT - ProcessDrawer.PADDING; // if panel would be outside process renderer, fix it if (panelX < WorkflowAnnotation.MIN_X) { panelX = WorkflowAnnotation.MIN_X; } if (panelY < 0) { panelY = (int) loc.getMaxY() + ProcessDrawer.PADDING; } // last fallback is cramped to the bottom. If that does not fit either, don't care if (panelY + EDIT_PANEL_HEIGHT > view.getSize().getHeight() - ProcessDrawer.PADDING * 2) { panelY = (int) loc.getMaxY(); } int index = view.getModel().getProcessIndex(model.getSelected().getProcess()); if (absolute) { editPanel.setBounds(panelX, panelY, EDIT_PANEL_WIDTH, EDIT_PANEL_HEIGHT); } else { Point absoluteP = ProcessDrawUtils.convertToAbsoluteProcessPoint( new Point(panelX, panelY), index, rendererModel); editPanel.setBounds( (int) absoluteP.getX(), (int) absoluteP.getY(), EDIT_PANEL_WIDTH, EDIT_PANEL_HEIGHT); } } /** * Makes sure the current editor height matches its content if the annotation was never resized. * If the annotation has been manually resized before, does nothing. * * @param anno the annotation currently in the editor */ private void updateEditorHeight(final WorkflowAnnotation anno) { if (anno.wasResized()) { return; } Rectangle bounds = editPane.getBounds(); // height is either the pref height or the current height, depending on what is bigger int prefHeight; if (anno instanceof ProcessAnnotation) { prefHeight = (int) Math.max(getContentHeightOfEditor((int) bounds.getWidth()), bounds.getHeight()); } else { prefHeight = Math.max( getContentHeightOfEditor((int) bounds.getWidth()), OperatorAnnotation.MIN_HEIGHT); } Rectangle newBounds = new Rectangle( (int) bounds.getX(), (int) bounds.getY(), (int) bounds.getWidth(), prefHeight); if (!bounds.equals(newBounds)) { editPane.setBounds(newBounds); updateEditPanelPosition(newBounds, true); view.getModel().fireAnnotationMiscChanged(anno); } } /** Updates the location of the color edit panel (if shown). */ private void updateColorPanelPosition() { if (editPanel != null && colorOverlay != null) { int colorPanelX = (int) editPanel.getLocationOnScreen().getX() + colorButton.getX(); int colorPanelY = (int) (editPanel.getLocationOnScreen().getY() + editPanel.getBounds().getHeight()); colorOverlay.setBounds( colorPanelX, colorPanelY, EDIT_COLOR_PANEL_WIDTH, EDIT_COLOR_PANEL_HEIGHT); } } /** * Calculates the preferred height of the editor pane with the given fixed width. * * @param width the width of the pane * @return the preferred height given the current editor pane content or {@code -1} if there was a * problem. Value will never exceed {@link WorkflowAnnotation#MAX_HEIGHT} */ private int getContentHeightOfEditor(final int width) { HTMLDocument document = (HTMLDocument) editPane.getDocument(); StringWriter writer = new StringWriter(); try { editPane.getEditorKit().write(writer, document, 0, document.getLength()); } catch (IndexOutOfBoundsException | IOException | BadLocationException e1) { // should not happen return -1; } String comment = writer.toString(); comment = AnnotationDrawUtils.removeStyleFromComment(comment); int maxHeight = model.getSelected() instanceof ProcessAnnotation ? ProcessAnnotation.MAX_HEIGHT : OperatorAnnotation.MAX_HEIGHT; return Math.min( AnnotationDrawUtils.getContentHeight( AnnotationDrawUtils.createStyledCommentString(comment, model.getSelected().getStyle()), width), maxHeight); } }
/** * The colors used for the RapidLook look and feel. * * @author Ingo Mierswa */ public class Colors { public static ColorUIResource white = new ColorUIResource(255, 255, 255); public static ColorUIResource black = new ColorUIResource(0, 0, 0); // set via UIManager.setColor("VLDocking.highlight", ...) public static ColorUIResource vlDockingHighlight = new ColorUIResource(255, 0, 0); // set via UIManager.setColor("VLDocking.shadow", ...) public static ColorUIResource vlDockingShadow = new ColorUIResource(0, 255, 0); private ColorUIResource[] tableHeaderColors = new ColorUIResource[] { new ColorUIResource(210, 210, 230), new ColorUIResource(220, 220, 240), new ColorUIResource(225, 225, 245), new ColorUIResource(235, 235, 255), new ColorUIResource(245, 145, 0), // highlight 1 new ColorUIResource(245, 145, 0), // hightlight 2 new ColorUIResource(250, 250, 255), new ColorUIResource(200, 200, 220), new ColorUIResource(250, 250, 255), new ColorUIResource(230, 230, 250), new ColorUIResource(225, 225, 245), new ColorUIResource(215, 215, 235), new ColorUIResource(210, 210, 230), new ColorUIResource(190, 190, 210) }; private ColorUIResource[] buttonSkinColors = new ColorUIResource[] { new ColorUIResource(253, 254, 255), // begin pressed // 0 new ColorUIResource(253, 253, 255), // both new ColorUIResource(249, 251, 255), // both new ColorUIResource(248, 250, 255), // both new ColorUIResource(254, 254, 255), // both new ColorUIResource(234, 234, 235), // 5 new ColorUIResource(230, 232, 235), new ColorUIResource(224, 229, 235), new ColorUIResource(209, 221, 234), // end pressed new ColorUIResource(254, 254, 255), new ColorUIResource(253, 254, 255), // 10 new ColorUIResource(246, 249, 255), new ColorUIResource(243, 247, 255), new ColorUIResource(239, 244, 255), new ColorUIResource(233, 240, 255), new ColorUIResource(225, 235, 255), // 15 new ColorUIResource(217, 230, 255), new ColorUIResource(252, 253, 255), new ColorUIResource(247, 251, 255), new ColorUIResource(224, 228, 235), // start down new ColorUIResource(239, 244, 255), // 20 new ColorUIResource(218, 230, 240) // 21 }; /* private ColorUIResource[] buttonSkinColors = new ColorUIResource[] { new ColorUIResource(253, 254, 255), // begin pressed new ColorUIResource(253, 253, 255), new ColorUIResource(249, 251, 255), new ColorUIResource(248, 250, 255), new ColorUIResource(254, 254, 255), new ColorUIResource(254, 254, 255), new ColorUIResource(250, 252, 255), new ColorUIResource(244, 249, 255), new ColorUIResource(229, 241, 254), // end pressed new ColorUIResource(254, 254, 255), new ColorUIResource(253, 254, 255), new ColorUIResource(246, 249, 255), new ColorUIResource(243, 247, 255), new ColorUIResource(239, 244, 255), new ColorUIResource(233, 240, 255), new ColorUIResource(225, 235, 255), new ColorUIResource(217, 230, 255), new ColorUIResource(252, 253, 255), new ColorUIResource(247, 251, 255) }; */ private ColorUIResource[] tabbedPaneColors = new ColorUIResource[] { // new ColorUIResource(220, 225, 230), // 0 new ColorUIResource(200, 205, 210), // 0 new ColorUIResource(215, 220, 225), new ColorUIResource(170, 170, 190), new ColorUIResource(200, 200, 220), new ColorUIResource(190, 200, 220), new ColorUIResource(250, 250, 250), new ColorUIResource(255, 255, 255), new ColorUIResource(210, 210, 230), new ColorUIResource(180, 190, 210), new ColorUIResource(200, 200, 220), new ColorUIResource(210, 210, 230), // 10 new ColorUIResource(220, 220, 240), new ColorUIResource(230, 230, 250), new ColorUIResource(235, 235, 255), new ColorUIResource(240, 240, 255), new ColorUIResource(245, 245, 255), new ColorUIResource(250, 250, 255), new ColorUIResource(255, 255, 255), new ColorUIResource(255, 255, 255), new ColorUIResource(210, 210, 230), new ColorUIResource(240, 240, 255), // 20 new ColorUIResource(245, 145, 0), // highlight }; private ColorUIResource[] spinnerColors = new ColorUIResource[] { new ColorUIResource(230, 230, 250), new ColorUIResource(170, 170, 190), new ColorUIResource(240, 240, 255), new ColorUIResource(235, 235, 255), new ColorUIResource(220, 220, 240), new ColorUIResource(220, 220, 240), new ColorUIResource(210, 210, 230), new ColorUIResource(170, 170, 190), new ColorUIResource(230, 230, 250), new ColorUIResource(110, 110, 110), new ColorUIResource(195, 195, 195) }; private ColorUIResource[][] buttonBorderColors = new ColorUIResource[][] { { // gray new ColorUIResource(100, 100, 100), new ColorUIResource(80, 80, 80), new ColorUIResource(150, 150, 150), new ColorUIResource(200, 200, 200), new ColorUIResource(150, 150, 150), new ColorUIResource(115, 115, 115), new ColorUIResource(125, 125, 125), new ColorUIResource(190, 190, 190), new ColorUIResource(100, 100, 100), new ColorUIResource(215, 215, 215), new ColorUIResource(235, 235, 235) }, { // orange hover new ColorUIResource(200, 80, 20), new ColorUIResource(180, 60, 0), new ColorUIResource(230, 110, 45), new ColorUIResource(255, 205, 175), new ColorUIResource(230, 115, 50), new ColorUIResource(220, 105, 40), new ColorUIResource(230, 115, 50), new ColorUIResource(230, 125, 45), new ColorUIResource(205, 100, 20), new ColorUIResource(255, 200, 160), new ColorUIResource(255, 225, 205) }, { // orange focus new ColorUIResource(180, 60, 0), new ColorUIResource(160, 40, 0), new ColorUIResource(210, 90, 25), new ColorUIResource(235, 185, 155), new ColorUIResource(210, 95, 30), new ColorUIResource(200, 85, 20), new ColorUIResource(210, 95, 30), new ColorUIResource(210, 105, 25), new ColorUIResource(185, 80, 0), new ColorUIResource(235, 180, 140), new ColorUIResource(235, 205, 185) }, { // gray 2 new ColorUIResource(170, 170, 170), new ColorUIResource(150, 150, 150), new ColorUIResource(200, 200, 200), new ColorUIResource(220, 220, 220), new ColorUIResource(200, 200, 200), new ColorUIResource(180, 180, 180), new ColorUIResource(185, 185, 185), new ColorUIResource(220, 220, 220), new ColorUIResource(150, 150, 150), new ColorUIResource(230, 230, 230), new ColorUIResource(240, 240, 240) }, { // default new ColorUIResource(100, 100, 100), new ColorUIResource(80, 80, 80), new ColorUIResource(150, 150, 150), new ColorUIResource(200, 200, 200), new ColorUIResource(150, 150, 150), new ColorUIResource(115, 115, 115), new ColorUIResource(125, 125, 125), new ColorUIResource(140, 140, 160), new ColorUIResource(50, 50, 70), new ColorUIResource(165, 165, 185), new ColorUIResource(185, 185, 205) } }; private ColorUIResource[] toolbarButtonColors = new ColorUIResource[] { new ColorUIResource(170, 170, 170), new ColorUIResource(250, 250, 250), new ColorUIResource(190, 190, 190), new ColorUIResource(230, 230, 230), new ColorUIResource(240, 240, 240), new ColorUIResource(200, 200, 200), new ColorUIResource(215, 215, 215), new ColorUIResource(235, 235, 235), new ColorUIResource(220, 220, 220), new ColorUIResource(225, 225, 225) }; private static ColorUIResource[][] radioButtonColors = new ColorUIResource[][] { { new ColorUIResource(242, 242, 242), new ColorUIResource(197, 197, 197), new ColorUIResource(172, 172, 172), new ColorUIResource(153, 153, 153), new ColorUIResource(215, 215, 215) }, { // orange border hover new ColorUIResource(255, 230, 200), new ColorUIResource(230, 185, 160), new ColorUIResource(220, 155, 160), new ColorUIResource(210, 135, 100), new ColorUIResource(240, 205, 190) }, { new ColorUIResource(240, 245, 255), new ColorUIResource(255, 255, 255), new ColorUIResource(253, 253, 253), new ColorUIResource(251, 251, 251), new ColorUIResource(249, 249, 249), new ColorUIResource(247, 247, 247), new ColorUIResource(245, 245, 245), new ColorUIResource(243, 243, 243), new ColorUIResource(240, 240, 240), new ColorUIResource(238, 238, 238) }, { // gray bullet new ColorUIResource(210, 210, 230), new ColorUIResource(200, 200, 220), new ColorUIResource(180, 180, 200), new ColorUIResource(170, 170, 190), new ColorUIResource(160, 160, 180), new ColorUIResource(150, 150, 170), new ColorUIResource(140, 140, 160), new ColorUIResource(120, 120, 140), new ColorUIResource(205, 205, 205) } }; private static ColorUIResource[][] checkBoxButtonColors = new ColorUIResource[][] { { new ColorUIResource(200, 200, 200), new ColorUIResource(145, 145, 145), new ColorUIResource(105, 105, 105), new ColorUIResource(255, 255, 255), new ColorUIResource(252, 252, 252), new ColorUIResource(248, 248, 248), new ColorUIResource(245, 245, 245), new ColorUIResource(241, 241, 241), new ColorUIResource(238, 238, 238) }, { new ColorUIResource(205, 215, 233), new ColorUIResource(170, 185, 215), new ColorUIResource(80, 110, 173), new ColorUIResource(238, 245, 255), new ColorUIResource(215, 225, 245) }, { new ColorUIResource(235, 235, 235), new ColorUIResource(205, 205, 205), new ColorUIResource(180, 180, 180), new ColorUIResource(240, 240, 240), new ColorUIResource(190, 190, 190) }, { new ColorUIResource(235, 165, 120), new ColorUIResource(255, 220, 190), new ColorUIResource(230, 180, 130), new ColorUIResource(225, 145, 80), new ColorUIResource(200, 130, 70), new ColorUIResource(215, 160, 105), new ColorUIResource(240, 190, 155), new ColorUIResource(210, 135, 70), new ColorUIResource(245, 170, 100), new ColorUIResource(235, 185, 140), new ColorUIResource(210, 135, 70) } }; private ColorUIResource[][] textFieldBorderColors = new ColorUIResource[][] { { // focus new ColorUIResource(200, 125, 50), new ColorUIResource(235, 210, 130), new ColorUIResource(255, 195, 160), new ColorUIResource(230, 160, 110) }, { new ColorUIResource(110, 110, 110), new ColorUIResource(220, 220, 220), new ColorUIResource(200, 200, 200), new ColorUIResource(160, 160, 160) }, { new ColorUIResource(160, 160, 160), new ColorUIResource(225, 225, 225), new ColorUIResource(211, 211, 211), new ColorUIResource(175, 175, 175) } }; private ColorUIResource[][] internalFrameTitlePaneColors = new ColorUIResource[][] { { new ColorUIResource(160, 175, 200), new ColorUIResource(125, 150, 190), new ColorUIResource(122, 148, 194), new ColorUIResource(85, 123, 187), new ColorUIResource(75, 115, 185), new ColorUIResource(85, 123, 191), new ColorUIResource(172, 180, 205), new ColorUIResource(85, 123, 191), new ColorUIResource(95, 137, 192), new ColorUIResource(85, 123, 191), new ColorUIResource(130, 155, 197), new ColorUIResource(188, 201, 226), new ColorUIResource(153, 172, 206), new ColorUIResource(125, 150, 192) }, { new ColorUIResource(160, 175, 200), new ColorUIResource(125, 150, 190), new ColorUIResource(122, 148, 194), new ColorUIResource(85, 123, 187), new ColorUIResource(75, 115, 185), new ColorUIResource(85, 123, 191), new ColorUIResource(85, 125, 193), new ColorUIResource(85, 123, 191), new ColorUIResource(172, 180, 205), new ColorUIResource(84, 122, 189), new ColorUIResource(95, 137, 192), new ColorUIResource(81, 119, 187), new ColorUIResource(79, 118, 185), new ColorUIResource(77, 116, 183), new ColorUIResource(75, 113, 181), new ColorUIResource(73, 112, 179), new ColorUIResource(72, 110, 177), new ColorUIResource(70, 108, 176), new ColorUIResource(68, 107, 174), new ColorUIResource(67, 105, 172), new ColorUIResource(65, 104, 171), new ColorUIResource(63, 102, 169), new ColorUIResource(62, 100, 167), new ColorUIResource(61, 99, 165), new ColorUIResource(59, 96, 162), new ColorUIResource(56, 93, 157), new ColorUIResource(49, 85, 148), new ColorUIResource(43, 80, 143), new ColorUIResource(117, 120, 130), new ColorUIResource(130, 155, 197), new ColorUIResource(188, 201, 226), new ColorUIResource(153, 172, 206), new ColorUIResource(125, 150, 192) } }; private ColorUIResource[][] bordersColors = new ColorUIResource[][] { {new ColorUIResource(205, 160, 130), new ColorUIResource(175, 110, 70)} }; private ColorUIResource[][] progressBarColors = new ColorUIResource[][] { { new ColorUIResource(245, 170, 120), new ColorUIResource(255, 215, 150), new ColorUIResource(255, 210, 170), new ColorUIResource(250, 180, 140), new ColorUIResource(255, 165, 100), new ColorUIResource(250, 155, 100), new ColorUIResource(250, 140, 80), new ColorUIResource(250, 170, 130), new ColorUIResource(250, 180, 140), new ColorUIResource(255, 160, 105), new ColorUIResource(250, 185, 155), new ColorUIResource(255, 160, 95), new ColorUIResource(230, 160, 120) }, { new ColorUIResource(255, 180, 130), new ColorUIResource(255, 225, 160), new ColorUIResource(255, 220, 180), new ColorUIResource(255, 190, 150), new ColorUIResource(255, 175, 110), new ColorUIResource(255, 165, 110), new ColorUIResource(255, 150, 90), new ColorUIResource(255, 180, 140), new ColorUIResource(255, 190, 150), new ColorUIResource(255, 170, 115), new ColorUIResource(255, 195, 165), new ColorUIResource(255, 170, 105), new ColorUIResource(240, 170, 130) }, }; private ColorUIResource[][] scrollBarColors = new ColorUIResource[][] { { new ColorUIResource(180, 180, 180), new ColorUIResource(240, 240, 240), new ColorUIResource(245, 245, 245), new ColorUIResource(248, 248, 248) }, { new ColorUIResource(180, 180, 200), new ColorUIResource(200, 200, 220), new ColorUIResource(195, 195, 215), new ColorUIResource(190, 190, 210), new ColorUIResource(185, 185, 205), new ColorUIResource(180, 180, 200), new ColorUIResource(175, 175, 195), new ColorUIResource(170, 170, 190), new ColorUIResource(165, 165, 185), new ColorUIResource(160, 160, 180), new ColorUIResource(200, 200, 220), new ColorUIResource(180, 180, 200), new ColorUIResource(220, 220, 240), new ColorUIResource(200, 200, 220) } }; private ColorUIResource[][] arrowButtonColors = new ColorUIResource[][] { { new ColorUIResource(220, 220, 240), new ColorUIResource(160, 160, 180), new ColorUIResource(210, 210, 230), new ColorUIResource(190, 190, 210), new ColorUIResource(160, 160, 180), new ColorUIResource(180, 180, 200), new ColorUIResource(210, 210, 230), new ColorUIResource(220, 220, 250) }, { new ColorUIResource(230, 230, 250), new ColorUIResource(230, 230, 250), new ColorUIResource(200, 200, 220), new ColorUIResource(180, 180, 200), new ColorUIResource(220, 220, 240), new ColorUIResource(170, 170, 190), new ColorUIResource(200, 200, 220), new ColorUIResource(150, 150, 170), new ColorUIResource(215, 215, 235), new ColorUIResource(180, 180, 200), new ColorUIResource(160, 160, 180), new ColorUIResource(150, 150, 170), new ColorUIResource(170, 170, 190), new ColorUIResource(200, 200, 220), new ColorUIResource(170, 170, 190), new ColorUIResource(160, 160, 180), new ColorUIResource(220, 220, 240) } }; private ColorUIResource[] fileChooserColors = new ColorUIResource[] { new ColorUIResource(255, 200, 200), new ColorUIResource(230, 170, 170) }; private ColorUIResource[] toolbarColors = new ColorUIResource[] {new ColorUIResource(240, 240, 245)}; private ImageIconUIResource sliderImage = new ImageIconUIResource(SwingTools.createImage("plaf/slider.png").getImage()); private ColorUIResource[][] sliderColors = new ColorUIResource[][] {{}}; private ColorUIResource desktopBackgroundColor = new ColorUIResource(180, 195, 220); private static ColorUIResource commonBackground = new ColorUIResource(240, 240, 245); private static ColorUIResource commonForeground = new ColorUIResource(0, 0, 0); private static ColorUIResource commonFocusColor = new ColorUIResource(205, 85, 0); public static ColorUIResource getWhite() { return white; } public static ColorUIResource getBlack() { return black; } public ColorUIResource getMenuItemBackground() { return new ColorUIResource(UIManager.getColor("MenuItem.background")); } public ColorUIResource getMenuItemSelectionBackground() { return new ColorUIResource(UIManager.getColor("MenuItem.selectionBackground")); } public ColorUIResource getMenuItemFadingColor() { return new ColorUIResource(UIManager.getColor("MenuItem.fadingColor")); } public String getName() { return "Colors"; } public void addCustomEntriesToTable(UIDefaults table) { Object[] values = new Object[] { "MenuItem.background", getWhite(), "MenuItem.selectionBackground", new ColorUIResource(150, 150, 170), "MenuItem.fadingColor", new ColorUIResource(235, 235, 255), "ToolTip.background", new ColorUIResource(250, 240, 225), "ToolTip.borderColor", new ColorUIResource(113, 103, 74) }; table.putDefaults(values); } public ColorUIResource getCommonFocusColor() { return commonFocusColor; } public ColorUIResource getTextHighlightBackColor() { return new ColorUIResource(150, 150, 170); } public ColorUIResource[] getButtonSkinColors() { return this.buttonSkinColors; } public ColorUIResource[] getToolbarButtonColors() { return this.toolbarButtonColors; } public ColorUIResource[][] getButtonBorderColors() { return this.buttonBorderColors; } public ColorUIResource getCommonBackground() { return commonBackground; } public ColorUIResource getCommonForeground() { return commonForeground; } public ColorUIResource[][] getRadioButtonColors() { return radioButtonColors; } public ColorUIResource[][] getCheckBoxButtonColors() { return checkBoxButtonColors; } public ColorUIResource[][] getTextFieldBorderColors() { return this.textFieldBorderColors; } public ColorUIResource[][] getInternalFrameTitlePaneColors() { return this.internalFrameTitlePaneColors; } public ColorUIResource[][] getBorderColors() { return this.bordersColors; } public ColorUIResource[][] getProgressBarColors() { return this.progressBarColors; } public ColorUIResource[][] getScrollBarColors() { return this.scrollBarColors; } public ColorUIResource[][] getArrowButtonColors() { return this.arrowButtonColors; } public ColorUIResource[][] getSliderColors() { return this.sliderColors; } public ImageIconUIResource getSliderImage() { return this.sliderImage; } public ColorUIResource[] getSpinnerColors() { return this.spinnerColors; } public ColorUIResource[] getTabbedPaneColors() { return this.tabbedPaneColors; } public ColorUIResource[] getTableHeaderColors() { return this.tableHeaderColors; } public ColorUIResource[] getFileChooserColors() { return this.fileChooserColors; } public ColorUIResource getDesktopBackgroundColor() { return this.desktopBackgroundColor; } public ColorUIResource[] getToolbarColors() { return this.toolbarColors; } }
/** * Creates and adds the edit panel for the currently selected annotation to the process renderer. */ private void createEditPanel() { final WorkflowAnnotation selected = model.getSelected(); Rectangle2D loc = selected.getLocation(); // panel containing buttons editPanel = new JPanel(); editPanel.setCursor(Cursor.getDefaultCursor()); editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.LINE_AXIS)); updateEditPanelPosition(loc, false); editPanel.setOpaque(true); editPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); // consume mouse events so focus is not lost editPanel.addMouseListener( new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { e.consume(); } @Override public void mousePressed(MouseEvent e) { e.consume(); } @Override public void mouseClicked(MouseEvent e) { e.consume(); } }); // add alignment controls final List<JButton> alignmentButtonList = new LinkedList<JButton>(); for (AnnotationAlignment align : AnnotationAlignment.values()) { final Action action = align.makeAlignmentChangeAction(model, model.getSelected()); final JButton alignButton = new JButton(); alignButton.setIcon((Icon) action.getValue(Action.SMALL_ICON)); alignButton.setBorderPainted(false); alignButton.setBorder(null); alignButton.setFocusable(false); if (align == selected.getStyle().getAnnotationAlignment()) { alignButton.setBackground(Color.LIGHT_GRAY); } alignButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { removeColorPanel(); colorButton.setBackground(null); for (JButton button : alignmentButtonList) { button.setBackground(null); } alignButton.setBackground(Color.LIGHT_GRAY); int caretPos = editPane.getCaretPosition(); // remember if we were at last position because doc length can change after 1st // save boolean lastPos = caretPos == editPane.getDocument().getLength(); int selStart = editPane.getSelectionStart(); int selEnd = editPane.getSelectionEnd(); // change alignment and save current comment action.actionPerformed(e); saveEdit(selected); // reload edit pane with changes editPane.setText(AnnotationDrawUtils.createStyledCommentString(selected)); // special handling for documents of length 1 to avoid not being able to type if (editPane.getDocument().getLength() == 1) { caretPos = 1; } else if (lastPos) { caretPos = editPane.getDocument().getLength(); } else { caretPos = Math.min(editPane.getDocument().getLength(), caretPos); } editPane.setCaretPosition(caretPos); if (selEnd - selStart > 0) { editPane.setSelectionStart(selStart); editPane.setSelectionEnd(selEnd); } editPane.requestFocusInWindow(); } }); editPanel.add(alignButton); alignmentButtonList.add(alignButton); } // add small empty space editPanel.add(Box.createHorizontalStrut(2)); // add color controls colorOverlay = new JDialog(ApplicationFrame.getApplicationFrame()); colorOverlay.setCursor(Cursor.getDefaultCursor()); colorOverlay .getRootPane() .setLayout(new BoxLayout(colorOverlay.getRootPane(), BoxLayout.LINE_AXIS)); colorOverlay.setUndecorated(true); colorOverlay.getRootPane().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); colorOverlay.setFocusable(false); colorOverlay.setAutoRequestFocus(false); // consume mouse events so focus is not lost colorOverlay.addMouseListener( new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { e.consume(); } @Override public void mousePressed(MouseEvent e) { e.consume(); } @Override public void mouseClicked(MouseEvent e) { e.consume(); } }); for (final AnnotationColor color : AnnotationColor.values()) { final Action action = color.makeColorChangeAction(model, selected); JButton colChangeButton = new JButton(); colChangeButton.setText(null); colChangeButton.setBorderPainted(false); colChangeButton.setBorder(null); colChangeButton.setFocusable(false); final Icon icon = SwingTools.createIconFromColor( color.getColor(), Color.BLACK, 16, 16, new Rectangle2D.Double(1, 1, 14, 14)); colChangeButton.setIcon(icon); colChangeButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // change color and save current comment action.actionPerformed(e); saveEdit(selected); // set edit pane bg color editPane.requestFocusInWindow(); if (color == AnnotationColor.TRANSPARENT) { editPane.setBackground(Color.WHITE); } else { editPane.setBackground(color.getColorHighlight()); } // adapt color of main button, remove color panel colorButton.setIcon(icon); if (removeColorPanel()) { colorButton.setBackground(null); view.repaint(); } } }); colorOverlay.getRootPane().add(colChangeButton); } colorButton = new JButton("\u25BE"); colorButton.setBorderPainted(false); colorButton.setFocusable(false); AnnotationColor color = selected.getStyle().getAnnotationColor(); colorButton.setIcon( SwingTools.createIconFromColor( color.getColor(), Color.BLACK, 16, 16, new Rectangle2D.Double(1, 1, 14, 14))); colorButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (removeColorPanel()) { colorButton.setBackground(null); view.repaint(); return; } updateColorPanelPosition(); colorOverlay.setVisible(true); colorButton.setBackground(Color.LIGHT_GRAY); editPane.requestFocusInWindow(); view.repaint(); } }); editPanel.add(colorButton); // add separator JLabel separator = new JLabel() { private static final long serialVersionUID = 1L; @Override public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.LIGHT_GRAY); g2.drawLine(2, 0, 2, 20); } }; separator.setText(" "); // dummy text to show label editPanel.add(separator); // add delete button final JButton deleteButton = new JButton( I18N.getMessage(I18N.getGUIBundle(), "gui.action.workflow.annotation.delete.label")); deleteButton.setForeground(Color.RED); deleteButton.setContentAreaFilled(false); deleteButton.setFocusable(false); deleteButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { model.deleteAnnotation(selected); removeEditor(); } }); deleteButton.addMouseListener( new MouseAdapter() { @Override @SuppressWarnings({"unchecked", "rawtypes"}) public void mouseExited(MouseEvent e) { Font font = deleteButton.getFont(); Map attributes = font.getAttributes(); attributes.put(TextAttribute.UNDERLINE, -1); deleteButton.setFont(font.deriveFont(attributes)); } @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void mouseEntered(MouseEvent e) { Font font = deleteButton.getFont(); Map attributes = font.getAttributes(); attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); deleteButton.setFont(font.deriveFont(attributes)); } }); editPanel.add(deleteButton); // add panel to view view.add(editPanel); }
static { int counter = 0; for (IconSize size : IconSize.values()) { ICONS[counter++] = SwingTools.createIcon(size.getSize() + "/" + ICON_NAME); } }
/** @author Simon Fischer */ public class ErrorTable extends JPanel implements Dockable, ProcessEditor { private static final long serialVersionUID = -954934789614113138L; private static final ImageIcon IMAGE_WARNING = SwingTools.createIcon("16/sign_warning.png"); private static final ImageIcon IMAGE_ERROR = SwingTools.createIcon("16/error.png"); private static final ImageIcon IMAGE_NO_QUICKFIX = SwingTools.createIcon( "16/" + I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.no_quickfix_available.icon")); private static final ImageIcon IMAGE_QUICKFIX = SwingTools.createIcon( "16/" + I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.choose_quickfix.icon")); private static final String[] COLUMN_NAMES = { I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.header.message.label"), I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.header.fixes.label"), I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.header.location.label") }; private static final String[] COLUMN_TOOLTIPS = { I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.header.message.tip"), I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.header.fixes.tip"), I18N.getMessage(I18N.getGUIBundle(), "gui.errortable.header.location.tip") }; private final MainFrame mainFrame; private final TableCellRenderer iconRenderer = new DefaultTableCellRenderer() { private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof ProcessSetupError) { JLabel label = (JLabel) super.getTableCellRendererComponent( table, ((ProcessSetupError) value).getMessage(), isSelected, hasFocus, row, column); switch (((ProcessSetupError) value).getSeverity()) { case WARNING: label.setIcon(IMAGE_WARNING); break; case ERROR: label.setIcon(IMAGE_ERROR); break; default: label.setIcon(null); // cannot happen } return label; } else if (value instanceof Port) { JLabel label = (JLabel) super.getTableCellRendererComponent( table, ((Port) value).getSpec(), isSelected, hasFocus, row, column); label.setIcon( ((Port) value) .getPorts() .getOwner() .getOperator() .getOperatorDescription() .getSmallIcon()); return label; } else if (value instanceof Operator) { JLabel label = (JLabel) super.getTableCellRendererComponent( table, ((Operator) value).getName(), isSelected, hasFocus, row, column); label.setIcon(((Operator) value).getOperatorDescription().getSmallIcon()); return label; } else { if (column == 1) { JLabel label = (JLabel) super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); if (value == null) { label.setIcon(IMAGE_NO_QUICKFIX); label.setText( I18N.getMessage( I18N.getGUIBundle(), "gui.errortable.no_quickfix_available.label")); } if (value instanceof List) { label.setIcon(IMAGE_QUICKFIX); label.setText( I18N.getMessage( I18N.getGUIBundle(), "gui.errortable.choose_quickfix.label", ((List) value).size())); } if (value instanceof QuickFix) { QuickFix quickFix = (QuickFix) value; label.setIcon((Icon) quickFix.getAction().getValue(Action.SMALL_ICON)); label.setText(quickFix.toString()); } return label; } else { JLabel label = (JLabel) super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); label.setIcon(null); return label; } } } }; private final ExtendedJTable table = new ExtendedJTable() { private static final long serialVersionUID = 3731781319040565353L; @Override public TableCellRenderer getCellRenderer(int row, int column) { return iconRenderer; } @Override public void populatePopupMenu(JPopupMenu menu) { List<? extends QuickFix> fixes = errors.get(getSelectedRow()).getQuickFixes(); if (!fixes.isEmpty()) { JMenu fixMenu = new ResourceMenu("quick_fixes"); for (QuickFix fix : fixes) { fixMenu.add(fix.getAction()); } menu.add(fixMenu); menu.addSeparator(); } super.populatePopupMenu(menu); } @Override protected JTableHeader createDefaultTableHeader() { return new JTableHeader(columnModel) { private static final long serialVersionUID = -2000774622129683602L; @Override public String getToolTipText(MouseEvent e) { java.awt.Point p = e.getPoint(); int index = columnModel.getColumnIndexAtX(p.x); int realIndex = columnModel.getColumn(index).getModelIndex(); return COLUMN_TOOLTIPS[realIndex]; }; }; }; @Override public String getToolTipText(MouseEvent e) { Point p = e.getPoint(); int realColumnIndex = convertColumnIndexToModel(columnAtPoint(p)); int rowIndex = rowAtPoint(p); if (rowIndex >= 0 && rowIndex < getRowCount() && realColumnIndex == 1) { Object value = getModel().getValueAt(rowIndex, realColumnIndex); if (value == null) { return I18N.getMessage( I18N.getGUIBundle(), "gui.errortable.no_quickfix_available.tip"); } if (value instanceof List) { return I18N.getMessage( I18N.getGUIBundle(), "gui.errortable.choose_quickfix.tip", ((List) value).size()); } if (value instanceof QuickFix) { return ((QuickFix) value).toString(); } } return super.getToolTipText(e); } }; private final JLabel headerLabel = new JLabel(); private final JToggleButton onlyCurrent = new JToggleButton( new ResourceAction(true, "error_table_only_current") { private static final long serialVersionUID = -1454330266199555397L; @Override public void actionPerformed(ActionEvent e) { updateErrors(); } }); private List<ProcessSetupError> errors = new LinkedList<ProcessSetupError>(); private final AbstractTableModel model = new AbstractTableModel() { private static final long serialVersionUID = 1L; @Override public String getColumnName(int col) { return COLUMN_NAMES[col]; } @Override public boolean isCellEditable(int row, int col) { return false; } @Override public int getColumnCount() { return 3; } @Override public int getRowCount() { return errors.size(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { ProcessSetupError error = errors.get(rowIndex); switch (columnIndex) { case 0: return error; case 1: List<? extends QuickFix> fixes = error.getQuickFixes(); if (fixes.size() > 1) { return fixes; } if (fixes.size() == 1) { return fixes.get(0); } return null; case 2: if (error instanceof MetaDataError) { return ((MetaDataError) error).getPort(); } else { return error.getOwner().getOperator(); } default: return null; } } }; private Process currentProcess; public ErrorTable(final MainFrame mainFrame) { super(new BorderLayout()); this.mainFrame = mainFrame; onlyCurrent.setSelected(false); table.setShowVerticalLines(false); table.setModel(model); table.installToolTip(); table.getColumnModel().getColumn(0).setPreferredWidth(400); table.getColumnModel().getColumn(1).setPreferredWidth(200); table.getColumnModel().getColumn(2).setPreferredWidth(150); headerLabel.setHorizontalAlignment(SwingConstants.CENTER); headerLabel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); table.setBorder(null); JScrollPane scrollPane = new ExtendedJScrollPane(table); scrollPane.setBorder(null); add(scrollPane, BorderLayout.CENTER); ViewToolBar toolBar = new ViewToolBar(); toolBar.add(onlyCurrent); onlyCurrent.setText(null); toolBar.add(headerLabel); add(toolBar, BorderLayout.NORTH); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.addMouseListener( new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { switch (table.getSelectedColumn()) { // quick fixes case 1: List<? extends QuickFix> quickFixes = errors.get(table.getSelectedRow()).getQuickFixes(); if (quickFixes.size() == 1) { quickFixes.get(0).apply(); } if (quickFixes.size() > 1) { new QuickFixDialog(quickFixes).setVisible(true); } break; default: ProcessSetupError error = errors.get(table.getSelectedRow()); Operator op = error.getOwner().getOperator(); ErrorTable.this.mainFrame.selectOperator(op); // other } } } }); } private void updateErrors() { if ((currentOperator != null) && onlyCurrent.isSelected()) { fill(currentOperator); } else { if (currentProcess != null) { fill(currentProcess.getRootOperator()); } } } private void fill(Operator root) { int numTotal = root.getProcess().getRootOperator().getErrorList().size(); errors = root.getErrorList(); String errorString; switch (errors.size()) { case 0: errorString = "No problems found"; break; case 1: errorString = "One potential problem"; break; default: errorString = errors.size() + " potential problems"; break; } if (errors.size() != numTotal) { errorString = errorString + " (" + (numTotal - errors.size()) + " Filtered)"; } headerLabel.setText(errorString); model.fireTableDataChanged(); } @Override public void processChanged(Process process) { currentProcess = process; updateErrors(); } @Override public void processUpdated(Process process) { currentProcess = process; updateErrors(); } @Override public void setSelection(List<Operator> selection) { this.currentOperator = selection.isEmpty() ? null : selection.get(0); updateErrors(); } public static final String ERROR_TABLE_DOCK_KEY = "error_table"; private final DockKey DOCK_KEY = new ResourceDockKey(ERROR_TABLE_DOCK_KEY); { DOCK_KEY.setDockGroup(MainFrame.DOCK_GROUP_ROOT); } private Operator currentOperator; @Override public Component getComponent() { return this; } @Override public DockKey getDockKey() { return DOCK_KEY; } }
private void storeInFolder(final Folder folder) { // get current process name (if present) String currentName = null; if (RapidMinerGUI.getMainFrame().getProcess().getProcessLocation() != null) { currentName = RapidMinerGUI.getMainFrame().getProcess().getProcessLocation().getShortName(); } final String name = SwingTools.showRepositoryEntryInputDialog("store_process", currentName); if (name != null) { if (name.isEmpty()) { SwingTools.showVerySimpleErrorMessage("please_enter_non_empty_name"); return; } try { // check if folder already contains entry with said name RepositoryLocation entryLocation = new RepositoryLocation(folder.getLocation(), name); if (folder.containsEntry(name)) { Entry existingEntry = entryLocation.locateEntry(); if (!(existingEntry instanceof ProcessEntry)) { // existing entry is not a ProcessEntry, cannot overwrite SwingTools.showVerySimpleErrorMessage("repository_entry_already_exists", name); return; } else { // existing entry is ProcessEntry,let #overwriteProcess() handle it overwriteProcess((ProcessEntry) existingEntry); return; } } } catch (RepositoryException e1) { SwingTools.showSimpleErrorMessage("cannot_store_process_in_repository", e1, name); return; } catch (MalformedRepositoryLocationException e1) { SwingTools.showSimpleErrorMessage("cannot_store_process_in_repository", e1, name); return; } ProgressThread storeProgressThread = new ProgressThread("store_process") { public void run() { getProgressListener().setTotal(100); Process process = RapidMinerGUI.getMainFrame().getProcess(); RepositoryProcessLocation processLocation = null; try { processLocation = new RepositoryProcessLocation( new RepositoryLocation(folder.getLocation(), name)); getProgressListener().setCompleted(10); Process.checkIfSavable(process); folder.createProcessEntry(name, process.getRootOperator().getXML(false)); process.setProcessLocation(processLocation); tree.expandPath(tree.getSelectionPath()); RapidMinerGUI.addToRecentFiles(process.getProcessLocation()); RapidMinerGUI.getMainFrame().processHasBeenSaved(); } catch (Exception e) { SwingTools.showSimpleErrorMessage( "cannot_save_process", e, processLocation, e.getMessage()); RapidMinerGUI.getMainFrame().getProcess().setProcessLocation(null); } finally { getProgressListener().setCompleted(10); getProgressListener().complete(); } } }; storeProgressThread.start(); } }
static { resultIcon = SwingTools.createIcon("16/" + RESULT_ICON_NAME); }
/** Setup the GUI. */ private void setupGUI() { JPanel mainPanel = new JPanel(); this.setContentPane(mainPanel); // start layout mainPanel.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(5, 5, 2, 5); JLabel valueLabel = new JLabel( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.value.label")); this.add(valueLabel, gbc); gbc.gridx = 1; gbc.gridy = 0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; valueField = new JTextField(); valueField.setInputVerifier( new InputVerifier() { @Override public boolean verify(JComponent input) { return verifyValueInput(input); } }); valueField.setToolTipText( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.value.tip")); this.add(valueField, gbc); gbc.gridx = 0; gbc.gridy = 1; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0; JLabel colorLabel = new JLabel( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.color.label")); this.add(colorLabel, gbc); gbc.gridx = 1; gbc.gridy = 1; lineColorButton = new JButton( new ResourceAction(true, "edit_parallel_line.select_line_color") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { createLineColorDialog(); } }); this.add(lineColorButton, gbc); gbc.gridx = 0; gbc.gridy = 2; JLabel widthLabel = new JLabel( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.width.label")); this.add(widthLabel, gbc); gbc.gridx = 1; gbc.gridy = 2; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; widthField = new JTextField(); widthField.setInputVerifier( new InputVerifier() { @Override public boolean verify(JComponent input) { return verifyWidthInput(input); } }); widthField.setToolTipText( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.width.tip")); this.add(widthField, gbc); gbc.gridx = 0; gbc.gridy = 3; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0; JLabel styleLabel = new JLabel( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.line_style.label")); this.add(styleLabel, gbc); gbc.gridx = 1; gbc.gridy = 3; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; lineStyleCombobox = new JComboBox(LineStyle.values()); ((DefaultComboBoxModel) lineStyleCombobox.getModel()).removeElement(LineStyle.NONE); lineStyleCombobox.setToolTipText( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.line_style.tip")); lineStyleCombobox.setSelectedItem(LineStyle.SOLID); this.add(lineStyleCombobox, gbc); gbc.gridx = 0; gbc.gridy = 4; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; gbc.weighty = 0; gbc.anchor = GridBagConstraints.CENTER; gbc.insets = new Insets(15, 5, 5, 5); this.add(new JSeparator(), gbc); gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(5, 5, 5, 5); okButton = new JButton(I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.ok.label")); okButton.setToolTipText( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.ok.tip")); okButton.setIcon( SwingTools.createIcon( "24/" + I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.ok.icon"))); okButton.setMnemonic( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.ok.mne") .toCharArray()[0]); okButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { boolean successful = editLine(); // don't dispose dialog if not successful if (!successful) { return; } EditParallelLineDialog.this.dispose(); } }); okButton.addKeyListener( new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { okButton.doClick(); } } }); this.add(okButton, gbc); gbc.gridx = 1; gbc.gridy = 5; gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.EAST; cancelButton = new JButton( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.cancel.label")); cancelButton.setToolTipText( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.cancel.tip")); cancelButton.setIcon( SwingTools.createIcon( "24/" + I18N.getMessage( I18N.getGUIBundle(), "gui.action.edit_parallel_line.cancel.icon"))); cancelButton.setMnemonic( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.cancel.mne") .toCharArray()[0]); cancelButton.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // cancel requested, close dialog EditParallelLineDialog.this.dispose(); } }); this.add(cancelButton, gbc); // misc settings this.setMinimumSize(new Dimension(275, 225)); // center dialog this.setLocationRelativeTo(null); this.setTitle( I18N.getMessage(I18N.getGUIBundle(), "gui.action.edit_parallel_line.title.label")); this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); this.setModal(true); this.addWindowListener( new WindowAdapter() { @Override public void windowActivated(WindowEvent e) { cancelButton.requestFocusInWindow(); } }); }
/** * This panel displays parameters of an operator. It refreshes in either of these cases: * * <ul> * <li>A new operator is selected. * <li>The {@link Parameters} of the current operator (which are observed) change in a way such * that the parameter value differs from the one displayed by the editor. This should only * happen if a parameter value is changed programmatically, e.g. by an operator. * <li>{@link #processUpdated(Process)} is called and {@link #getProperties()} returns a different * list than the one returned during the last {@link #setupComponents()}. * <li>When changing to expert mode. * </ul> * * @author Simon Fischer, Tobias Malbrecht */ public class OperatorPropertyPanel extends PropertyPanel implements Dockable, ProcessEditor { private static final long serialVersionUID = 6056794546696461864L; private class BreakpointButton extends ToggleDropDownButton implements ToggleActionListener { private static final long serialVersionUID = 7364886954405951709L; private final Icon IMAGE_BREAKPOINTS = SwingTools.createIcon("16/breakpoints.png"); private final Icon IMAGE_BREAKPOINT_BEFORE = SwingTools.createIcon("16/breakpoint_up.png"); private final Icon IMAGE_BREAKPOINT_AFTER = SwingTools.createIcon("16/breakpoint_down.png"); { for (int i = 0; i < mainFrame.getActions().TOGGLE_BREAKPOINT.length; i++) { mainFrame.getActions().TOGGLE_BREAKPOINT[i].addToggleActionListener(this); } } public BreakpointButton() { super( new ResourceAction(true, "breakpoint_after") { private static final long serialVersionUID = -8913366165786891652L; @Override public void actionPerformed(ActionEvent e) { if (mainFrame.getActions().TOGGLE_BREAKPOINT[0].isSelected() || mainFrame.getActions().TOGGLE_BREAKPOINT[1].isSelected()) { mainFrame.getActions().TOGGLE_BREAKPOINT[0].resetAction(false); mainFrame.getActions().TOGGLE_BREAKPOINT[1].resetAction(false); return; } mainFrame.getActions().TOGGLE_BREAKPOINT[1].actionPerformed(null); } }); } @Override public void setSelected(boolean selected) { Icon breakpointIcon; if (operator != null && operator.hasBreakpoint()) { super.setSelected(true); if (operator.getNumberOfBreakpoints() == 1) { if (operator.hasBreakpoint(BreakpointListener.BREAKPOINT_BEFORE)) { breakpointIcon = IMAGE_BREAKPOINT_BEFORE; } else { breakpointIcon = IMAGE_BREAKPOINT_AFTER; } } else { breakpointIcon = IMAGE_BREAKPOINTS; } } else { super.setSelected(false); breakpointIcon = IMAGE_BREAKPOINT_AFTER; } setIcon(breakpointIcon); } @Override protected JPopupMenu getPopupMenu() { JPopupMenu menu = new JPopupMenu(); for (int i = 0; i < mainFrame.getActions().TOGGLE_BREAKPOINT.length; i++) { menu.add(mainFrame.getActions().TOGGLE_BREAKPOINT[i].createMenuItem()); } return menu; } } private final BreakpointButton breakpointButton; private final MainFrame mainFrame; private static final Icon WARNING_ICON = SwingTools.createIcon("16/sign_warning.png"); private final JLabel headerLabel = new JLabel(""); private final Font selectedFont = headerLabel.getFont().deriveFont(Font.BOLD); private final Font unselectedFont = headerLabel.getFont(); private final JLabel expertModeHintLabel = new JLabel(""); private Operator operator; private final Observer<String> parameterObserver = new Observer<String>() { @Override public void update(Observable<String> observable, String key) { PropertyValueCellEditor editor = getEditorForKey(key); if (editor != null) { ParameterType type = operator.getParameters().getParameterType(key); String editorValue = type.toString(editor.getCellEditorValue()); String opValue = operator.getParameters().getParameterOrNull(key); if (((opValue != null) && (editorValue == null)) || ((opValue == null) && (editorValue != null)) || ((opValue != null) && (editorValue != null) && !opValue.equals(editorValue))) { editor.getTableCellEditorComponent(null, opValue, false, 0, 1); } } else { setupComponents(); } } }; private JSpinner compatibilityLevelSpinner = new JSpinner(new CompatibilityLevelSpinnerModel()); private ResourceLabel compatibilityLabel = new ResourceLabel("compatibility_level"); private JPanel compatibilityPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));; public OperatorPropertyPanel(final MainFrame mainFrame) { super(); this.mainFrame = mainFrame; breakpointButton = new BreakpointButton(); headerLabel.setHorizontalAlignment(SwingConstants.CENTER); expertModeHintLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); expertModeHintLabel.setIcon(WARNING_ICON); expertModeHintLabel.addMouseListener( new MouseListener() { public void mouseReleased(MouseEvent e) { mainFrame.TOGGLE_EXPERT_MODE_ACTION.actionPerformed(null); } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} }); expertModeHintLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); expertModeHintLabel.setHorizontalAlignment(SwingConstants.LEFT); setupComponents(); compatibilityLevelSpinner.addChangeListener( new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { // compatibility level OperatorVersion[] versionChanges = operator.getIncompatibleVersionChanges(); if (versionChanges.length != 0) { OperatorVersion latestChange = versionChanges[versionChanges.length - 1]; if (latestChange.isAtLeast(operator.getCompatibilityLevel())) { compatibilityLabel.setIcon(WARNING_ICON); } else { compatibilityLabel.setIcon(SwingTools.createIcon("16/ok.png")); } } } }); } @Override protected String getValue(ParameterType type) { return operator.getParameters().getParameterOrNull(type.getKey()); } @Override protected void setValue(Operator operator, ParameterType type, String value) { if (value.length() == 0) { value = null; } operator.setParameter(type.getKey(), value); } @Override protected List<ParameterType> getProperties() { List<ParameterType> visible = new LinkedList<ParameterType>(); int hidden = 0; if (operator != null) { for (ParameterType type : operator.getParameters().getParameterTypes()) { if (type.isHidden()) { continue; } if (!isExpertMode() && type.isExpert()) { hidden++; continue; } visible.add(type); } } if (hidden > 0) { expertModeHintLabel.setText(hidden + " hidden expert parameter" + (hidden == 1 ? "" : "s")); expertModeHintLabel.setVisible(true); } else { expertModeHintLabel.setVisible(false); } return visible; } @Override public void processChanged(Process process) {} @Override public void processUpdated(Process process) { setNameFor(operator); // check if we have editors for the current parameters. If not, refresh. int count = 0; // count hits. If we have to many, also refresh List<ParameterType> properties = getProperties(); if (properties.size() != getNumberOfEditors()) { setupComponents(); return; } for (ParameterType type : properties) { if (hasEditorFor(type)) { count++; } else { setupComponents(); return; } } if (count != properties.size()) { setupComponents(); } } @Override public void setSelection(List<Operator> selection) { Operator operator = selection.isEmpty() ? null : selection.get(0); if (operator == this.operator) { return; } if (this.operator != null) { this.operator.getParameters().removeObserver(parameterObserver); } this.operator = operator; if (operator != null) { this.operator.getParameters().addObserver(parameterObserver, true); breakpointButton.setEnabled(true); // compatibility level OperatorVersion[] versionChanges = operator.getIncompatibleVersionChanges(); if (versionChanges.length == 0) { // no incompatible versions exist compatibilityLevelSpinner.setVisible(false); compatibilityLabel.setVisible(false); } else { compatibilityLevelSpinner.setVisible(true); compatibilityLabel.setVisible(true); ((CompatibilityLevelSpinnerModel) compatibilityLevelSpinner.getModel()) .setOperator(operator); } } else { breakpointButton.setEnabled(false); } setNameFor(operator); setupComponents(); } private void setNameFor(Operator operator) { if (operator != null) { headerLabel.setFont(selectedFont); if (operator.getName().equals(operator.getOperatorDescription().getName())) { headerLabel.setText(operator.getName()); } else { headerLabel.setText( operator.getName() + " (" + operator.getOperatorDescription().getName() + ")"); } headerLabel.setIcon(operator.getOperatorDescription().getSmallIcon()); } else { headerLabel.setFont(unselectedFont); headerLabel.setText("No Operator Selected"); headerLabel.setIcon(null); } } @Override public Component getComponent() { if (dockableComponent == null) { JScrollPane scrollPane = new ExtendedJScrollPane(this); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setBorder(null); dockableComponent = new JPanel(new BorderLayout()); JPanel toolBarPanel = new JPanel(new BorderLayout()); ViewToolBar toolBar = new ViewToolBar(); JToggleButton toggleExpertModeButton = mainFrame.TOGGLE_EXPERT_MODE_ACTION.createToggleButton(); toggleExpertModeButton.setText(null); toolBar.add(toggleExpertModeButton); Action infoOperatorAction = new InfoOperatorAction() { private static final long serialVersionUID = 6758272768665592429L; @Override protected Operator getOperator() { return mainFrame.getFirstSelectedOperator(); } }; toolBar.add(infoOperatorAction); JToggleButton enableOperatorButton = new ToggleActivationItem(mainFrame.getActions()).createToggleButton(); enableOperatorButton.setText(null); toolBar.add(enableOperatorButton); Action renameOperatorAction = new ResourceAction(true, "rename_in_processrenderer") { { setCondition(OPERATOR_SELECTED, MANDATORY); } private static final long serialVersionUID = -3104160320178045540L; @Override public void actionPerformed(ActionEvent e) { Operator operator = mainFrame.getFirstSelectedOperator(); String name = SwingTools.showInputDialog("rename_operator", operator.getName()); if (name != null && name.length() > 0) { operator.rename(name); } } }; toolBar.add(renameOperatorAction); toolBar.add(new DeleteOperatorAction()); breakpointButton.addToToolBar(toolBar); // toolBar.add(mainFrame.getActions().MAKE_DIRTY_ACTION); toolBarPanel.add(toolBar, BorderLayout.NORTH); JPanel headerPanel = new JPanel(); headerPanel.setBackground(SwingTools.LIGHTEST_BLUE); headerPanel.add(headerLabel); headerPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.LIGHT_GRAY)); toolBarPanel.add(headerPanel, BorderLayout.SOUTH); dockableComponent.add(toolBarPanel, BorderLayout.NORTH); dockableComponent.add(scrollPane, BorderLayout.CENTER); // compatibility level and warnings JPanel southPanel = new JPanel(new BorderLayout()); southPanel.add(expertModeHintLabel, BorderLayout.CENTER); compatibilityLabel.setLabelFor(compatibilityLevelSpinner); compatibilityLevelSpinner.setPreferredSize( new Dimension(80, (int) compatibilityLevelSpinner.getPreferredSize().getHeight())); compatibilityPanel.add(compatibilityLabel); compatibilityPanel.add(compatibilityLevelSpinner); southPanel.add(compatibilityPanel, BorderLayout.SOUTH); dockableComponent.add(southPanel, BorderLayout.SOUTH); } return dockableComponent; } // implements Dockable public static final String PROPERTY_EDITOR_DOCK_KEY = "property_editor"; private final DockKey DOCK_KEY = new ResourceDockKey(PROPERTY_EDITOR_DOCK_KEY); { DOCK_KEY.setDockGroup(MainFrame.DOCK_GROUP_ROOT); } private JPanel dockableComponent; @Override public DockKey getDockKey() { return DOCK_KEY; } public boolean isExpertMode() { return mainFrame.TOGGLE_EXPERT_MODE_ACTION.isSelected(); } @Override protected Operator getOperator() { return operator; } }
private class BreakpointButton extends ToggleDropDownButton implements ToggleActionListener { private static final long serialVersionUID = 7364886954405951709L; private final Icon IMAGE_BREAKPOINTS = SwingTools.createIcon("16/breakpoints.png"); private final Icon IMAGE_BREAKPOINT_BEFORE = SwingTools.createIcon("16/breakpoint_up.png"); private final Icon IMAGE_BREAKPOINT_AFTER = SwingTools.createIcon("16/breakpoint_down.png"); { for (int i = 0; i < mainFrame.getActions().TOGGLE_BREAKPOINT.length; i++) { mainFrame.getActions().TOGGLE_BREAKPOINT[i].addToggleActionListener(this); } } public BreakpointButton() { super( new ResourceAction(true, "breakpoint_after") { private static final long serialVersionUID = -8913366165786891652L; @Override public void actionPerformed(ActionEvent e) { if (mainFrame.getActions().TOGGLE_BREAKPOINT[0].isSelected() || mainFrame.getActions().TOGGLE_BREAKPOINT[1].isSelected()) { mainFrame.getActions().TOGGLE_BREAKPOINT[0].resetAction(false); mainFrame.getActions().TOGGLE_BREAKPOINT[1].resetAction(false); return; } mainFrame.getActions().TOGGLE_BREAKPOINT[1].actionPerformed(null); } }); } @Override public void setSelected(boolean selected) { Icon breakpointIcon; if (operator != null && operator.hasBreakpoint()) { super.setSelected(true); if (operator.getNumberOfBreakpoints() == 1) { if (operator.hasBreakpoint(BreakpointListener.BREAKPOINT_BEFORE)) { breakpointIcon = IMAGE_BREAKPOINT_BEFORE; } else { breakpointIcon = IMAGE_BREAKPOINT_AFTER; } } else { breakpointIcon = IMAGE_BREAKPOINTS; } } else { super.setSelected(false); breakpointIcon = IMAGE_BREAKPOINT_AFTER; } setIcon(breakpointIcon); } @Override protected JPopupMenu getPopupMenu() { JPopupMenu menu = new JPopupMenu(); for (int i = 0; i < mainFrame.getActions().TOGGLE_BREAKPOINT.length; i++) { menu.add(mainFrame.getActions().TOGGLE_BREAKPOINT[i].createMenuItem()); } return menu; } }