All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yaoqiang.graph.swing.CellEditor Maven / Gradle / Ivy

There is a newer version: 2.2.18
Show newest version
package org.yaoqiang.graph.swing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Rectangle;
import java.util.EventObject;

import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;

import org.yaoqiang.bpmn.model.elements.XMLElement;
import org.yaoqiang.bpmn.model.elements.artifacts.CategoryValue;
import org.yaoqiang.bpmn.model.elements.artifacts.Group;
import org.yaoqiang.bpmn.model.elements.core.common.FlowElements;
import org.yaoqiang.bpmn.model.elements.data.DataObject;
import org.yaoqiang.bpmn.model.elements.data.DataObjectReference;
import org.yaoqiang.bpmn.model.elements.data.DataStore;
import org.yaoqiang.bpmn.model.elements.data.DataStoreReference;
import org.yaoqiang.graph.model.GraphModel;
import org.yaoqiang.graph.view.Graph;

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.view.mxCellEditor;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;

/**
 * CellEditor
 * 
 * @author Shi Yaoqiang([email protected])
 */
public class CellEditor extends mxCellEditor {

	protected transient JComboBox comboBox;

	public CellEditor(mxGraphComponent graphComponent) {
		super(graphComponent);
	}

	public GraphComponent getGraphComponent() {
		return (GraphComponent) graphComponent;
	}
	
	public Component getEditor()
	{
		if (textArea.getParent() != null)
		{
			return textArea;
		}
		// ==============start==============
		else if (comboBox != null && comboBox.getParent() != null)
		{
			return comboBox;
		}
		// ==============end================
		else if (editingCell != null)
		{
			return editorPane;
		}

		return null;
	}
	
	public Rectangle getEditorBounds(mxCellState state, double scale)
	{
		Graph graph = (Graph) state.getView().getGraph();
		GraphModel model = graph.getModel();
		Rectangle bounds = null;

		if (useLabelBounds(state))
		{
			bounds = state.getLabelBounds().getRectangle();
			bounds.height += 10;
		}
		else
		{
			bounds = state.getRectangle();
		}

		// Applies the horizontal and vertical label positions
		if (model.isVertex(state.getCell()))
		{
			String horizontal = mxUtils.getString(state.getStyle(),
					mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER);

			if (horizontal.equals(mxConstants.ALIGN_LEFT))
			{
				bounds.x -= state.getWidth();
			}
			else if (horizontal.equals(mxConstants.ALIGN_RIGHT))
			{
				bounds.x += state.getWidth();
			}

			String vertical = mxUtils.getString(state.getStyle(),
					mxConstants.STYLE_VERTICAL_LABEL_POSITION,
					mxConstants.ALIGN_MIDDLE);

			if (vertical.equals(mxConstants.ALIGN_TOP))
			{
				bounds.y -= state.getHeight();
			}
			else if (vertical.equals(mxConstants.ALIGN_BOTTOM))
			{
				bounds.y += state.getHeight();
			}
		}

		bounds.setSize(
				(int) Math.max(bounds.getWidth(),
						Math.round(minimumWidth * scale)),
				(int) Math.max(bounds.getHeight(),
						Math.round(minimumHeight * scale)));
		// ==============start==============
		if (model.isGroupArtifact(state.getCell()) || model.isDataStore(state.getCell()) || model.isDataObject(state.getCell())) {
			int width = (comboBox == null ? 120 : comboBox.getWidth());
			int y = (int) (state.getY() + state.getHeight());
			if (model.isGroupArtifact(state.getCell())) {
				y = (int) state.getY();
			}
			bounds.setLocation((int) state.getCenterX() - width / 2, y);
			bounds.setSize(width, (int) (25 * scale));
		}
		// ==============end================
		return bounds;
	}
	
