Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/property/PropertyContentMergeViewer.java')
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/property/PropertyContentMergeViewer.java578
1 files changed, 578 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/property/PropertyContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/property/PropertyContentMergeViewer.java
new file mode 100644
index 000000000..d7e2e3007
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/property/PropertyContentMergeViewer.java
@@ -0,0 +1,578 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Philip Langer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.property;
+
+import static com.google.common.collect.Iterables.getFirst;
+
+import com.google.common.collect.Iterables;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Conflict;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Equivalence;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
+import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree.AbstractTreeContentMergeViewer;
+import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.CompareInputAdapter;
+import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration;
+import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.DiffNode;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.tree.TreeNode;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A specialized {@link ContentMergeViewer} that shows property views for the three side viewers.
+ */
+class PropertyContentMergeViewer extends AbstractTreeContentMergeViewer {
+ /**
+ * The bundle name of the properties file containing all displayed strings needed by the base class.
+ */
+ private static final String BUNDLE_NAME = PropertyContentMergeViewer.class.getName();
+
+ /**
+ * The three values of {@link MergeViewerSide} in the order {@link MergeViewerSide#ANCESTOR},
+ * {@link MergeViewerSide#LEFT}, and {@link MergeViewerSide#RIGHT}.
+ */
+ static final MergeViewerSide[] MERGE_VIEWER_SIDES = new MergeViewerSide[] {MergeViewerSide.ANCESTOR,
+ MergeViewerSide.LEFT, MergeViewerSide.RIGHT };
+
+ /**
+ * The {@link IEMFCompareConfiguration#getBooleanProperty(String) configuration property key} used to
+ * indicate whether {@link IItemPropertyDescriptor#getFilterFlags(Object) advanced properties} should be
+ * shown.
+ *
+ * @see #createToolItems(ToolBarManager)
+ * @see PropertyItem#createPropertyItem(EMFCompareConfiguration, Object, MergeViewerSide)
+ */
+ static String SHOW_ADVANCED_PROPERTIES = "SHOW_ADVANCED_PROPERTIES"; //$NON-NLS-1$
+
+ /**
+ * The {@link IEMFCompareConfiguration#getBooleanProperty(String) configuration property key} used to
+ * indicate whether {@link IItemPropertyDescriptor#getCategory(Object) categories} should be shown.
+ *
+ * @see #createToolItems(ToolBarManager)
+ * @see PropertyItem#createPropertyItem(EMFCompareConfiguration, Object, MergeViewerSide)
+ */
+ static String SHOW_CATEGORIES = "SHOW_CATEGORIES"; //$NON-NLS-1$
+
+ /**
+ * The value used by {@link #updateContent(Object, Object, Object)} as a substitution for the ancestor.
+ *
+ * @see #buildPropertiesFromSides(Object, Object, Object)
+ */
+ private PropertyAccessor ancestorPropertyAccessor;
+
+ /**
+ * The value used by {@link #updateContent(Object, Object, Object)} as a substitution for the left.
+ *
+ * @see #buildPropertiesFromSides(Object, Object, Object)
+ */
+ private PropertyAccessor leftPropertyAccessor;
+
+ /**
+ * The value used by {@link #updateContent(Object, Object, Object)} as a substitution for the right.
+ *
+ * @see #buildPropertiesFromSides(Object, Object, Object)
+ */
+ private PropertyAccessor rightPropertyAccessor;
+
+ /**
+ * A listener attached the tree of {@link #getPropertyMergeViewer(MergeViewerSide) property merge viewer}
+ * that synchronizes the expansion state of the three trees as each individual tree expands and collapses
+ * a tree item.
+ *
+ * @see #createMergeViewer(Composite, MergeViewerSide)
+ */
+ private ITreeViewerListener treeListener = new ITreeViewerListener() {
+ public void treeExpanded(TreeExpansionEvent event) {
+ update(event, true);
+ }
+
+ public void treeCollapsed(TreeExpansionEvent event) {
+ update(event, false);
+ }
+
+ private void update(TreeExpansionEvent event, boolean expanded) {
+ AbstractTreeViewer treeViewer = event.getTreeViewer();
+ PropertyItem element = (PropertyItem)event.getElement();
+ for (MergeViewerSide side : MERGE_VIEWER_SIDES) {
+ PropertyTreeMergeViewer propertyMergeViewer = getPropertyMergeViewer(side);
+ if (propertyMergeViewer.getStructuredViewer() != treeViewer) {
+ PropertyItem sideElement = element.getSide(side);
+ if (sideElement != null) {
+ propertyMergeViewer.setExpandedState(sideElement, expanded);
+ propertyMergeViewer.columnResizer.resizeColumns();
+ }
+ }
+ }
+ redrawCenterControl();
+ }
+ };
+
+ /**
+ * Creates an instance contained by the parent composite for the given configuration.
+ *
+ * @param parent
+ * composite in which to create this instance.
+ * @param configuration
+ * the configuration used by this instance.
+ */
+ protected PropertyContentMergeViewer(Composite parent, EMFCompareConfiguration configuration) {
+ super(SWT.NONE, ResourceBundle.getBundle(BUNDLE_NAME), configuration);
+ buildControl(parent);
+ }
+
+ /**
+ * Returns the property merge viewer for the given side.
+ *
+ * @param side
+ * the side.
+ * @return the property merge viewer for the given side.
+ */
+ protected PropertyTreeMergeViewer getPropertyMergeViewer(MergeViewerSide side) {
+ switch (side) {
+ case ANCESTOR:
+ return (PropertyTreeMergeViewer)getAncestorMergeViewer();
+ case LEFT:
+ return (PropertyTreeMergeViewer)getLeftMergeViewer();
+ case RIGHT:
+ default:
+ return (PropertyTreeMergeViewer)getRightMergeViewer();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation is specialized to set its own specialized content provider during initialization.
+ * The initialization first happens when the base class' constructor is invoked.
+ * </p>
+ */
+ @Override
+ public void setContentProvider(IContentProvider contentProvider) {
+ // If this is the first time this is called, i.e., by the base class constructor...
+ if (getContentProvider() == null) {
+ // Wrap the default content provider with our own delegating implementation.
+ final IMergeViewerContentProvider mergeViewerContentProvider = (IMergeViewerContentProvider)contentProvider;
+ super.setContentProvider(new PropertyContentProvider(mergeViewerContentProvider));
+ } else {
+ super.setContentProvider(contentProvider);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation creates a {@link PropertyContentMergeViewer}.
+ * </p>
+ */
+ @Override
+ protected IMergeViewer createMergeViewer(Composite parent, final MergeViewerSide side) {
+ PropertyTreeMergeViewer propertyMergeViewer = new PropertyTreeMergeViewer(parent, side, this,
+ getCompareConfiguration());
+ hookListeners(propertyMergeViewer);
+ propertyMergeViewer.getStructuredViewer().addTreeListener(treeListener);
+ return propertyMergeViewer;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation creates tool items for showing/hiding advanced properties and for showing/hiding
+ * categories.
+ * </p>
+ *
+ * @see #SHOW_ADVANCED_PROPERTIES
+ * @see #SHOW_CATEGORIES
+ */
+ @Override
+ protected void createToolItems(ToolBarManager toolBarManager) {
+ super.createToolItems(toolBarManager);
+
+ Action showCategories = new ToggleAction(SHOW_CATEGORIES, true,
+ "icons/full/toolb16/show_categories.png", "PropertyContentMergeViewer.hideCategories.tooltip", //$NON-NLS-1$ //$NON-NLS-2$
+ "PropertyContentMergeViewer.showCategories.tooltip"); //$NON-NLS-1$
+ toolBarManager.add(new ActionContributionItem(showCategories));
+
+ Action showAdvancedProperties = new ToggleAction(SHOW_ADVANCED_PROPERTIES, false,
+ "icons/full/toolb16/show_advanced_properties.png", //$NON-NLS-1$
+ "PropertyContentMergeViewer.hideAdvancedProperties.tooltip", //$NON-NLS-1$
+ "PropertyContentMergeViewer.showAdvancedProperties.tooltip"); //$NON-NLS-1$
+ toolBarManager.add(new ActionContributionItem(showAdvancedProperties));
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation is specialized to {@link #buildProperties(Object) build the properties} for each of
+ * the three sides of the input.
+ * </p>
+ */
+ @Override
+ public void setInput(Object input) {
+ buildProperties(input);
+ super.setInput(input);
+ }
+
+ /**
+ * Builds the properties corresponding to the input.
+ *
+ * @param input
+ * the {@link #setInput(Object) input}.
+ */
+ private void buildProperties(Object input) {
+ if (input instanceof CompareInputAdapter) {
+ CompareInputAdapter compareInputAdapter = (CompareInputAdapter)input;
+ Notifier target = compareInputAdapter.getTarget();
+ if (target instanceof TreeNode) {
+ TreeNode treeNode = (TreeNode)target;
+ buildPropertiesFromTreeNode(treeNode, true);
+ return;
+ }
+ }
+ buildPropertiesFromSides(null, null, null);
+ }
+
+ /**
+ * Builds the properties corresponding to the tree node of the input. This is only called if the
+ * {@link #setInput(Object) input} is a {@link CompareInputAdapter} whose
+ * {@link CompareInputAdapter#getTarget() target} is {@link TreeNode}.
+ *
+ * @param treeNode
+ * the tree node.
+ * @param visitParent
+ * whether to visit the parent while visiting this tree node.
+ */
+ @SuppressWarnings("restriction")
+ private void buildPropertiesFromTreeNode(TreeNode treeNode, boolean visitParent) {
+ EObject data = treeNode.getData();
+
+ if (treeNode instanceof DiffNode) {
+ // If there is a refined diff, build the properties using that, but of course don't visit the
+ // parent while doing so, or we'd end up with a stack overflow.
+ TreeNode refinedDiff = getFirst(((DiffNode)treeNode).getRefinedDiffs(), null);
+ if (refinedDiff != null) {
+ // Then ensures that, for example, when a shape is moved, we see the properties for the object
+ // on which the coordinates are changing.
+ buildPropertiesFromTreeNode(refinedDiff, false);
+ setInitialItemsForProperties(data);
+ return;
+ }
+
+ if (visitParent) {
+ TreeNode parent = treeNode.getParent();
+ if (parent != null) {
+ buildPropertiesFromTreeNode(parent, true);
+ setInitialItemsForProperties(data);
+ return;
+ }
+ }
+ }
+
+ buildPropertiesFromEObject(data);
+ setInitialItemsForProperties(data);
+ }
+
+ /**
+ * Builds the properties corresponding to a tree node's {@link TreeNode#getData() data}.
+ *
+ * @param eObject
+ * the data object.
+ * @see #buildPropertiesFromSides(Object, Object, Object)
+ */
+ private void buildPropertiesFromEObject(EObject eObject) {
+ if (eObject instanceof Match) {
+ // If it's a match, get the sides from the match.
+ Match match = (Match)eObject;
+ EObject effectiveAncestor = match.getOrigin();
+ EObject effectiveLeft = match.getLeft();
+ EObject effectiveRight = match.getRight();
+
+ // If they're all null, and there is a containing match, populate using that instead.
+ if (effectiveAncestor == null && effectiveLeft == null && effectiveRight == null) {
+ EObject eContainer = match.eContainer();
+ if (eContainer instanceof Match) {
+ buildPropertiesFromEObject(eContainer);
+ }
+ } else {
+ // Otherwise build using the tree sides.
+ buildPropertiesFromSides(effectiveAncestor, effectiveLeft, effectiveRight);
+ }
+ } else if (eObject instanceof Diff) {
+ // If it's a diff, build using the containing match.
+ Diff diff = (Diff)eObject;
+ buildPropertiesFromEObject(diff.getMatch());
+ setInitialItemsForProperties(diff);
+ } else if (eObject instanceof MatchResource) {
+ // If it's a match resource, build directly from the three side resources.
+ MatchResource matchResource = (MatchResource)eObject;
+ buildPropertiesFromSides(matchResource.getOrigin(), matchResource.getLeft(),
+ matchResource.getRight());
+ } else if (eObject instanceof Equivalence) {
+ // If it's an equivalence, use the first diff.
+ Equivalence equivalence = (Equivalence)eObject;
+ EList<Diff> differences = equivalence.getDifferences();
+ Diff first = Iterables.getFirst(differences, null);
+ buildPropertiesFromEObject(first);
+ } else if (eObject instanceof Conflict) {
+ // If it's a conflict, use the first diff.
+ Conflict conflict = (Conflict)eObject;
+ EList<Diff> differences = conflict.getDifferences();
+ Diff first = Iterables.getFirst(differences, null);
+ buildPropertiesFromEObject(first);
+ }
+ }
+
+ /**
+ * Builds the {@link #ancestorPropertyAccessor}, {@link #leftPropertyAccessor}, and
+ * {@link #rightPropertyAccessor} from the given sides.
+ *
+ * @param origin
+ * the origin.
+ * @param left
+ * the left.
+ * @param right
+ * the right.
+ */
+ private void buildPropertiesFromSides(Object origin, Object left, Object right) {
+ EMFCompareConfiguration configuration = getCompareConfiguration();
+ ancestorPropertyAccessor = new PropertyAccessor(configuration, origin, MergeViewerSide.ANCESTOR);
+ leftPropertyAccessor = new PropertyAccessor(configuration, left,
+ getEffectiveSide(MergeViewerSide.LEFT));
+ rightPropertyAccessor = new PropertyAccessor(configuration, right,
+ getEffectiveSide(MergeViewerSide.RIGHT));
+
+ ancestorPropertyAccessor.rootPropertyItem.reconcile(leftPropertyAccessor.rootPropertyItem,
+ rightPropertyAccessor.rootPropertyItem);
+ }
+
+ /**
+ * Updates the {@link PropertyAccessor#setInitialItem(Diff) initial item} based on the given object. If
+ * the object is a {@link Diff} that is used, otherwise {@code null} is used.
+ *
+ * @param eObject
+ * the object.
+ */
+ private void setInitialItemsForProperties(EObject eObject) {
+ Diff diff = null;
+ if (eObject instanceof Diff) {
+ diff = (Diff)eObject;
+ }
+ ancestorPropertyAccessor.setInitialItem(diff);
+ leftPropertyAccessor.setInitialItem(diff);
+ rightPropertyAccessor.setInitialItem(diff);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation {@link #buildProperties(Object) re-builds the properties}, and attempts to preserve
+ * the selection before calling {@code super.refresh()}.
+ * </p>
+ */
+ @Override
+ public void refresh() {
+ buildProperties(getInput());
+ for (MergeViewerSide side : MERGE_VIEWER_SIDES) {
+ PropertyTreeMergeViewer propertyMergeViewer = getPropertyMergeViewer(side);
+ ISelection selection = propertyMergeViewer.getSelection();
+ PropertyItem selectedItem = null;
+ if (!selection.isEmpty()) {
+ selectedItem = (PropertyItem)((IStructuredSelection)selection).getFirstElement();
+ }
+ switch (side) {
+ case ANCESTOR:
+ ancestorPropertyAccessor.setInitialItem(selectedItem);
+ break;
+ case LEFT:
+ leftPropertyAccessor.setInitialItem(selectedItem);
+ break;
+ case RIGHT:
+ rightPropertyAccessor.setInitialItem(selectedItem);
+ break;
+ }
+ }
+ super.refresh();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation substitutes {@link #ancestorPropertyAccessor}, {@link #leftPropertyAccessor}, and
+ * {@link #rightPropertyAccessor} in place of {@code ancestor}, {@code left}, and {@code right}. It also
+ * switches the left and right if {@link IEMFCompareConfiguration#isMirrored() mirrored}.
+ * </p>
+ */
+ @Override
+ protected void updateContent(Object ancestor, Object left, Object right) {
+ if (getCompareConfiguration().isMirrored()) {
+ super.updateContent(ancestorPropertyAccessor, rightPropertyAccessor, leftPropertyAccessor);
+ } else {
+ super.updateContent(ancestorPropertyAccessor, leftPropertyAccessor, rightPropertyAccessor);
+ }
+ }
+
+ private final class PropertyContentProvider implements IMergeViewerContentProvider {
+ private final IMergeViewerContentProvider mergeViewerContentProvider;
+
+ private PropertyContentProvider(IMergeViewerContentProvider mergeViewerContentProvider) {
+ this.mergeViewerContentProvider = mergeViewerContentProvider;
+ }
+
+ public void dispose() {
+ mergeViewerContentProvider.dispose();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ mergeViewerContentProvider.inputChanged(viewer, oldInput, newInput);
+ }
+
+ private String getSideLabel(String baseLabel, MergeViewerSide side) {
+ // Augment the base label with the label of the root object
+ PropertyTreeMergeViewer propertyMergeViewer = getPropertyMergeViewer(side);
+ if (propertyMergeViewer != null && propertyMergeViewer.getRootPropertyItem() != null) {
+ String text = propertyMergeViewer.getRootPropertyItem().getText();
+ if (!text.isEmpty()) {
+ return text + " - " + baseLabel; //$NON-NLS-1$
+ }
+ }
+ return baseLabel;
+ }
+
+ private Image getSideImage(Image baseImage, MergeViewerSide side) {
+ // Substitute the base image with the image of the root object
+ PropertyTreeMergeViewer propertyMergeViewer = getPropertyMergeViewer(side);
+ if (propertyMergeViewer != null && propertyMergeViewer.getRootPropertyItem() != null) {
+ Object image = propertyMergeViewer.getRootPropertyItem().getImage();
+ if (image != null) {
+ return ExtendedImageRegistry.INSTANCE.getImage(image);
+ }
+ }
+ return baseImage;
+ }
+
+ public String getAncestorLabel(Object input) {
+ return getSideLabel(mergeViewerContentProvider.getAncestorLabel(input), MergeViewerSide.ANCESTOR);
+ }
+
+ public Image getAncestorImage(Object input) {
+ return getSideImage(mergeViewerContentProvider.getAncestorImage(input), MergeViewerSide.ANCESTOR);
+ }
+
+ public Object getAncestorContent(Object input) {
+ return mergeViewerContentProvider.getAncestorContent(input);
+ }
+
+ public boolean showAncestor(Object input) {
+ return mergeViewerContentProvider.showAncestor(input);
+ }
+
+ public String getLeftLabel(Object input) {
+ return getSideLabel(mergeViewerContentProvider.getLeftLabel(input), MergeViewerSide.LEFT);
+ }
+
+ public Image getLeftImage(Object input) {
+ return getSideImage(mergeViewerContentProvider.getLeftImage(input), MergeViewerSide.LEFT);
+ }
+
+ public Object getLeftContent(Object input) {
+ return mergeViewerContentProvider.getLeftContent(input);
+ }
+
+ public boolean isLeftEditable(Object input) {
+ return mergeViewerContentProvider.isLeftEditable(input);
+ }
+
+ public void saveLeftContent(Object input, byte[] bytes) {
+ mergeViewerContentProvider.saveLeftContent(input, bytes);
+ }
+
+ public String getRightLabel(Object input) {
+ return getSideLabel(mergeViewerContentProvider.getRightLabel(input), MergeViewerSide.RIGHT);
+ }
+
+ public Image getRightImage(Object input) {
+ return getSideImage(mergeViewerContentProvider.getRightImage(input), MergeViewerSide.RIGHT);
+ }
+
+ public Object getRightContent(Object input) {
+ return mergeViewerContentProvider.getRightContent(input);
+ }
+
+ public boolean isRightEditable(Object input) {
+ return mergeViewerContentProvider.isRightEditable(input);
+ }
+
+ public void saveRightContent(Object input, byte[] bytes) {
+ mergeViewerContentProvider.saveRightContent(input, bytes);
+ }
+ }
+
+ private final class ToggleAction extends Action {
+ private final String propertyKey;
+
+ private final String checkedTooltip;
+
+ private final String uncheckedTooltip;
+
+ public ToggleAction(String propertyKey, boolean propertyDefaultValue, String imageLocation,
+ String checkedTooltipKey, String uncheckedTooltipKey) {
+ this.propertyKey = propertyKey;
+ checkedTooltip = EMFCompareIDEUIMessages.getString(checkedTooltipKey);
+ uncheckedTooltip = EMFCompareIDEUIMessages.getString(uncheckedTooltipKey);
+ setChecked(getCompareConfiguration().getBooleanProperty(propertyKey, propertyDefaultValue));
+ setImageDescriptor(EMFCompareIDEUIPlugin.getImageDescriptor(imageLocation));
+ updateToolTipText();
+ }
+
+ @Override
+ public void run() {
+ getCompareConfiguration().setProperty(propertyKey, Boolean.valueOf(isChecked()));
+ refresh();
+ updateToolTipText();
+ }
+
+ private void updateToolTipText() {
+ final String toolTipText;
+ if (isChecked()) {
+ toolTipText = checkedTooltip;
+ } else {
+ toolTipText = uncheckedTooltip;
+ }
+ setToolTipText(toolTipText);
+ }
+ }
+
+}

Back to the top