From a069c1062731dd7bb83b2795e4edd66f838d9c68 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 9 Sep 2013 17:37:39 -0700 Subject: [PATCH 01/18] [Refresh] Add initial refresh button --- .../arc/mct/gui/housing/MCTContentArea.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java index 8b582e1c..b9302638 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java @@ -29,11 +29,14 @@ package gov.nasa.arc.mct.gui.housing; import gov.nasa.arc.mct.components.AbstractComponent; +import gov.nasa.arc.mct.gui.ActionContext; import gov.nasa.arc.mct.gui.CompositeViewManifestationProvider; +import gov.nasa.arc.mct.gui.ContextAwareAction; import gov.nasa.arc.mct.gui.SelectionProvider; import gov.nasa.arc.mct.gui.SettingsButton; import gov.nasa.arc.mct.gui.View; import gov.nasa.arc.mct.gui.ViewProvider; +import gov.nasa.arc.mct.gui.actions.RefreshAction; import gov.nasa.arc.mct.gui.housing.MCTHousing.ControlProvider; import gov.nasa.arc.mct.gui.impl.ActionContextImpl; import gov.nasa.arc.mct.gui.menu.MenuFactory; @@ -61,6 +64,7 @@ import javax.swing.Box; import javax.swing.BoxLayout; +import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; @@ -401,6 +405,7 @@ public void actionPerformed(ActionEvent e) { // Only enable control toggle if control manifestation not null. controlToggle.setEnabled(controlManifestation != null); add(Box.createHorizontalGlue()); + add(new RefreshButton()); add(controlToggle); // Add popup listener to title bar. @@ -467,5 +472,26 @@ public boolean setHousedViewManifestation(ViewInfo viewInfo) { return true; } - + private class RefreshButton extends JButton { + private ContextAwareAction action = new RefreshAction(); + + public RefreshButton() { + this.setAction(action); + this.setText("REFRESH"); + update(); + } + + public void update() { + setVisible(action.canHandle(context)); + setEnabled(action.isEnabled()); + } + + private ActionContext context = new ActionContextImpl() { + @Override + public View getWindowManifestation() { + return parentHousing.getHousedViewManifestation(); + } + }; + } + } From 43e02d95dd7996a6abd8fa0053ef8b6db1379fe7 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 10:05:57 -0700 Subject: [PATCH 02/18] [Refresh] Add button class for ContextAwareActions --- .../nasa/arc/mct/gui/ContextAwareButton.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java diff --git a/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java b/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java new file mode 100644 index 00000000..19c98345 --- /dev/null +++ b/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Mission Control Technologies, Copyright (c) 2009-2012, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * The MCT platform is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * MCT includes source code licensed under additional open source licenses. See + * the MCT Open Source Licenses file included with this distribution or the About + * MCT Licenses dialog available at runtime from the MCT Help menu for additional + * information. + *******************************************************************************/ +package gov.nasa.arc.mct.gui; + +import javax.swing.Action; +import javax.swing.JButton; + +/** + * A button containing a context aware action. + * Sets its enabled/disabled state in response to context + * changes. Must be notified of these context changes explicitly. + * + * @author vwoeltje + * + */ +public class ContextAwareButton extends JButton { + private static final long serialVersionUID = -2380576132488962171L; + + /** + * Create a new button for the specified action. + * @param action the action to perform when the button is clicked + */ + public ContextAwareButton(ContextAwareAction action) { + super(action); + } + + @Override + public void setText(String text) { + // If text is not the action name, make a tool tip + Object name = getAction().getValue(Action.NAME); + if (name != null && !name.equals(text)) { + this.setToolTipText(name.toString()); + } + super.setText(text); + } + + /** + * Set the context for the current action. + * Button will enable/disable based on the action's + * state with regard to the current context. + * + * This method should be called whenever the action's + * context may have meaningfully changed. Otherwise, + * the action performed by the button may be outdated. + * + * @param context the context for this action + */ + public void setContext(ActionContext context) { + if (context != null) { + Action a = getAction(); + if (a instanceof ContextAwareAction) { + ContextAwareAction action = (ContextAwareAction) a; + setVisible(action.canHandle(context)); + setEnabled(action.isEnabled()); + } + } else { + setVisible(false); + setEnabled(false); + } + } +} From d91da5b1e7a53578f73723fe4cce261a6b8a4c4a Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 10:07:11 -0700 Subject: [PATCH 03/18] [Refresh] Add refresh button to center pane Complete nasa/mct#138 by adding a refresh button to the center pane (in the title bar of the content area). Triggers the Refresh Now action. --- .../arc/mct/gui/housing/MCTContentArea.java | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java index b9302638..cb6e53f8 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java @@ -31,7 +31,7 @@ import gov.nasa.arc.mct.components.AbstractComponent; import gov.nasa.arc.mct.gui.ActionContext; import gov.nasa.arc.mct.gui.CompositeViewManifestationProvider; -import gov.nasa.arc.mct.gui.ContextAwareAction; +import gov.nasa.arc.mct.gui.ContextAwareButton; import gov.nasa.arc.mct.gui.SelectionProvider; import gov.nasa.arc.mct.gui.SettingsButton; import gov.nasa.arc.mct.gui.View; @@ -44,6 +44,7 @@ import gov.nasa.arc.mct.services.component.ViewInfo; import gov.nasa.arc.mct.services.component.ViewType; import gov.nasa.arc.mct.util.LafColor; +import gov.nasa.arc.mct.util.MCTIcons; import java.awt.BorderLayout; import java.awt.Color; @@ -62,9 +63,11 @@ import java.util.Map; import java.util.ResourceBundle; +import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; -import javax.swing.JButton; +import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; @@ -83,7 +86,16 @@ @SuppressWarnings("serial") public class MCTContentArea extends JPanel implements CompositeViewManifestationProvider, SelectionProvider, ControlProvider { - public static final String CENTER_PANE_VIEW_CHANGE = "center-pane-view-change"; + public static final String CENTER_PANE_VIEW_CHANGE = "center-pane-view-change"; + + private static final Icon REFRESH_ICON = MCTIcons.processIcon( + new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), + 0.9f, 0.9f, 0.9f, false); + private static final Icon REFRESH_ICON_PRESSED = MCTIcons.processIcon( + new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), + 1f, 1f, 1f, false); + + private MCTHousing parentHousing; private final AbstractComponent ownerComponent; private CanvasTitleArea titleBar; @@ -97,6 +109,8 @@ public class MCTContentArea extends JPanel implements CompositeViewManifestation private final Map housedManifestations = new HashMap(); + private ContextAwareButton refreshButton = new ContextAwareButton(new RefreshAction()); + private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( MCTStandardHousing.class.getName().substring(0, @@ -133,6 +147,8 @@ public MCTContentArea(MCTHousing parentHousing, AbstractComponent ownerComponent setOwnerComponentCanvasManifestation(ownerComponentCanvasManifestation); this.revalidate(); this.parentHousing.setContentArea(this); + this.refreshButton.setContext(context); + configureRefreshButtonAppearance(); STALE_LABEL.setForeground(Color.red); } @@ -221,7 +237,8 @@ public JComponent getContentAreaPane() { } public void setParentHousing(MCTHousing parentHousing) { - this.parentHousing = parentHousing; + this.parentHousing = parentHousing; + this.refreshButton.setContext(context); } /** @@ -292,6 +309,7 @@ public void setOwnerComponentCanvasManifestation(View viewManifestation) { add(scrollPane); } + this.refreshButton.setContext(context); revalidate(); } @@ -364,6 +382,14 @@ private boolean containsMCTViewManifestation(Container parent) { void clearHousedManifestations() { housedManifestations.clear(); } + + private void configureRefreshButtonAppearance() { + refreshButton.setIcon(REFRESH_ICON); + refreshButton.setPressedIcon(REFRESH_ICON_PRESSED); + refreshButton.setContentAreaFilled(false); + refreshButton.setText(""); + refreshButton.setBorder(BorderFactory.createEmptyBorder()); + } private class CanvasTitleArea extends JPanel { private final Color BACKGROUND_COLOR = LafColor.WINDOW_BORDER.darker(); @@ -405,7 +431,7 @@ public void actionPerformed(ActionEvent e) { // Only enable control toggle if control manifestation not null. controlToggle.setEnabled(controlManifestation != null); add(Box.createHorizontalGlue()); - add(new RefreshButton()); + add(refreshButton); add(controlToggle); // Add popup listener to title bar. @@ -471,27 +497,14 @@ public boolean setHousedViewManifestation(ViewInfo viewInfo) { setOwnerComponentCanvasManifestation(newView); return true; } - - private class RefreshButton extends JButton { - private ContextAwareAction action = new RefreshAction(); - - public RefreshButton() { - this.setAction(action); - this.setText("REFRESH"); - update(); - } - - public void update() { - setVisible(action.canHandle(context)); - setEnabled(action.isEnabled()); - } - - private ActionContext context = new ActionContextImpl() { - @Override - public View getWindowManifestation() { - return parentHousing.getHousedViewManifestation(); - } - }; - } + + // Used to provide a context for buttons + private ActionContext context = new ActionContextImpl() { + @Override + public View getWindowManifestation() { + return parentHousing.getHousedViewManifestation(); + } + }; + } From 21e02dd02adfc742754313d9c72ff3a7635911ef Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 10:29:20 -0700 Subject: [PATCH 04/18] [Refresh] Unit test ContextAwareButton --- .../nasa/arc/mct/gui/ContextAwareButton.java | 14 +++ .../arc/mct/gui/TestContextAwareButton.java | 103 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java diff --git a/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java b/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java index 19c98345..b1d231d9 100644 --- a/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java +++ b/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java @@ -40,7 +40,21 @@ public class ContextAwareButton extends JButton { * @param action the action to perform when the button is clicked */ public ContextAwareButton(ContextAwareAction action) { + this(action, null); + } + + /** + * Create a new button for the specified action. + * Provide an initial context, used to determine + * visible/enabled states (and typically to also + * inform the actual behavior of the button.) + * + * @param action the action to perform when the button is clicked + * @param context the context for this action + */ + public ContextAwareButton(ContextAwareAction action, ActionContext context) { super(action); + setContext(context); } @Override diff --git a/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java b/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java new file mode 100644 index 00000000..985a12e4 --- /dev/null +++ b/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java @@ -0,0 +1,103 @@ +package gov.nasa.arc.mct.gui; + +import javax.swing.Action; + +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class TestContextAwareButton { + + private static final String ACTION_NAME = "Mock"; + + @Mock private ContextAwareAction action; + @Mock private ActionContext context; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + Mockito.when(action.getValue(Action.NAME)).thenReturn(ACTION_NAME); + } + + @Test + public void testNoContext() { + // Button should not be visible if no context has been provided + ContextAwareButton button = new ContextAwareButton(action); + Assert.assertFalse(button.isEnabled()); + Assert.assertFalse(button.isVisible()); + + // Should behave similarly if context is explicitly null + button = new ContextAwareButton(action, null); + Assert.assertFalse(button.isEnabled()); + Assert.assertFalse(button.isVisible()); + } + + @Test + public void testContext() { + // Should invoke canHandle for the specified context + new ContextAwareButton(action, context); + Mockito.verify(action).canHandle(context); + Mockito.verify(action, Mockito.atLeastOnce()).isEnabled(); + } + + @Test + public void testSetContext() { + // Should invoke canHandle for the specified context + new ContextAwareButton(action).setContext(context); + Mockito.verify(action).canHandle(context); + Mockito.verify(action, Mockito.atLeastOnce()).isEnabled(); + } + + @Test (dataProvider="generateStates") + public void testState(boolean canHandle, boolean isEnabled, boolean useConstructor) { + // Set up states + Mockito.when(action.canHandle(context)).thenReturn(canHandle); + Mockito.when(action.isEnabled()).thenReturn(isEnabled); + + // Make the button + ContextAwareButton button = useConstructor ? + new ContextAwareButton(action, context) : + new ContextAwareButton(action); + if (!useConstructor) { + button.setContext(context); + } + + // Verify visibility/enabled states match what the action reports + Assert.assertEquals(button.isVisible(), canHandle); + Assert.assertEquals(button.isEnabled(), isEnabled); + } + + @Test + public void testToolTip() { + // Tool tip should show action name if text set to something else + ContextAwareButton button = new ContextAwareButton(action); + + // Should not have a tool tip by default + Assert.assertTrue(button.getToolTipText() == null || button.getToolTipText().isEmpty()); + + // Setting text to same action name should not change tool tip + button.setText(ACTION_NAME); + Assert.assertTrue(button.getToolTipText() == null || button.getToolTipText().isEmpty()); + + // Setting text to some other name should change tool tip + button.setText("Something else"); + Assert.assertEquals(button.getToolTipText(), ACTION_NAME); + } + + @DataProvider + public Object[][] generateStates() { + Object[][] result = new Object[8][]; + for (int i = 0; i < result.length; i++) { + result[i] = new Object[]{ + (i & 1) != 0, // canHandle + (i & 2) != 0, // isEnabled + (i & 4) != 0 // useConstructor + }; + } + return result; + } +} From 5b68f319329b7c80b098b91fc7e87276ab59d14b Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 10:34:16 -0700 Subject: [PATCH 05/18] [Refresh] Add refresh icon --- .../main/resources/icons/mct_icon_refresh.png | Bin 0 -> 15521 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/src/main/resources/icons/mct_icon_refresh.png diff --git a/platform/src/main/resources/icons/mct_icon_refresh.png b/platform/src/main/resources/icons/mct_icon_refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..79de9e0fbe5ad195f59455ab7220d01870ade831 GIT binary patch literal 15521 zcmeI3ZEO@p7{{0T0+cioFi4P)^@s+dcYAwp?QQO^X>WV9z}2Hyr9~6i?oRJk?sk{m zz23DLLP*3I10uwPG#bCCseFKtNJ8L)m}r7AiW)RQgP<`nNPPJMiA2$vd%wBs6hn<) z=F;BnGyi%1yZd`)X7|gylo;I5(Y~skVVI7AesKu>qW?wr!*BEYkI%!O#YX?A#V|{j zqyGiW^y@2O<3f8N-na1bqJ>Kxt9Qio0Bl-g_l?*wH3Qf|DGQjaY;RX(UE6MgaT8c+ zm!YLrB|qK7Fv2Z$c*GuwZx&=d>yi|G47dte16nXlsJmcD@=jp0V<4q!VaIQ0-*>R8 z5_W9$$K7!w3esx-lnIhkgTwOFPC2MJx+CqOf&dM&z?RrTHltZWA?zsn3h)>;a}KuH z#oifq^q>>6Bk=?q)lIDgbVn}reak)}4q>jtUaTo1hPBUC z4n?k3!^oMLV$l_u0~wG7nr*>~@QoEwWMN!4vyvTAvr-Cha887{TH}0QpHV4w^)ed< zO;v6lI#o%C>KWaHwEz)sh-=k6-xm!BVLaaYf-9puo8?-~4$JPFfD@-Y5gTr`l4%W3 z8h{%DmYy?Z&^H0gRGW?EITMcy1Da(^nhXZS2)rDZsw#rNuQw?AyZn5w#~tY6`7V#A zrz;xk?Dcx0K9TP!4*bT{#$gLJQI~UQWRz_cWGmj8ZCz@U?USYo*Gef<*9Tqozp-y& z(R7-A)q*R@WM#6HmZsvANrGLCt(CcyQHxW^kW338@?l2>ef>gJazZ)93JQ{p*20L4 zmM)-#xQ5o+W#MURi=xd*x8z-yI=g>94K&iiSF$Shn%%_G$L+jif}Ru{2Xn8;CC|nr z+`P1$Wz_$m1eP>$mj#$}*4$+Q>Yp0_R{?4xS58Y>3Mdh-GH5FecUH4fB^zf`WnIB$ z-@HA;Y<0Z$^3t$oBBlAsfLaB(T)^Qg6{jg5;+ooOw;L*IBWT)Za>f3g9yk1OJo+xD z*2{S6C^@xW##3vVPid+h@s!VoHJ7vI4Jat6vj9a(Gf>o8ddeo@t1pNI{C=-L#No|# zH&>JrY5`YxH~`)b40L zT`@0u5)24Aq`1g@FqPuMfRICqi_8a8DJ~2MIi$GAd@z;b!hn!Nii^w#QzU00(0vdQvxAO_o;>HFkh3if#b_1S8wHZYlF&HyId zulv!5CoV(jivh7`c-@894u=Qt;g`m)9ACG7?2+dV9bS^ywf|!Ot8J9mWUDDRuSr zHK#XDb?;%eT|Kn#<@3EaCgLl$?RewnPg}ljJKFa6)sEAVGmowM^>$&}_1NgeFJpgs xuO4|bc%NpzbNk@~U+un;0GE#CuRZ%m+d~^t;^Acvo`W~X4D=0($9s3|`v;z{?)(4% literal 0 HcmV?d00001 From 32b68d0300c1ba8a66b2b5ef306553fe94721ee8 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 11:06:14 -0700 Subject: [PATCH 06/18] [Refresh] Use component from persistence on refresh --- .../gov/nasa/arc/mct/gui/actions/RefreshAction.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java index 45bf2077..e16c9f0e 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java @@ -21,6 +21,7 @@ *******************************************************************************/ package gov.nasa.arc.mct.gui.actions; +import gov.nasa.arc.mct.components.AbstractComponent; import gov.nasa.arc.mct.defaults.view.MCTHousingViewManifestation; import gov.nasa.arc.mct.gui.ActionContext; import gov.nasa.arc.mct.gui.ContextAwareAction; @@ -105,11 +106,17 @@ public void actionPerformed(ActionEvent e) { hints); doRefresh = input.equals(ok); } - + // Perform the refresh by re-creating view if (doRefresh) { + // Update component from persistence + AbstractComponent comp = contentArea.getHousedViewManifestation().getManifestedComponent(); + comp = PlatformAccess.getPlatform().getPersistenceProvider().getComponent(comp.getComponentId()); + contentArea.getHousedViewManifestation().setManifestedComponent(comp); + + // Re-create view ViewInfo vi = contentArea.getHousedViewManifestation().getInfo(); - View newView = vi.createView(housing.getManifestedComponent()); + View newView = vi.createView(comp); contentArea.setOwnerComponentCanvasManifestation(newView); } } From a48c7b9bd9924f654bcbc7a038e119573cd08daa Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 11:09:48 -0700 Subject: [PATCH 07/18] [Refresh] Update refresh action test --- .../java/gov/nasa/arc/mct/gui/actions/TestRefresh.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java b/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java index 07d0ba53..b5024906 100644 --- a/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java +++ b/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java @@ -27,6 +27,7 @@ import gov.nasa.arc.mct.gui.ContextAwareAction; import gov.nasa.arc.mct.gui.View; import gov.nasa.arc.mct.gui.housing.MCTContentArea; +import gov.nasa.arc.mct.platform.spi.PersistenceProvider; import gov.nasa.arc.mct.platform.spi.Platform; import gov.nasa.arc.mct.platform.spi.PlatformAccess; import gov.nasa.arc.mct.platform.spi.WindowManager; @@ -64,6 +65,7 @@ public class TestRefresh { @Mock private ViewInfo mockViewInfo; @Mock private ActionEvent mockEvent; @Mock private WindowManager mockWindowManager; + @Mock private PersistenceProvider mockPersistence; @BeforeClass public void setup() { @@ -88,6 +90,9 @@ public void setupMethod() { Mockito.when(mockView.getManifestedComponent()).thenReturn(mockComponent); Mockito.when(mockView.getInfo()).thenReturn(mockViewInfo); Mockito.when(mockPlatform.getWindowManager()).thenReturn(mockWindowManager); + Mockito.when(mockPlatform.getPersistenceProvider()).thenReturn(mockPersistence); + Mockito.when(mockPersistence.getComponent(Mockito.anyString())).thenReturn(mockComponent); + Mockito.when(mockComponent.getComponentId()).thenReturn("mock"); } // Test various 'canHandle' responses @@ -128,7 +133,7 @@ public void testActionPerformedNonDirty() { // The newer version of the component, for which a view should be created AbstractComponent newerComponent = Mockito.mock(AbstractComponent.class); - Mockito.when(mockHousing.getManifestedComponent()).thenReturn(newerComponent); + Mockito.when(mockPersistence.getComponent("mock")).thenReturn(newerComponent); // Similarly, newer version of the view View newerView = Mockito.mock(View.class); @@ -160,7 +165,7 @@ public void testActionPerformedDirty(final boolean confirmed) { // The newer version of the component, for which a view should be created AbstractComponent newerComponent = Mockito.mock(AbstractComponent.class); - Mockito.when(mockHousing.getManifestedComponent()).thenReturn(newerComponent); + Mockito.when(mockPersistence.getComponent("mock")).thenReturn(newerComponent); // Similarly, newer version of the view View newerView = Mockito.mock(View.class); From 613d879b00761d8a4c5ce28da99b911e14af959e Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 11:55:20 -0700 Subject: [PATCH 08/18] [Refresh] Add refresh button to Inspector --- .../arc/mct/gui/actions/RefreshAction.java | 42 ++++++++++++------ .../nasa/arc/mct/gui/housing/Inspector.java | 43 +++++++++++++++++-- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java index e16c9f0e..fdae4f6b 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java @@ -27,7 +27,6 @@ import gov.nasa.arc.mct.gui.ContextAwareAction; import gov.nasa.arc.mct.gui.OptionBox; import gov.nasa.arc.mct.gui.View; -import gov.nasa.arc.mct.gui.housing.MCTContentArea; import gov.nasa.arc.mct.gui.impl.WindowManagerImpl; import gov.nasa.arc.mct.platform.spi.PlatformAccess; import gov.nasa.arc.mct.services.component.ViewInfo; @@ -52,7 +51,9 @@ public class RefreshAction extends ContextAwareAction { ThisSaveAllAction.class.getName().substring(0, ThisSaveAllAction.class.getName().lastIndexOf("."))+".Bundle"); //NOI18N + private boolean isHousing; private MCTHousingViewManifestation housing; + private View view; /** * Create the refresh action. @@ -63,11 +64,20 @@ public RefreshAction() { @Override public boolean canHandle(ActionContext context) { - // Store reference to housing for "actionPerformed" - this.housing = (MCTHousingViewManifestation) context.getWindowManifestation(); + // Get the view container whose contents will be refreshed. + this.view = context.getWindowManifestation(); + isHousing = view != null && view instanceof MCTHousingViewManifestation; - // Only valid if we have a center pane - return housing != null && housing.getContentArea() != null; + if (isHousing) { + // Store reference to housing for "actionPerformed" + this.housing = (MCTHousingViewManifestation) context.getWindowManifestation(); + + // Only valid if we have a center pane + return housing != null && housing.getContentArea() != null; + } else { + // Otherwise, we're dealing with some view directly + return view != null && view.getHousedViewManifestation() != null; + } } @Override @@ -80,11 +90,12 @@ public boolean isEnabled() { @Override public void actionPerformed(ActionEvent e) { - MCTContentArea contentArea = housing.getContentArea(); + View housedView = isHousing ? + housing.getContentArea().getHousedViewManifestation() : + view.getHousedViewManifestation(); // Should not be null per canHandle, but check for safety - if (contentArea != null) { - View housedView = contentArea.getHousedViewManifestation(); + if (housedView != null) { boolean doRefresh = true; // Give the user an opportunity to cancel the refresh if it would @@ -110,14 +121,19 @@ public void actionPerformed(ActionEvent e) { // Perform the refresh by re-creating view if (doRefresh) { // Update component from persistence - AbstractComponent comp = contentArea.getHousedViewManifestation().getManifestedComponent(); + AbstractComponent comp = housedView.getManifestedComponent(); comp = PlatformAccess.getPlatform().getPersistenceProvider().getComponent(comp.getComponentId()); - contentArea.getHousedViewManifestation().setManifestedComponent(comp); + housedView.setManifestedComponent(comp); // Re-create view - ViewInfo vi = contentArea.getHousedViewManifestation().getInfo(); - View newView = vi.createView(comp); - contentArea.setOwnerComponentCanvasManifestation(newView); + ViewInfo vi = housedView.getInfo(); + if (isHousing) { + View newView = vi.createView(comp); + housing.getContentArea().setOwnerComponentCanvasManifestation(newView); + } else { + housedView.setManifestedComponent(comp); + view.setHousedViewManifestation(vi); + } } } } diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java index 6f8a91b5..bc4909b5 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java @@ -23,11 +23,15 @@ import gov.nasa.arc.mct.components.AbstractComponent; import gov.nasa.arc.mct.defaults.view.SwitcherView; -import gov.nasa.arc.mct.gui.SettingsButton; +import gov.nasa.arc.mct.gui.ActionContext; +import gov.nasa.arc.mct.gui.ContextAwareButton; import gov.nasa.arc.mct.gui.OptionBox; import gov.nasa.arc.mct.gui.SelectionProvider; +import gov.nasa.arc.mct.gui.SettingsButton; import gov.nasa.arc.mct.gui.View; import gov.nasa.arc.mct.gui.ViewRoleSelection; +import gov.nasa.arc.mct.gui.actions.RefreshAction; +import gov.nasa.arc.mct.gui.impl.ActionContextImpl; import gov.nasa.arc.mct.gui.impl.WindowManagerImpl; import gov.nasa.arc.mct.platform.spi.Platform; import gov.nasa.arc.mct.platform.spi.PlatformAccess; @@ -36,6 +40,7 @@ import gov.nasa.arc.mct.services.component.ViewInfo; import gov.nasa.arc.mct.services.component.ViewType; import gov.nasa.arc.mct.util.LafColor; +import gov.nasa.arc.mct.util.MCTIcons; import java.awt.BorderLayout; import java.awt.Color; @@ -59,6 +64,9 @@ import java.util.ResourceBundle; import java.util.Set; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; @@ -76,7 +84,13 @@ public class Inspector extends View { private static final Color BACKGROUND_COLOR = LafColor.WINDOW_BORDER.darker(); private static final Color FOREGROUND_COLOR = LafColor.WINDOW.brighter(); - + private static final Icon REFRESH_ICON = MCTIcons.processIcon( + new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), + 0.9f, 0.9f, 0.9f, false); + private static final Icon REFRESH_ICON_PRESSED = MCTIcons.processIcon( + new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), + 1f, 1f, 1f, false); + private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( Inspector.class.getName().substring(0, @@ -136,6 +150,7 @@ public void propertyChange(PropertyChangeEvent evt) { private JPanel statusbar = new JPanel(); private GridBagConstraints c = new GridBagConstraints(); private JToggleButton controlAreaToggle = new SettingsButton(); + private ContextAwareButton refreshButton = new ContextAwareButton(new RefreshAction()); public Inspector(AbstractComponent ac, ViewInfo vi) { super(ac,vi); @@ -183,12 +198,22 @@ public void actionPerformed(ActionEvent e) { STALE_LABEL.setForeground(Color.red); content = emptyPanel; setMinimumSize(new Dimension(0, 0)); + + configureRefreshButtonAppearance(); + refreshButton.setContext(context); } public AbstractComponent getCurrentlyShowingComponent() { return view.getManifestedComponent(); } + private ActionContext context = new ActionContextImpl() { + @Override + public View getWindowManifestation() { + return Inspector.this; + } + }; + /** * Prompt the user to commit or abort pending changes, * if there are any. Note that this may not be possible @@ -281,6 +306,8 @@ private void refreshInspector(ViewInfo viewInfo) { STALE_LABEL.setVisible(false); populateStatusBar(); + refreshButton.setContext(context); + view.requestFocusInWindow(); } @@ -327,6 +354,7 @@ private void selectedManifestationChanged(View view) { switcher.addMonitoredGUI(this); switcher.setForeground(FOREGROUND_COLOR); p.setOpaque(false); + p.add(refreshButton, BorderLayout.WEST); p.add(switcher, BorderLayout.CENTER); p.add(controlAreaToggle, BorderLayout.EAST); titlebar.add(p, c); @@ -344,6 +372,9 @@ private void selectedManifestationChanged(View view) { ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); content = inspectorScrollPane; add(inspectorScrollPane, BorderLayout.CENTER); + + refreshButton.setContext(context); + revalidate(); } @@ -422,7 +453,13 @@ public void exitLockedState() { view.exitLockedState(); } - + private void configureRefreshButtonAppearance() { + refreshButton.setIcon(REFRESH_ICON); + refreshButton.setPressedIcon(REFRESH_ICON_PRESSED); + refreshButton.setContentAreaFilled(false); + refreshButton.setText(""); + refreshButton.setBorder(BorderFactory.createEmptyBorder()); + } @Override public boolean setHousedViewManifestation(ViewInfo viewInfo) { From 9d4266b53b3785ddd77f1681bef04b8a04ed39e6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 13:01:51 -0700 Subject: [PATCH 09/18] [Refresh] Verify Inspector support in test --- .../nasa/arc/mct/gui/actions/TestRefresh.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java b/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java index b5024906..fafd03c2 100644 --- a/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java +++ b/platform/src/test/java/gov/nasa/arc/mct/gui/actions/TestRefresh.java @@ -66,6 +66,7 @@ public class TestRefresh { @Mock private ActionEvent mockEvent; @Mock private WindowManager mockWindowManager; @Mock private PersistenceProvider mockPersistence; + @Mock private View mockInspector; @BeforeClass public void setup() { @@ -86,6 +87,7 @@ public void setupMethod() { Mockito.when(mockContext.getWindowManifestation()).thenReturn(mockHousing); Mockito.when(mockHousing.getContentArea()).thenReturn(mockContentArea); Mockito.when(mockContentArea.getHousedViewManifestation()).thenReturn(mockView); + Mockito.when(mockInspector.getHousedViewManifestation()).thenReturn(mockView); Mockito.when(mockHousing.getManifestedComponent()).thenReturn(mockComponent); Mockito.when(mockView.getManifestedComponent()).thenReturn(mockComponent); Mockito.when(mockView.getInfo()).thenReturn(mockViewInfo); @@ -212,4 +214,21 @@ public Object answer(InvocationOnMock invocation) throws Throwable { public Object[][] truthData() { return new Object[][] { {true} , {false} }; } + + // An Inspector has some differences from ContentArea - verify that it is refreshable too + @Test + public void testInspector() { + // Verify interactions with a mock inspector + Mockito.when(mockContext.getWindowManifestation()).thenReturn(mockInspector); + + // Verify that refresh can handle, is enabled for an Inspector + ContextAwareAction refresh = new RefreshAction(); + Assert.assertTrue(refresh.canHandle(mockContext)); + Assert.assertTrue(refresh.isEnabled()); + + // Verify actionPerformed triggers appropriate method + refresh.actionPerformed(mockEvent); + Mockito.verify(mockInspector).setHousedViewManifestation(mockViewInfo); + } } + From 9d79d016ccdfc03ddb4d3bad4d9c28daff5af1dd Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 13:36:31 -0700 Subject: [PATCH 10/18] [Icons] Adjust look of settings/refresh icons Adjust appearance of settings icon, refresh icon, and switcher view to match more closely with provided mock-ups and other specifications. Specifically, add drop shadow to refresh and settings and tweak alignment of these buttons around the view switcher. --- .../nasa/arc/mct/gui/ContextAwareButton.java | 14 +++++++++ .../gov/nasa/arc/mct/gui/SettingsButton.java | 30 ++++++------------- .../arc/mct/defaults/view/SwitcherView.java | 9 +++--- .../arc/mct/gui/actions/RefreshAction.java | 11 ++++++- .../nasa/arc/mct/gui/housing/Inspector.java | 22 ++------------ .../arc/mct/gui/housing/MCTContentArea.java | 27 ++++------------- 6 files changed, 47 insertions(+), 66 deletions(-) diff --git a/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java b/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java index b1d231d9..8dbbeb5a 100644 --- a/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java +++ b/mctcore/src/main/java/gov/nasa/arc/mct/gui/ContextAwareButton.java @@ -21,7 +21,11 @@ *******************************************************************************/ package gov.nasa.arc.mct.gui; +import gov.nasa.arc.mct.util.MCTIcons; + import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JButton; /** @@ -57,6 +61,16 @@ public ContextAwareButton(ContextAwareAction action, ActionContext context) { setContext(context); } + @Override + public void setIcon(Icon icon) { + if (icon != null && icon instanceof ImageIcon) { + super.setIcon(MCTIcons.processIcon((ImageIcon) icon, .9f, .9f, .9f, true)); + super.setPressedIcon(MCTIcons.processIcon((ImageIcon) icon, 1f, 1f, 1f, true)); + } else { + super.setIcon(icon); + } + } + @Override public void setText(String text) { // If text is not the action name, make a tool tip diff --git a/mctcore/src/main/java/gov/nasa/arc/mct/gui/SettingsButton.java b/mctcore/src/main/java/gov/nasa/arc/mct/gui/SettingsButton.java index 080cbdb3..3a98164d 100644 --- a/mctcore/src/main/java/gov/nasa/arc/mct/gui/SettingsButton.java +++ b/mctcore/src/main/java/gov/nasa/arc/mct/gui/SettingsButton.java @@ -24,7 +24,6 @@ import gov.nasa.arc.mct.util.MCTIcons; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; @@ -47,34 +46,18 @@ public class SettingsButton extends JToggleButton { private static final Icon CONFIG_DESELECTED = MCTIcons.processIcon( new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_config.png")), - 0.9f, 0.9f, 0.9f, false); + 0.9f, 0.9f, 0.9f, true); private static final Icon CONFIG_SELECTED = MCTIcons.processIcon( new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_config.png")), - 1f, 1f, 1f, false); - private static final Icon CONFIG_DISABLED = new Icon() { - @Override - public void paintIcon(Component c, Graphics g, int x, int y) { - // Do not paint when disabled - } - - @Override - public int getIconWidth() { - return CONFIG_SELECTED.getIconWidth(); - } - - @Override - public int getIconHeight() { - return CONFIG_SELECTED.getIconHeight(); - } - }; + 1f, 1f, 1f, true); private static final Color SELECTED_BACKGROUND = new Color(193, 193, 193); private static final Color SELECTED_BORDER = new Color(138, 138, 138); private static final Color FOCUS_BORDER = new Color(138, 138, 200); private static final Dimension PREFERRED_SIZE = - new Dimension(19, 17); + new Dimension(17, 17); /** * Create a new configuration button. @@ -86,11 +69,16 @@ public SettingsButton() { setBorder(BorderFactory.createEmptyBorder()); setOpaque(false); setIcon(CONFIG_DESELECTED); - setDisabledIcon(CONFIG_DISABLED); setSelectedIcon(CONFIG_SELECTED); setSelected(false); } + @Override + public void setEnabled(boolean enabled) { + setVisible(enabled); + super.setEnabled(enabled); + } + @Override public void paintComponent(Graphics g) { if (isSelected()) { diff --git a/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java b/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java index 54adc85a..e967e852 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java +++ b/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java @@ -84,7 +84,7 @@ public SwitcherView(AbstractComponent ac, ViewInfo vi) { comboBox.setVisible(false); comboBox.setEnabled(false); comboBox.setOpaque(false); - comboBox.setFont(comboBox.getFont().deriveFont(FONT_SIZE)); + //comboBox.setFont(comboBox.getFont().deriveFont(FONT_SIZE)); add(comboBox); } else if (viewInfos.length == 1) { // Otherwise, just show the one available view as a label @@ -96,6 +96,7 @@ public SwitcherView(AbstractComponent ac, ViewInfo vi) { // No views to show } + setBorder(BorderFactory.createEmptyBorder(1,4,1,2)); setOpaque(false); } @@ -200,7 +201,7 @@ public void paint(Graphics g, JComponent c) { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } g.setColor(c.getBackground()); - g.fillRoundRect(0, 1, c.getWidth()-2, c.getHeight()-2, 10, 10); + g.fillRoundRect(0, 1, c.getWidth()-1, c.getHeight()-2, 10, 10); super.paint(g, c); } @@ -220,8 +221,8 @@ public void paintCurrentValueBackground(Graphics g, Rectangle bounds, boolean ha private static final Icon ARROW_ICON = new Icon() { @Override public void paintIcon(Component c, Graphics g, int x, int y) { - int tx[] = { 2, 10, 6 }; - int ty[] = { 7, 7, 11 }; + int tx[] = { 3, 11, 7 }; + int ty[] = { 6, 6, 10 }; if (g instanceof Graphics2D) { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java index fdae4f6b..acfae352 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java @@ -36,6 +36,10 @@ import java.util.Map; import java.util.ResourceBundle; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; + /** * The "Refresh Now" menu option. Causes the view in the * center pane to be re-created with the latest version @@ -50,7 +54,10 @@ public class RefreshAction extends ContextAwareAction { ResourceBundle.getBundle( ThisSaveAllAction.class.getName().substring(0, ThisSaveAllAction.class.getName().lastIndexOf("."))+".Bundle"); //NOI18N - + private static final Icon ICON = + new ImageIcon(RefreshAction.class.getResource("/icons/mct_icon_refresh.png")); + + private boolean isHousing; private MCTHousingViewManifestation housing; private View view; @@ -60,6 +67,8 @@ public class RefreshAction extends ContextAwareAction { */ public RefreshAction() { super(BUNDLE.getString("RefreshAction.label")); //NOI18N + this.putValue(Action.SMALL_ICON, ICON); + this.putValue(Action.LARGE_ICON_KEY, ICON); } @Override diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java index bc4909b5..1f6380ca 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/Inspector.java @@ -40,7 +40,6 @@ import gov.nasa.arc.mct.services.component.ViewInfo; import gov.nasa.arc.mct.services.component.ViewType; import gov.nasa.arc.mct.util.LafColor; -import gov.nasa.arc.mct.util.MCTIcons; import java.awt.BorderLayout; import java.awt.Color; @@ -64,9 +63,6 @@ import java.util.ResourceBundle; import java.util.Set; -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; @@ -84,12 +80,6 @@ public class Inspector extends View { private static final Color BACKGROUND_COLOR = LafColor.WINDOW_BORDER.darker(); private static final Color FOREGROUND_COLOR = LafColor.WINDOW.brighter(); - private static final Icon REFRESH_ICON = MCTIcons.processIcon( - new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), - 0.9f, 0.9f, 0.9f, false); - private static final Icon REFRESH_ICON_PRESSED = MCTIcons.processIcon( - new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), - 1f, 1f, 1f, false); private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( @@ -199,7 +189,9 @@ public void actionPerformed(ActionEvent e) { content = emptyPanel; setMinimumSize(new Dimension(0, 0)); - configureRefreshButtonAppearance(); + refreshButton.setContentAreaFilled(false); + refreshButton.setText(""); + refreshButton.setBorder(null); refreshButton.setContext(context); } @@ -453,14 +445,6 @@ public void exitLockedState() { view.exitLockedState(); } - private void configureRefreshButtonAppearance() { - refreshButton.setIcon(REFRESH_ICON); - refreshButton.setPressedIcon(REFRESH_ICON_PRESSED); - refreshButton.setContentAreaFilled(false); - refreshButton.setText(""); - refreshButton.setBorder(BorderFactory.createEmptyBorder()); - } - @Override public boolean setHousedViewManifestation(ViewInfo viewInfo) { AbstractComponent ac = view.getManifestedComponent(); diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java index cb6e53f8..3187c823 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/housing/MCTContentArea.java @@ -44,7 +44,6 @@ import gov.nasa.arc.mct.services.component.ViewInfo; import gov.nasa.arc.mct.services.component.ViewType; import gov.nasa.arc.mct.util.LafColor; -import gov.nasa.arc.mct.util.MCTIcons; import java.awt.BorderLayout; import java.awt.Color; @@ -66,8 +65,6 @@ import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; -import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; @@ -87,14 +84,6 @@ public class MCTContentArea extends JPanel implements CompositeViewManifestationProvider, SelectionProvider, ControlProvider { public static final String CENTER_PANE_VIEW_CHANGE = "center-pane-view-change"; - - private static final Icon REFRESH_ICON = MCTIcons.processIcon( - new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), - 0.9f, 0.9f, 0.9f, false); - private static final Icon REFRESH_ICON_PRESSED = MCTIcons.processIcon( - new ImageIcon(SettingsButton.class.getResource("/icons/mct_icon_refresh.png")), - 1f, 1f, 1f, false); - private MCTHousing parentHousing; private final AbstractComponent ownerComponent; @@ -147,8 +136,12 @@ public MCTContentArea(MCTHousing parentHousing, AbstractComponent ownerComponent setOwnerComponentCanvasManifestation(ownerComponentCanvasManifestation); this.revalidate(); this.parentHousing.setContentArea(this); - this.refreshButton.setContext(context); - configureRefreshButtonAppearance(); + + refreshButton.setContentAreaFilled(false); + refreshButton.setText(""); + refreshButton.setBorder(BorderFactory.createEmptyBorder()); + refreshButton.setContext(context); + STALE_LABEL.setForeground(Color.red); } @@ -381,14 +374,6 @@ private boolean containsMCTViewManifestation(Container parent) { void clearHousedManifestations() { housedManifestations.clear(); - } - - private void configureRefreshButtonAppearance() { - refreshButton.setIcon(REFRESH_ICON); - refreshButton.setPressedIcon(REFRESH_ICON_PRESSED); - refreshButton.setContentAreaFilled(false); - refreshButton.setText(""); - refreshButton.setBorder(BorderFactory.createEmptyBorder()); } private class CanvasTitleArea extends JPanel { From 7cdb98ab9fe99776ddc5ef8b176bf9806290fa06 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 13:50:27 -0700 Subject: [PATCH 11/18] [Icons] Remove more outdated icons --- .../provider/ImportExportProvider.java | 6 +---- .../limits/LimitLineComponentProvider.java | 24 +++++++++---------- .../NonTimePlotComponentProvider.java | 10 ++------ 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/ImportExportProvider/src/main/java/gov/nasa/arc/mct/importExport/provider/ImportExportProvider.java b/ImportExportProvider/src/main/java/gov/nasa/arc/mct/importExport/provider/ImportExportProvider.java index 24158be4..08d98b1e 100644 --- a/ImportExportProvider/src/main/java/gov/nasa/arc/mct/importExport/provider/ImportExportProvider.java +++ b/ImportExportProvider/src/main/java/gov/nasa/arc/mct/importExport/provider/ImportExportProvider.java @@ -33,8 +33,6 @@ import java.util.List; import java.util.ResourceBundle; -import javax.swing.ImageIcon; - /** * The ImportExportProvider provides menu items to import data into a * taxonomy node to the MCT directory and export data from a node. @@ -54,9 +52,7 @@ public ImportExportProvider() { * EventsCollection.class, false), */ new ComponentTypeInfo(bundle.getString("display_name"), bundle - .getString("description"), ImportExportComponent.class, false, - new ImageIcon(ImportExportComponent.class - .getResource("/icons/legacyCollection.png")))); + .getString("description"), ImportExportComponent.class, false)); assert componentTypes != null; } diff --git a/limits/src/main/java/gov/nasa/arc/mct/limits/LimitLineComponentProvider.java b/limits/src/main/java/gov/nasa/arc/mct/limits/LimitLineComponentProvider.java index b001b0b7..a8306584 100644 --- a/limits/src/main/java/gov/nasa/arc/mct/limits/LimitLineComponentProvider.java +++ b/limits/src/main/java/gov/nasa/arc/mct/limits/LimitLineComponentProvider.java @@ -21,17 +21,15 @@ *******************************************************************************/ package gov.nasa.arc.mct.limits; -import gov.nasa.arc.mct.gui.MenuItemInfo; -import gov.nasa.arc.mct.policy.PolicyInfo; -import gov.nasa.arc.mct.services.component.AbstractComponentProvider; -import gov.nasa.arc.mct.services.component.ComponentTypeInfo; -import gov.nasa.arc.mct.services.component.ViewInfo; - -import java.util.Collection; -import java.util.Collections; -import java.util.ResourceBundle; - -import javax.swing.ImageIcon; +import gov.nasa.arc.mct.gui.MenuItemInfo; +import gov.nasa.arc.mct.policy.PolicyInfo; +import gov.nasa.arc.mct.services.component.AbstractComponentProvider; +import gov.nasa.arc.mct.services.component.ComponentTypeInfo; +import gov.nasa.arc.mct.services.component.ViewInfo; + +import java.util.Collection; +import java.util.Collections; +import java.util.ResourceBundle; public class LimitLineComponentProvider extends AbstractComponentProvider { @@ -45,8 +43,8 @@ public LimitLineComponentProvider() { bundle.getString("display_name"), bundle.getString("description"), LimitLineComponent.class, - new LimitLineCreateWizardUI(), - new ImageIcon(LimitLineComponent.class.getResource("/icons/limit.png"))); + new LimitLineCreateWizardUI() + ); } @Override diff --git a/nonTimePlots/src/main/java/gov/nasa/arc/mct/nontimeplot/NonTimePlotComponentProvider.java b/nonTimePlots/src/main/java/gov/nasa/arc/mct/nontimeplot/NonTimePlotComponentProvider.java index 0dd89b83..698b3fbd 100644 --- a/nonTimePlots/src/main/java/gov/nasa/arc/mct/nontimeplot/NonTimePlotComponentProvider.java +++ b/nonTimePlots/src/main/java/gov/nasa/arc/mct/nontimeplot/NonTimePlotComponentProvider.java @@ -32,8 +32,6 @@ import java.util.Collection; import java.util.Collections; -import javax.swing.ImageIcon; - public class NonTimePlotComponentProvider extends AbstractComponentProvider { private Collection policies = @@ -41,15 +39,11 @@ public class NonTimePlotComponentProvider extends AbstractComponentProvider { private Collection views = Arrays.asList(new ViewInfo(NonTimePlotView.class, "Non Time", "gov.nasa.arc.mct.nontimeplot.NonTimePlotView", - ViewType.OBJECT, - new ImageIcon(getClass().getResource("/images/nonTimeViewButton-OFF.png")), - new ImageIcon(getClass().getResource("/images/nonTimeViewButton-ON.png"))), + ViewType.OBJECT), new ViewInfo(NonTimePlotView.class, "Non Time", "gov.nasa.arc.mct.nontimeplot.NonTimePlotView", - ViewType.EMBEDDED, - new ImageIcon(getClass().getResource("/images/nonTimeViewButton-OFF.png")), - new ImageIcon(getClass().getResource("/images/nonTimeViewButton-ON.png")))); + ViewType.EMBEDDED)); @Override public Collection getPolicyInfos() { From 72d3170879146392f8cc5f140b0682a2cd2e0339 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 13:57:01 -0700 Subject: [PATCH 12/18] [Icons] Test ContextAwareButton's icon usage --- .../arc/mct/gui/TestContextAwareButton.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java b/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java index 985a12e4..3d7038dd 100644 --- a/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java +++ b/mctcore/src/test/java/gov/nasa/arc/mct/gui/TestContextAwareButton.java @@ -1,6 +1,10 @@ package gov.nasa.arc.mct.gui; +import java.awt.image.BufferedImage; + import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; import org.mockito.Mock; import org.mockito.Mockito; @@ -88,6 +92,25 @@ public void testToolTip() { Assert.assertEquals(button.getToolTipText(), ACTION_NAME); } + @Test + public void testSetIcon() { + // Should not have an icon by default + Assert.assertNull(new ContextAwareButton(action).getIcon()); + + // Should customize (change) icon if it can (only for ImageIcons) + Icon icon = new ImageIcon(new BufferedImage(12,12,BufferedImage.TYPE_INT_ARGB)); + Mockito.when(action.getValue(Action.SMALL_ICON)).thenReturn(icon); + Mockito.when(action.getValue(Action.LARGE_ICON_KEY)).thenReturn(icon); + Assert.assertNotNull(new ContextAwareButton(action).getIcon()); + Assert.assertNotSame(new ContextAwareButton(action).getIcon(), icon); + + // Should use (but not customize) regular icon + icon = Mockito.mock(Icon.class); + Mockito.when(action.getValue(Action.SMALL_ICON)).thenReturn(icon); + Mockito.when(action.getValue(Action.LARGE_ICON_KEY)).thenReturn(icon); + Assert.assertEquals(new ContextAwareButton(action).getIcon(), icon); + } + @DataProvider public Object[][] generateStates() { Object[][] result = new Object[8][]; From 65b1954e635e23b7a7631563ea55f36f8bf8dd37 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 14:00:46 -0700 Subject: [PATCH 13/18] [Icons] Remove menu icon from Refresh Remove the SMALL_ICON key from RefreshAction; this is used for menu items, but icon is only desired for buttons (which use LARGE_ICON_KEY) --- .../main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java index acfae352..76973eca 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java +++ b/platform/src/main/java/gov/nasa/arc/mct/gui/actions/RefreshAction.java @@ -67,7 +67,6 @@ public class RefreshAction extends ContextAwareAction { */ public RefreshAction() { super(BUNDLE.getString("RefreshAction.label")); //NOI18N - this.putValue(Action.SMALL_ICON, ICON); this.putValue(Action.LARGE_ICON_KEY, ICON); } From f5f54080ddc07ef522806ebfaca4035c6e870bbf Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 10 Sep 2013 14:06:34 -0700 Subject: [PATCH 14/18] [Icons] Clean up commented-out code --- .../main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java b/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java index e967e852..30ae410b 100644 --- a/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java +++ b/platform/src/main/java/gov/nasa/arc/mct/defaults/view/SwitcherView.java @@ -84,7 +84,6 @@ public SwitcherView(AbstractComponent ac, ViewInfo vi) { comboBox.setVisible(false); comboBox.setEnabled(false); comboBox.setOpaque(false); - //comboBox.setFont(comboBox.getFont().deriveFont(FONT_SIZE)); add(comboBox); } else if (viewInfos.length == 1) { // Otherwise, just show the one available view as a label From b57f7b4df682c2abe38c072aab27b519dde51f9f Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 13 Sep 2013 17:02:50 -0700 Subject: [PATCH 15/18] [Database] Allow configuration of polling interval Reduces database polling interval, and allows configuration on a per-user basis. This addresses both perceived and actual issues with object modification: * nasa/mct#54 notes that object deletion seems to take a long time. Root cause is that the Browse area is refreshed by database polling, which takes place at a longer interval (3s). Decreasing this interval means that the user sees the consequences of their action sooner. * nasa/mct#132 occurs when the user switches back and forth between objects faster than the poll interval. This can cause an object to be flagged as stale because changes from one save have not made their way back to the Browse area. While this still may occur with a shorter polling interval, the odds of the user observing this decrease significantly. * nasa/mct#111 describes latency issues, some of which may be related to the poll interval. (It is unlikely, however, that menu item latency is related to this.) --- .../service/PersistenceServiceImpl.java | 16 ++++++++++++++-- .../main/resources/properties/mysql.properties | 3 +++ .../resources/properties/persistence.properties | 6 ++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/databasePersistence/src/main/java/gov/nasa/arc/mct/dbpersistence/service/PersistenceServiceImpl.java b/databasePersistence/src/main/java/gov/nasa/arc/mct/dbpersistence/service/PersistenceServiceImpl.java index 6a498d00..5377fbe1 100644 --- a/databasePersistence/src/main/java/gov/nasa/arc/mct/dbpersistence/service/PersistenceServiceImpl.java +++ b/databasePersistence/src/main/java/gov/nasa/arc/mct/dbpersistence/service/PersistenceServiceImpl.java @@ -131,9 +131,21 @@ public void setEntityManagerProperties(Properties p) { } public void activate(ComponentContext context) throws IOException { - setEntityManagerProperties(getPersistenceProperties()); + Properties persistenceProperties = getPersistenceProperties(); + setEntityManagerProperties(persistenceProperties); new InternalDBPersistenceAccess().setPersistenceService(this); checkDatabaseVersion(); + + // Check for configuration of the polling interval (default is 3s) + long pollingInterval = 3000; + try { + String intervalString = persistenceProperties.getProperty("mct.database_pollInterval"); + if (intervalString != null) { + pollingInterval = Long.parseLong(intervalString); + } + } catch (NumberFormatException nfe) { + // Stick with the default + } Timer databasePollingTimer = new Timer(); databasePollingTimer.schedule(new TimerTask() { @@ -143,7 +155,7 @@ public void run() { InternalDBPersistenceAccess.getService().updateComponentsFromDatabase(); } - }, Calendar.getInstance().getTime(), 3000); + }, Calendar.getInstance().getTime(), pollingInterval); } diff --git a/platform-assembly/src/main/resources/properties/mysql.properties b/platform-assembly/src/main/resources/properties/mysql.properties index 39970ead..7afa08c2 100644 --- a/platform-assembly/src/main/resources/properties/mysql.properties +++ b/platform-assembly/src/main/resources/properties/mysql.properties @@ -45,6 +45,9 @@ mct.database_userName=root # script. mct.database_password=root +# Configure the polling interval for retrieving new component versions from +# the database. This value is in milliseconds. +mct.database_pollInterval=500 # The properties below this line are passed directly into the JPA persistence manager hibernate.show_sql=false diff --git a/platform-assembly/src/main/resources/properties/persistence.properties b/platform-assembly/src/main/resources/properties/persistence.properties index aa6e8ecb..6e980b1c 100644 --- a/platform-assembly/src/main/resources/properties/persistence.properties +++ b/platform-assembly/src/main/resources/properties/persistence.properties @@ -26,6 +26,12 @@ javax.persistence.jdbc.url=jdbc:derby:testdb;create=true hibernate.hbm2ddl.auto=update +# Configure the polling interval for retrieving new component versions from +# the database. This value is in milliseconds. +# Using a low value with Derby should not pose problems, as there will not +# be multi-user load on the database. +mct.database_pollInterval=250 + # The properties below this line are passed directly into the JPA persistence manager hibernate.show_sql=false hibernate.format_sql=true From 2bd6dec93d576916ca6f0180c3a0b1cb71add88d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 16 Sep 2013 13:02:03 -0700 Subject: [PATCH 16/18] [Ownership] Prevent ownership change on bootstrap comps In nasa/mct#123 the user is able to change ownership of My Sandbox, which means they subsequently cannot edit their own sandbox. Worse, when they restart MCT they see no sandbox at all. This adds a check to prevent this. When ownership mutability is being determined, consult the list of bootstrap components - this is the list of components seen by the user in the User Environment. Categorically disallow changes of ownership to any of these (this includes both My Sandbox, and any future top-level components introduced, as these are presumed to be inherently tied to the user. An example of a top-level component not yet introduced is User Tags, described in nasa/MCT-Plugins#39.) --- .../gov/nasa/arc/mct/platform/spi/RoleAccess.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/mctcore/src/main/java/gov/nasa/arc/mct/platform/spi/RoleAccess.java b/mctcore/src/main/java/gov/nasa/arc/mct/platform/spi/RoleAccess.java index 27a7643e..e86fb7f4 100644 --- a/mctcore/src/main/java/gov/nasa/arc/mct/platform/spi/RoleAccess.java +++ b/mctcore/src/main/java/gov/nasa/arc/mct/platform/spi/RoleAccess.java @@ -67,10 +67,18 @@ public static boolean hasRole(User user, String role) { * @param runtimeUser the user * @return true if this components owner can be changed. */ - public static boolean canChangeOwner(AbstractComponent component, User runtimeUser) { - + public static boolean canChangeOwner(AbstractComponent component, User runtimeUser) { + // TODO: Consider moving this to Policy? + // First, rule out bootstrap components - changing ownership of these could result in major loss of functionality + for (AbstractComponent bootstrap : PlatformAccess.getPlatform().getBootstrapComponents()) { + if (bootstrap.getComponentId().equals(component.getComponentId())) { + return false; + } + } + + // Otherwise, consider ownership and role rules String componentOwner = component.getOriginalOwner() == null ? component.getOwner() : component.getOriginalOwner(); - if (componentOwner.equals(runtimeUser.getUserId()) || "admin".equals(runtimeUser.getUserId())) { + if (componentOwner.equals(runtimeUser.getUserId()) || "admin".equals(runtimeUser.getUserId())) { return true; } else { return RoleAccess.hasRole(runtimeUser, componentOwner); From e53276ad7651a207746db6ebe918f97e0df6b351 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 16 Sep 2013 13:16:20 -0700 Subject: [PATCH 17/18] [Ownership] Consider bootstrap comps in unit test Consider the case of bootstrap components in unit test verifying whether or not ownership change to a component is allowed. --- .../arc/mct/platform/spi/RoleAccessTest.java | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java b/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java index a27786b2..6127b44a 100644 --- a/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java +++ b/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java @@ -21,6 +21,8 @@ *******************************************************************************/ package gov.nasa.arc.mct.platform.spi; +import java.util.Arrays; + import gov.nasa.arc.mct.components.AbstractComponent; import gov.nasa.arc.mct.services.internal.component.ComponentInitializer; import gov.nasa.arc.mct.services.internal.component.User; @@ -29,6 +31,7 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.testng.Assert; +import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -36,33 +39,52 @@ public class RoleAccessTest { @Mock private User testUser; + @Mock private Platform mockPlatform; + @Mock private AbstractComponent mockBootstrap; private AbstractComponent component; + private Platform oldPlatform; + @BeforeTest void setup() { MockitoAnnotations.initMocks(this); component = new AbstractComponent() { }; + oldPlatform = PlatformAccess.getPlatform(); + new PlatformAccess().setPlatform(mockPlatform); + Mockito.when(mockBootstrap.getComponentId()).thenReturn("boot"); + Mockito.when(mockPlatform.getBootstrapComponents()).thenReturn(Arrays.asList(mockBootstrap)); + } + + @AfterTest + void teardown() { + new PlatformAccess().setPlatform(oldPlatform); } @DataProvider(name="userAndComponentSetup") Object[][] userTests() { return new Object[][] { - new Object[] {"admin", "xyz", true}, - new Object[] {"xyz", "xyz", true}, - new Object[] {"qqq", "xyz", false} + new Object[] {"admin", "xyz", "...", true}, + new Object[] {"xyz", "xyz", "...", true}, + new Object[] {"qqq", "xyz", "...", false}, + // The following should be identified as bootstrap components, + // and ownership changed should be disallowed. + new Object[] {"admin", "xyz", "boot", false}, + new Object[] {"xyz", "xyz", "boot", false}, + new Object[] {"qqq", "xyz", "boot", false} }; } - void setupUserAndComponent(String user, String originalOwner) { + void setupUserAndComponent(String user, String originalOwner, String id) { Mockito.when(testUser.getUserId()).thenReturn(user); ComponentInitializer ci = component.getCapability(ComponentInitializer.class); ci.setOwner(originalOwner); + ci.setId(id); } @Test(dataProvider="userAndComponentSetup") - public void testCanChangeOwner(String userName, String originalOwner, boolean expectedValue) { - setupUserAndComponent(userName, originalOwner); + public void testCanChangeOwner(String userName, String originalOwner, String id, boolean expectedValue) { + setupUserAndComponent(userName, originalOwner, id); component.setOwner(userName); Assert.assertEquals(RoleAccess.canChangeOwner(component, testUser), expectedValue); } From ae67ca26d5988b78f0968cd4758cb410bfb5c1ac Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 16 Sep 2013 16:58:39 -0700 Subject: [PATCH 18/18] [Ownership] Fix unit tests Amend unit tests to resolve issues related to changes in support of nasa/mct#123. Specifically: * Change method annotations in RoleAccessTest to clean up on a per-method basis, avoiding interference with global state (platform) in other tests. * Perform additional mock setup in test for info view, as platform is now indirectly consulted during the creation of that GUI. --- .../arc/mct/platform/spi/RoleAccessTest.java | 12 ++++++------ .../arc/mct/defaults/view/TestInfoView.java | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java b/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java index 6127b44a..f3146d67 100644 --- a/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java +++ b/mctcore/src/test/java/gov/nasa/arc/mct/platform/spi/RoleAccessTest.java @@ -21,18 +21,18 @@ *******************************************************************************/ package gov.nasa.arc.mct.platform.spi; -import java.util.Arrays; - import gov.nasa.arc.mct.components.AbstractComponent; import gov.nasa.arc.mct.services.internal.component.ComponentInitializer; import gov.nasa.arc.mct.services.internal.component.User; +import java.util.Arrays; + import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.testng.Assert; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -45,7 +45,7 @@ public class RoleAccessTest { private Platform oldPlatform; - @BeforeTest + @BeforeMethod void setup() { MockitoAnnotations.initMocks(this); component = new AbstractComponent() { @@ -56,7 +56,7 @@ void setup() { Mockito.when(mockPlatform.getBootstrapComponents()).thenReturn(Arrays.asList(mockBootstrap)); } - @AfterTest + @AfterMethod void teardown() { new PlatformAccess().setPlatform(oldPlatform); } diff --git a/platform/src/test/java/gov/nasa/arc/mct/defaults/view/TestInfoView.java b/platform/src/test/java/gov/nasa/arc/mct/defaults/view/TestInfoView.java index bee2a58d..445481e2 100644 --- a/platform/src/test/java/gov/nasa/arc/mct/defaults/view/TestInfoView.java +++ b/platform/src/test/java/gov/nasa/arc/mct/defaults/view/TestInfoView.java @@ -5,6 +5,8 @@ import gov.nasa.arc.mct.components.PropertyDescriptor.VisualControlDescriptor; import gov.nasa.arc.mct.components.PropertyEditor; import gov.nasa.arc.mct.context.GlobalContext; +import gov.nasa.arc.mct.platform.spi.Platform; +import gov.nasa.arc.mct.platform.spi.PlatformAccess; import gov.nasa.arc.mct.platform.spi.RoleAccess; import gov.nasa.arc.mct.platform.spi.RoleService; import gov.nasa.arc.mct.services.component.ViewInfo; @@ -29,6 +31,7 @@ import org.mockito.Mockito; import org.testng.Assert; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -38,19 +41,29 @@ public class TestInfoView { User mockUser = Mockito.mock(User.class); RoleService mockRoleService = Mockito.mock(RoleService.class); AbstractComponent comp = Mockito.mock(AbstractComponent.class); - ViewInfo info = new ViewInfo(InfoView.class, "Info", ViewType.CENTER); - + Platform mockPlatform = Mockito.mock(Platform.class); + Platform oldPlatform; + ViewInfo info = new ViewInfo(InfoView.class, "Info", ViewType.CENTER); + @BeforeMethod - public void setup() { + public void setup() { // Setup minimum expected environment for info view + oldPlatform = PlatformAccess.getPlatform(); + new PlatformAccess().setPlatform(mockPlatform); Mockito.when(comp.getOwner()).thenReturn("*"); Mockito.when(comp.getComponentTypeID()).thenReturn(""); Mockito.when(mockUser.getUserId()).thenReturn(""); Mockito.when(mockRoleService.getAllUsers()).thenReturn(Collections.singleton("")); + Mockito.when(mockPlatform.getBootstrapComponents()).thenReturn(Collections.emptyList()); GlobalContext.getGlobalContext().switchUser(mockUser, Mockito.mock(Runnable.class)); new RoleAccess().addRoleService(mockRoleService); } + @AfterMethod + public void teardown() { + new PlatformAccess().setPlatform(oldPlatform); + } + @Test public void testUpdateMonitoredGUI() { /* This test ensures that updateMonitoredGUI triggers revalidate/repaint */