	public void startEditing(Object cell, EventObject evt)
	{
		if (editingCell != null)
		{
			stopEditing(true);
		}

		mxCellState state = graphComponent.getGraph().getView().getState(cell);

		if (state != null)
		{
			editingCell = cell;
			trigger = evt;
			Graph graph = getGraphComponent().getGraph();
			GraphModel model = graph.getModel();
			double scale = Math.max(minimumEditorScale, graph.getView().getScale());
			scrollPane.setBounds(getEditorBounds(state, scale));
			scrollPane.setVisible(true);

			Object value = getInitialValue(state, evt);
			JTextComponent currentEditor = null;

			// Configures the style of the in-place editor
			if (graph.isHtmlLabel(cell))
			{
				if (isExtractHtmlBody())
				{
					value = mxUtils.getBodyMarkup((String) value,
							isReplaceHtmlLinefeeds());
				}

				editorPane.setDocument(mxUtils.createHtmlDocumentObject(
						state.getStyle(), scale));
				editorPane.setText((String) value);

				// Workaround for wordwrapping in editor pane
				// FIXME: Cursor not visible at end of line
				JPanel wrapper = new JPanel(new BorderLayout());
				wrapper.setOpaque(false);
				wrapper.add(editorPane, BorderLayout.CENTER);
				scrollPane.setViewportView(wrapper);

				currentEditor = editorPane;
			}
			// ==============start==============
			else if (model.isGroupArtifact(cell) || model.isDataStore(cell) || model.isDataObject(cell))
			{
				if (model.isGroupArtifact(cell)) {
					comboBox = new JComboBox(model.getBpmnModel().getAllCategoryValues().toArray());
				} else if (model.isDataStore(cell)) {
					comboBox = new JComboBox(model.getBpmnModel().getDataStores().toArray());
				} else {
					FlowElements flowElements = (FlowElements) ((XMLElement) model.getValue(cell)).getParent();
					if (model.isCollectionDataObject(cell)) {
						comboBox = new JComboBox(flowElements.getAccessibleDataObjects(true).toArray());
					} else {
						comboBox = new JComboBox(flowElements.getAccessibleDataObjects(false).toArray());
					}
				}
				comboBox.setFont(mxUtils.getFont(state.getStyle(), scale));
				Color fontColor = mxUtils.getColor(state.getStyle(),
						mxConstants.STYLE_FONTCOLOR, Color.black);
				comboBox.setForeground(fontColor);
				comboBox.setSelectedItem(value);
				scrollPane.setViewportView(comboBox);
			}// ==============end================
			else
			{
				textArea.setFont(mxUtils.getFont(state.getStyle(), scale));
				Color fontColor = mxUtils.getColor(state.getStyle(),
						mxConstants.STYLE_FONTCOLOR, Color.black);
				textArea.setForeground(fontColor);
				textArea.setText((String) value);

				scrollPane.setViewportView(textArea);
				currentEditor = textArea;
			}

			graphComponent.getGraphControl().add(scrollPane, 0);

			if (isHideLabel(state))
			{
				graphComponent.redraw(state);
			}
			
			if (currentEditor != null) {
				currentEditor.revalidate();
				currentEditor.requestFocusInWindow();
				currentEditor.selectAll();
			}

			configureActionMaps();
		}
	}

	public void stopEditing(boolean cancel)
	{
		if (editingCell != null)
		{
			Graph graph = getGraphComponent().getGraph();
			scrollPane.transferFocusUpCycle();
			Object cell = editingCell;
			editingCell = null;

			if (!cancel)
			{
				EventObject trig = trigger;
				trigger = null;
				Object currentValue = getCurrentValue();
				// ==============start==============
				if (graph.getModel().isDataStore(cell)) {
					DataStoreReference dsRef = (DataStoreReference) ((XMLElement) graph.getModel().getValue(cell)).clone();
					if (currentValue instanceof DataStore) {
						dsRef.setDataStoreRef(((DataStore)currentValue).getId());
					}
					currentValue = dsRef;
				} else if (graph.getModel().isDataObject(cell)) {
					DataObjectReference doRef = (DataObjectReference) ((XMLElement) graph.getModel().getValue(cell)).clone();
					if (currentValue instanceof DataObject) {
						doRef.setDataObjectRef(((DataObject)currentValue).getId());
					}
					currentValue = doRef;
				} else if (graph.getModel().isGroupArtifact(cell)) {
					Group group = (Group) ((XMLElement) graph.getModel().getValue(cell)).clone();
					if (currentValue instanceof CategoryValue) {
						group.setCategoryValueRef(((CategoryValue)currentValue).getId());
					}
					currentValue = group;
				}
				// ==============end================
				graphComponent.labelChanged(cell, currentValue, trig);
			}
			else
			{
				mxCellState state = graph.getView()
						.getState(cell);
				graphComponent.redraw(state);
			}

			if (scrollPane.getParent() != null)
			{
				scrollPane.setVisible(false);
				scrollPane.getParent().remove(scrollPane);
			}

			graphComponent.requestFocusInWindow();
		}
	}

	protected Object getInitialValue(mxCellState state, EventObject trigger)
	{
		Object value = graphComponent.getEditingValue(state.getCell(), trigger);
		// ==============start==============
		GraphModel model = getGraphComponent().getGraph().getModel();
		if (model.isDataStore(state.getCell())) {
			value = model.getBpmnModel().getDataStore(((DataStoreReference)model.getValue(state.getCell())).getDataStoreRef());
		} else if (model.isGroupArtifact(state.getCell())) {
			value = model.getBpmnModel().getCategoryValue(((Group)model.getValue(state.getCell())).getCategoryValueRef());
		} else if (model.isDataObject(state.getCell())) {
			value = ((DataObjectReference)model.getValue(state.getCell())).getRefDataObject();
		}
		// ==============end================
		return value;
	}
	
	public Object getCurrentValue()
	{
		Object result;

		if (textArea.getParent() != null)
		{
			result = textArea.getText();
		}// ==============start==============
		else if (comboBox != null && comboBox.getParent() != null) {
			if (comboBox.getSelectedItem() != null) {
				result = comboBox.getSelectedItem();
			} else {
				result = "";
			}
		}// ==============end================
		else
		{
			result = editorPane.getText();

			if (isExtractHtmlBody())
			{
				result = mxUtils
						.getBodyMarkup((String) result, isReplaceHtmlLinefeeds());
			}
		}

		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy