# HG changeset patch # User Mario Torre # Date 1380551930 -7200 # Node ID 16c666300582837fc4c0f8353e6a99605b5809ad # Parent ecf0cfd9dafe17f29dddee64afda9c4490b2ce7d New VMTree (part III) review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-September/008324.html reviewed-by: omajid diff -r ecf0cfd9dafe -r 16c666300582 agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/ConfigurationServerContextTest.java --- a/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/ConfigurationServerContextTest.java Mon Sep 30 16:38:49 2013 +0200 +++ b/agent/command/src/test/java/com/redhat/thermostat/agent/command/internal/ConfigurationServerContextTest.java Mon Sep 30 16:38:50 2013 +0200 @@ -60,8 +60,8 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import com.redhat.thermostat.common.ssl.SSLConfiguration; import com.redhat.thermostat.common.ssl.SSLContextFactory; -import com.redhat.thermostat.common.ssl.SSLConfiguration; @RunWith(PowerMockRunner.class) @PrepareForTest({ SSLConfiguration.class, SSLContextFactory.class, diff -r ecf0cfd9dafe -r 16c666300582 client/swing/pom.xml --- a/client/swing/pom.xml Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/pom.xml Mon Sep 30 16:38:50 2013 +0200 @@ -138,6 +138,7 @@ src/main/resources true + **/*.jpg **/*.png **/*.ttf @@ -146,6 +147,7 @@ src/main/resources false + **/*.jpg **/*.png **/*.ttf @@ -170,10 +172,15 @@ com.redhat.thermostat.client.swing.internal, + com.redhat.thermostat.client.swing.internal.sidepane, + com.redhat.thermostat.client.swing.internal.splitpane, com.redhat.thermostat.client.swing.internal.progress, com.redhat.thermostat.client.swing.internal.components, com.redhat.thermostat.client.swing.internal.osgi, com.redhat.thermostat.client.swing.internal.views, + com.redhat.thermostat.client.swing.internal.vmlist, + com.redhat.thermostat.client.swing.internal.vmlist.controller, + com.redhat.thermostat.client.swing.internal.accordion, <_nouses>true diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java Mon Sep 30 16:38:50 2013 +0200 @@ -50,7 +50,7 @@ public class IconResource { private boolean fromFileSytem = false; - + public static final IconResource JAVA_APPLICATION = new IconResource("java_application_identifier.png"); public static final IconResource HOST = new IconResource("computer.png"); public static final IconResource SEARCH = new IconResource("search.png"); diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java Mon Sep 30 16:38:50 2013 +0200 @@ -36,6 +36,7 @@ package com.redhat.thermostat.client.swing.components; +import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; @@ -52,9 +53,13 @@ @SuppressWarnings("serial") public class ShadowLabel extends JLabel { + private Color shadowColor; + private ShadowLabel(String text, Icon icon) { super(text); this.setIcon(icon); + this.shadowColor = new Color(0f, 0f, 0f, 0.1f); + setUI(new ShadowLabelUI()); } @@ -76,8 +81,18 @@ protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) { GraphicsUtils graphicsUtils = GraphicsUtils.getInstance(); Graphics2D graphics = graphicsUtils.createAAGraphics(g); - graphicsUtils.drawStringWithShadow(l, graphics, s, ShadowLabel.this.getForeground(), textX, textY); + graphicsUtils.drawStringWithShadow(l, graphics, s, ShadowLabel.this.getForeground(), + ShadowLabel.this.getShadowColor(), textX, textY); } } + + public Color getShadowColor() { + return shadowColor; + } + + public void setShadowColor(Color shadowColor) { + this.shadowColor = shadowColor; + repaint(); + } } diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SlimScrollBarUI.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SlimScrollBarUI.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SlimScrollBarUI.java Mon Sep 30 16:38:50 2013 +0200 @@ -68,7 +68,7 @@ } else { g.setColor(Palette.EARL_GRAY.getColor()); } - g.fillRect(0, 0, getWidth()- 1, getHeight() - 1); + g.fillRect(0, 0, getWidth() - 1, getHeight() - 1); } }; } diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorProvider.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorProvider.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorProvider.java Mon Sep 30 16:38:50 2013 +0200 @@ -36,10 +36,7 @@ package com.redhat.thermostat.client.swing.internal; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; import com.redhat.thermostat.client.core.Filter; import com.redhat.thermostat.client.core.NameMatchingRefFilter; @@ -47,7 +44,6 @@ import com.redhat.thermostat.client.ui.Decorator; import com.redhat.thermostat.client.ui.DecoratorProvider; import com.redhat.thermostat.client.ui.IconDescriptor; -import com.redhat.thermostat.common.utils.StreamUtils; import com.redhat.thermostat.storage.core.HostRef; public class HostIconDecoratorProvider implements DecoratorProvider { diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java Mon Sep 30 16:38:50 2013 +0200 @@ -41,17 +41,15 @@ import javax.swing.JFrame; -import com.redhat.thermostat.client.core.Filter; import com.redhat.thermostat.client.core.progress.ProgressNotifier; import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController; import com.redhat.thermostat.client.ui.ContextAction; -import com.redhat.thermostat.client.ui.DecoratorProvider; import com.redhat.thermostat.client.ui.MenuAction; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.storage.core.HostRef; -import com.redhat.thermostat.storage.core.HostsVMsLoader; import com.redhat.thermostat.storage.core.Ref; import com.redhat.thermostat.storage.core.VmRef; @@ -61,7 +59,6 @@ VISIBLE, HIDDEN, HOST_VM_TREE_FILTER, - HOST_VM_SELECTION_CHANGED, SHOW_AGENT_CONFIG, SHOW_CLIENT_CONFIG, SWITCH_HISTORY_MODE, @@ -72,12 +69,6 @@ } void addActionListener(ActionListener capture); - - void updateTree(List> hostFilters, List> vmFilters, - List> hostDecorators, List> vmDecorators, - HostsVMsLoader any); - - String getHostVmTreeFilterText(); void setWindowTitle(String title); @@ -85,8 +76,6 @@ void hideMainWindow(); - Ref getSelectedHostOrVm(); - void setSubView(BasicView view); void setStatusBarPrimaryStatus(LocalizedString primaryStatus); @@ -123,5 +112,11 @@ void showContextActions(List actions, MouseEvent e); JFrame getTopFrame(); + + /** + * Returns the {@link HostTreeController} that handles the {@link Ref}s + * object tracked by this UI Client. + */ + HostTreeController getHostTreeController(); } diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java Mon Sep 30 16:38:50 2013 +0200 @@ -40,7 +40,6 @@ import java.awt.Color; import java.awt.Component; import java.awt.Dimension; -import java.awt.Graphics2D; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.InputEvent; @@ -49,291 +48,70 @@ import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; -import java.nio.ByteBuffer; -import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; -import javax.swing.ToolTipManager; -import javax.swing.event.TreeExpansionEvent; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.event.TreeWillExpandListener; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; import sun.misc.Signal; -import com.redhat.thermostat.client.core.Filter; import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.locale.LocaleResources; -import com.redhat.thermostat.client.swing.ComponentVisibleListener; import com.redhat.thermostat.client.swing.EdtHelper; import com.redhat.thermostat.client.swing.MenuHelper; import com.redhat.thermostat.client.swing.SwingComponent; import com.redhat.thermostat.client.swing.components.OverlayPanel; -import com.redhat.thermostat.client.swing.components.SearchField; -import com.redhat.thermostat.client.swing.components.SearchField.SearchAction; import com.redhat.thermostat.client.swing.components.ThermostatPopupMenu; -import com.redhat.thermostat.client.swing.internal.components.DecoratedDefaultMutableTreeNode; +import com.redhat.thermostat.client.swing.internal.accordion.Accordion; +import com.redhat.thermostat.client.swing.internal.accordion.AccordionModel; import com.redhat.thermostat.client.swing.internal.components.ThermostatGlassPane; +import com.redhat.thermostat.client.swing.internal.components.ThermostatGlassPaneLayout; import com.redhat.thermostat.client.swing.internal.progress.AggregateNotificationPanel; -import com.redhat.thermostat.client.swing.internal.progress.AggregateProgressBarOverlayLayout; import com.redhat.thermostat.client.swing.internal.progress.ProgressNotificationArea; import com.redhat.thermostat.client.swing.internal.progress.SwingProgressNotifier; import com.redhat.thermostat.client.swing.internal.progress.SwingProgressNotifier.PropertyChange; +import com.redhat.thermostat.client.swing.internal.sidepane.ExpanderComponent; +import com.redhat.thermostat.client.swing.internal.sidepane.ThermostatSidePanel; +import com.redhat.thermostat.client.swing.internal.splitpane.ThermostatSplitPane; +import com.redhat.thermostat.client.swing.internal.vmlist.HostTreeComponentFactory; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorManager; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController; import com.redhat.thermostat.client.ui.ContextAction; -import com.redhat.thermostat.client.ui.Decorator; -import com.redhat.thermostat.client.ui.DecoratorProvider; -import com.redhat.thermostat.client.ui.IconDescriptor; import com.redhat.thermostat.client.ui.MenuAction; -import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.common.ActionNotifier; import com.redhat.thermostat.common.utils.StringUtils; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.HostRef; -import com.redhat.thermostat.storage.core.HostsVMsLoader; -import com.redhat.thermostat.storage.core.Ref; import com.redhat.thermostat.storage.core.VmRef; -@SuppressWarnings("restriction") +@SuppressWarnings({ "restriction", "serial" }) public class MainWindow extends JFrame implements MainView { public static final String MAIN_WINDOW_NAME = "Thermostat_mainWindo_JFrame_parent#1"; private static final Translate translator = LocaleResources.createLocalizer(); - /** - * Updates a TreeModel in the background in an Swing EDT-safe manner. - */ - private static class BackgroundTreeModelWorker extends SwingWorker { - - private JTree tree; - - private final DefaultTreeModel treeModel; - private DefaultMutableTreeNode treeRoot; - - private List> hostFilters; - private List> vmFilters; - private List> hostDecorators; - private List> vmDecorators; - - private HostsVMsLoader hostsVMsLoader; - - public BackgroundTreeModelWorker(DefaultTreeModel model, DefaultMutableTreeNode root, - List> hostFilters, List> vmFilters, - List> hostDecorators, - List> vmDecorators, - HostsVMsLoader hostsVMsLoader, JTree tree) - { - this.hostFilters = hostFilters; - this.vmFilters = vmFilters; - - this.vmDecorators = vmDecorators; - this.hostDecorators = hostDecorators; - - this.treeModel = model; - this.treeRoot = root; - this.hostsVMsLoader = hostsVMsLoader; - this.tree = tree; - } - - @Override - protected DefaultMutableTreeNode doInBackground() throws Exception { - DefaultMutableTreeNode root = new DefaultMutableTreeNode(); - - Collection hostsInRemoteModel = hostsVMsLoader.getHosts(); - buildHostSubTree(root, hostsInRemoteModel); - return root; - } - - private boolean buildHostSubTree(DefaultMutableTreeNode parent, Collection objectsInRemoteModel) { - boolean subTreeMatches = false; - for (HostRef inRemoteModel : objectsInRemoteModel) { - DecoratedDefaultMutableTreeNode inTreeNode = - new DecoratedDefaultMutableTreeNode(inRemoteModel); - - boolean shouldInsert = false; - if (hostFilters == null) { - shouldInsert = true; - } else { - shouldInsert = true; - for (Filter filter : hostFilters) { - if (!filter.matches(inRemoteModel)) { - shouldInsert = false; - break; - } - } - } - - Collection children = hostsVMsLoader.getVMs(inRemoteModel); - boolean subtreeResult = buildVmSubTree(inTreeNode, children); - if (subtreeResult) { - shouldInsert = true; - } - - if (shouldInsert) { - for (DecoratorProvider decorator : hostDecorators) { - Filter filter = decorator.getFilter(); - if (filter != null && filter.matches(inRemoteModel)) { - inTreeNode.addDecorator(decorator.getDecorator()); - } - } - - parent.add(inTreeNode); - subTreeMatches = true; - } - } - - return subTreeMatches; - } - - private boolean buildVmSubTree(DefaultMutableTreeNode parent, Collection objectsInRemoteModel) { - boolean subTreeMatches = false; - for (VmRef inRemoteModel : objectsInRemoteModel) { - DecoratedDefaultMutableTreeNode inTreeNode = - new DecoratedDefaultMutableTreeNode(inRemoteModel); - - boolean shouldInsert = false; - if (vmFilters == null) { - shouldInsert = true; - } else { - shouldInsert = true; - for (Filter filter : vmFilters) { - if (!filter.matches(inRemoteModel)) { - shouldInsert = false; - break; - } - } - } - - if (shouldInsert) { - for (DecoratorProvider decorator : vmDecorators) { - Filter filter = decorator.getFilter(); - if (filter != null && filter.matches(inRemoteModel)) { - inTreeNode.addDecorator(decorator.getDecorator()); - } - } - - parent.add(inTreeNode); - subTreeMatches = true; - } - } - - return subTreeMatches; - } - - @Override - protected void done() { - DefaultMutableTreeNode sourceRoot; - try { - sourceRoot = get(); - syncTree(sourceRoot, treeModel, treeRoot); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } - } - - private void syncTree(DefaultMutableTreeNode sourceRoot, DefaultTreeModel targetModel, DefaultMutableTreeNode targetNode) { - - @SuppressWarnings("unchecked") // We know what we put into these trees. - List sourceChildren = Collections.list(sourceRoot.children()); - - @SuppressWarnings("unchecked") - List targetChildren = Collections.list(targetNode.children()); - for (DefaultMutableTreeNode sourceChild : sourceChildren) { - Ref sourceRef = (Ref) sourceChild.getUserObject(); - DefaultMutableTreeNode targetChild = null; - for (DefaultMutableTreeNode aChild : targetChildren) { - Ref targetRef = (Ref) aChild.getUserObject(); - if (targetRef.equals(sourceRef)) { - targetChild = aChild; - if (sourceChild instanceof DecoratedDefaultMutableTreeNode) { - DecoratedDefaultMutableTreeNode source = (DecoratedDefaultMutableTreeNode) sourceChild; - ((DecoratedDefaultMutableTreeNode) targetChild).setDecorators(source.getDecorators()); - } - break; - } - } - - if (targetChild == null) { - targetChild = new DecoratedDefaultMutableTreeNode(sourceRef); - if (sourceChild instanceof DecoratedDefaultMutableTreeNode) { - DecoratedDefaultMutableTreeNode source = (DecoratedDefaultMutableTreeNode) sourceChild; - ((DecoratedDefaultMutableTreeNode) targetChild).setDecorators(source.getDecorators()); - } - targetModel.insertNodeInto(targetChild, targetNode, targetNode.getChildCount()); - } - - syncTree(sourceChild, targetModel, targetChild); - } - - for (DefaultMutableTreeNode targetChild : targetChildren) { - Ref targetRef = (Ref) targetChild.getUserObject(); - boolean matchFound = false; - for (DefaultMutableTreeNode sourceChild : sourceChildren) { - Ref sourceRef = (Ref) sourceChild.getUserObject(); - if (targetRef.equals(sourceRef)) { - matchFound = true; - break; - } - } - - if (!matchFound) { - targetModel.removeNodeFromParent(targetChild); - } - } - ensureRootIsExpanded(targetModel); - } - - private void ensureRootIsExpanded(final DefaultTreeModel model) { - DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); - tree.expandPath(new TreePath(root.getPath())); - } - - } - private SwingProgressNotifier notifier; - private static final long serialVersionUID = 5608972421496808177L; - private final JMenuBar mainMenuBar = new JMenuBar(); private final MenuHelper mainMenuHelper = new MenuHelper(mainMenuBar); private JPanel contentArea = null; - - private SearchField searchField = new SearchField(); - private JTree agentVmTree = null; - + private final ShutdownClient shutdownAction; private ActionNotifier actionNotifier = new ActionNotifier<>(this); @@ -341,11 +119,11 @@ private ThermostatPopupMenu contextMenu; private StatusBar statusBar; - private final DefaultMutableTreeNode publishedRoot = - new DefaultMutableTreeNode(translator.localize(LocaleResources.MAIN_WINDOW_TREE_ROOT_NAME).getContents()); - private final DefaultTreeModel publishedTreeModel = new DefaultTreeModel(publishedRoot); - - @SuppressWarnings("restriction") + private ThermostatSidePanel navigationPanel; + private Accordion hostTree; + + private HostTreeController hostTreeController; + public MainWindow() { super(); @@ -353,50 +131,19 @@ shutdownAction = new ShutdownClient(); - searchField.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent actionEvent) { - switch (actionEvent.getActionId()) { - case TEXT_CHANGED: - fireViewAction(Action.HOST_VM_TREE_FILTER); - break; - } - } - }); - agentVmTree = new JTree(publishedTreeModel); - agentVmTree.setName("agentVmTree"); - agentVmTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); - agentVmTree.setCellRenderer(new AgentVmTreeCellRenderer()); - agentVmTree.addTreeWillExpandListener(new TreeWillExpandListener() { - @Override - public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { - /* Yup, tree will expand */ - } - - @Override - public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { - if (new TreePath(publishedRoot.getPath()).equals(event.getPath())) { - throw new ExpandVetoException(event, "root cant be collapsed"); - } - } - }); - ToolTipManager.sharedInstance().registerComponent(agentVmTree); contentArea = new JPanel(new BorderLayout()); + ThermostatGlassPane glassPane = new ThermostatGlassPane(); + glassPane.setLayout(new ThermostatGlassPaneLayout()); + + setGlassPane(glassPane); + setupMenus(); - setupPanels(); + setupPanels(glassPane); this.setPreferredSize(new Dimension(800, 600)); - agentVmTree.setSelectionPath(new TreePath(((DefaultMutableTreeNode) publishedTreeModel.getRoot()).getPath())); - - //agentVmTree.setLargeModel(true); - agentVmTree.setRowHeight(25); - statusBar = new StatusBar(); - - ThermostatGlassPane glassPane = new ThermostatGlassPane(); - setGlassPane(glassPane); setupNotificationPane(statusBar, glassPane); getContentPane().add(statusBar, BorderLayout.SOUTH); @@ -409,7 +156,6 @@ Signal.handle(new Signal("INT"), shutdownAction); addComponentListener(new ComponentAdapter() { - @Override public void componentShown(ComponentEvent e) { fireViewAction(Action.VISIBLE); @@ -431,7 +177,6 @@ statusBar.add(notificationArea, BorderLayout.CENTER); - glassPane.setLayout(new AggregateProgressBarOverlayLayout()); LocalizedString title = translator.localize(LocaleResources.PROGRESS_NOTIFICATION_AREA_TITLE); final OverlayPanel overlay = new OverlayPanel(title, false); glassPane.add(overlay); @@ -535,51 +280,88 @@ setJMenuBar(mainMenuBar); } - private void setupPanels() { - JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - splitPane.setOneTouchExpandable(true); - - JPanel navigationPanel = new JPanel(new BorderLayout()); + private void setupPanels(final ThermostatGlassPane glassPane) { + final ThermostatSplitPane splitPane = new ThermostatSplitPane(); + splitPane.setOneTouchExpandable(false); + getContentPane().add(splitPane); - navigationPanel.add(searchField, BorderLayout.PAGE_START); - - agentVmTree.addTreeSelectionListener(new TreeSelectionListener() { + final JPanel detailsPanel = createDetailsPanel(); + detailsPanel.setMinimumSize(new Dimension(500, 500)); + splitPane.setRightComponent(detailsPanel); + + navigationPanel = new ThermostatSidePanel(); + splitPane.setLeftComponent(navigationPanel); + + DecoratorManager decoratorManager = new DecoratorManager(); + + hostTree = new Accordion<>(new HostTreeComponentFactory(decoratorManager)); + hostTreeController = new HostTreeController(hostTree, decoratorManager); + navigationPanel.addContent(hostTree); + + final JPanel collapsedPanel = new JPanel(); + collapsedPanel.setLayout(new BorderLayout()); + + final ExpanderComponent expander = new ExpanderComponent(); + + navigationPanel.setMinimumSize(new Dimension(300, 500)); + navigationPanel.addPropertyChangeListener(ThermostatSidePanel.COLLAPSED, + new PropertyChangeListener() + { @Override - public void valueChanged(TreeSelectionEvent e) { - if (e.isAddedPath()) { - fireViewAction(Action.HOST_VM_SELECTION_CHANGED); - } + public void propertyChange(final PropertyChangeEvent evt) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (((Boolean) evt.getNewValue()).booleanValue()) { + getContentPane().remove(splitPane); + + collapsedPanel.add(expander, BorderLayout.WEST); + collapsedPanel.add(detailsPanel, BorderLayout.CENTER); + + getContentPane().add(collapsedPanel); + revalidate(); + repaint(); + } + } + }); } }); - registerContextActionListener(agentVmTree); - JScrollPane treeScrollPane = new JScrollPane(agentVmTree); - - navigationPanel.add(treeScrollPane); - - JPanel detailsPanel = createDetailsPanel(); - - navigationPanel.setMinimumSize(new Dimension(200,500)); - detailsPanel.setMinimumSize(new Dimension(500, 500)); - - splitPane.add(navigationPanel); - splitPane.add(detailsPanel); - - getContentPane().add(splitPane); - } - - private void registerContextActionListener(JTree agentVmTree2) { - contextMenu = new ThermostatPopupMenu(); - agentVmTree2.addMouseListener(new MouseAdapter() { + expander.addPropertyChangeListener(ExpanderComponent.EXPANDED_PROPERTY, + new PropertyChangeListener() + { @Override - public void mousePressed(MouseEvent e) { - if (e.isPopupTrigger()) { - Ref ref = getSelectedHostOrVm(); - fireViewAction(Action.SHOW_HOST_VM_CONTEXT_MENU, e); + public void propertyChange(PropertyChangeEvent evt) { + if (((Boolean) evt.getNewValue()).booleanValue()) { + + collapsedPanel.removeAll(); + + getContentPane().remove(collapsedPanel); + + splitPane.setRightComponent(detailsPanel); + splitPane.setLeftComponent(navigationPanel); + + getContentPane().add(splitPane); + revalidate(); + repaint(); } } }); } + + // TODO +// private void registerContextActionListener(JTree agentVmTree2) { +// contextMenu = new ThermostatPopupMenu(); +// agentVmTree2.addMouseListener(new MouseAdapter() { +// @Override +// public void mousePressed(MouseEvent e) { +// if (e.isPopupTrigger()) { +// Ref ref = getSelectedHostOrVm(); +// fireViewAction(Action.SHOW_HOST_VM_CONTEXT_MENU, e); +// } +// } +// }); +// } @Override public void showContextActions(final List actions, final MouseEvent e) { @@ -642,97 +424,6 @@ } - private static class AgentVmTreeCellRenderer extends DefaultTreeCellRenderer { - private static final long serialVersionUID = 4444642511815252481L; - - @Override - public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { - - Object node = ((DefaultMutableTreeNode) value).getUserObject(); - setToolTipText(createToolTipText(node)); - - Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); - if (value instanceof DecoratedDefaultMutableTreeNode) { - DecoratedDefaultMutableTreeNode treeNode = (DecoratedDefaultMutableTreeNode) value; - setAnnotation(treeNode, node, component); - } - - return component; - } - - // TODO: we can cache more, for example the full icon, not just the decoration - private Map decoratorsCache = new HashMap<>(); - private void setAnnotation(DecoratedDefaultMutableTreeNode treeNode, Object value, Component component) { - - List decorators = treeNode.getDecorators(); - for (Decorator dec : decorators) { - String newText = dec.getLabel(getText()); - setText(newText); - setLabelFor(component); - - ImageIcon icon = decoratorsCache.get(dec); - if (icon == null) { - //System.err.println("cache miss: " + dec); - IconDescriptor iconDescriptor = dec.getIconDescriptor(); - if (iconDescriptor != null) { - ByteBuffer data = iconDescriptor.getData(); - icon = new ImageIcon(data.array()); - decoratorsCache.put(dec, icon); - } - } - - if (icon == null) { - return; - } - - Icon currentIcon = getIcon(); - switch (dec.getQuadrant()) { - case BOTTOM_LEFT: - int y = currentIcon.getIconHeight() - icon.getIconHeight(); - paintCustomIcon(currentIcon, icon, y); - break; - - case TOP_LEFT: - paintCustomIcon(currentIcon, icon, 0); - break; - - case MAIN: - default: - setIcon(icon); - break; - } - } - } - - private void paintCustomIcon(Icon currentIcon, ImageIcon icon, int y) { - BufferedImage image = new BufferedImage(currentIcon.getIconWidth(), - currentIcon.getIconHeight(), - BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = (Graphics2D) image.getGraphics(); - - currentIcon.paintIcon(null, graphics, 0, 0); - graphics.drawImage(icon.getImage(), 0, y, null); - - setIcon(new ImageIcon(image)); - } - - private String createToolTipText(Object value) { - if (value instanceof HostRef) { - HostRef hostRef = (HostRef) value; - String hostName = hostRef.getHostName(); - String agentId = hostRef.getAgentId(); - return translator.localize(LocaleResources.HOST_TOOLTIP, hostName, agentId).getContents(); - } else if (value instanceof VmRef) { - VmRef vmRef = (VmRef) value; - String vmName = vmRef.getName(); - String vmId = vmRef.getVmId(); - return translator.localize(LocaleResources.VM_TOOLTIP, vmName, vmId).getContents(); - } else { - return null; - } - } - } - @Override public JFrame getTopFrame() { return this; @@ -755,18 +446,6 @@ actionNotifier.fireAction(action, payload); } - @Override - public void updateTree(List> hostFilters, List> vmFilters, - List> hostDecorators, - List> vmDecorators, - HostsVMsLoader hostsVMsLoader) - { - BackgroundTreeModelWorker worker = - new BackgroundTreeModelWorker(publishedTreeModel, publishedRoot, - hostFilters, vmFilters, hostDecorators, vmDecorators, hostsVMsLoader, agentVmTree); - worker.execute(); - } - @SuppressWarnings("unused") // Used for debugging but not in production code. private static void printTree(PrintStream out, TreeNode node, int depth) { out.println(StringUtils.repeat(" ", depth) + node.toString()); @@ -842,21 +521,9 @@ mainMenuHelper.removeMenuAction(action); } - /** - * Returns null to indicate no Ref is selected - */ @Override - public Ref getSelectedHostOrVm() { - TreePath path = agentVmTree.getSelectionPath(); - if (path == null || path.getPathCount() == 1) { - return null; - } - return (Ref) ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject(); - } - - @Override - public String getHostVmTreeFilterText() { - return searchField.getSearchText(); + public HostTreeController getHostTreeController() { + return hostTreeController; } } diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java Mon Sep 30 16:38:50 2013 +0200 @@ -36,15 +36,12 @@ package com.redhat.thermostat.client.swing.internal; -import java.awt.event.MouseEvent; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -66,18 +63,18 @@ import com.redhat.thermostat.client.swing.internal.osgi.HostContextActionServiceTracker; import com.redhat.thermostat.client.swing.internal.osgi.InformationServiceTracker; import com.redhat.thermostat.client.swing.internal.osgi.VMContextActionServiceTracker; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorProviderExtensionListener; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController.ReferenceSelection; import com.redhat.thermostat.client.ui.AgentInformationDisplayController; import com.redhat.thermostat.client.ui.AgentInformationDisplayModel; import com.redhat.thermostat.client.ui.ClientConfigurationController; -import com.redhat.thermostat.client.ui.ContextAction; import com.redhat.thermostat.client.ui.DecoratorProvider; -import com.redhat.thermostat.client.ui.HostContextAction; import com.redhat.thermostat.client.ui.HostInformationController; import com.redhat.thermostat.client.ui.MainWindowController; import com.redhat.thermostat.client.ui.MenuAction; import com.redhat.thermostat.client.ui.MenuRegistry; import com.redhat.thermostat.client.ui.SummaryController; -import com.redhat.thermostat.client.ui.VMContextAction; import com.redhat.thermostat.client.ui.VmInformationController; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; @@ -85,38 +82,32 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.MultipleServiceTracker; import com.redhat.thermostat.common.ThermostatExtensionRegistry; -import com.redhat.thermostat.common.Timer; -import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.config.ClientPreferences; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.shared.locale.Translate; -import com.redhat.thermostat.storage.core.DefaultHostsVMsLoader; import com.redhat.thermostat.storage.core.HostRef; -import com.redhat.thermostat.storage.core.HostsVMsLoader; import com.redhat.thermostat.storage.core.Ref; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.dao.BackendInfoDAO; import com.redhat.thermostat.storage.dao.HostInfoDAO; import com.redhat.thermostat.storage.dao.VmInfoDAO; +import com.redhat.thermostat.storage.monitor.HostMonitor; +import com.redhat.thermostat.storage.monitor.NetworkMonitor; import com.redhat.thermostat.utils.keyring.Keyring; public class MainWindowControllerImpl implements MainWindowController { - + + private static final Translate t = LocaleResources.createLocalizer(); + private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class); - private static final Translate t = LocaleResources.createLocalizer(); - private final CopyOnWriteArrayList> hostFilters = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList> vmFilters = new CopyOnWriteArrayList<>(); - private final CopyOnWriteArrayList> hostTreeDecorators = new CopyOnWriteArrayList<>(); - private final CopyOnWriteArrayList> vmTreeDecorators = new CopyOnWriteArrayList<>(); - private final ApplicationInfo appInfo = new ApplicationInfo(); private ApplicationService appSvc; - private Timer backgroundUpdater; private MainView view; private Keyring keyring; @@ -140,6 +131,11 @@ private CountDownLatch shutdown; private CountDownLatch initViewLatch = new CountDownLatch(1); + private NetworkMonitor networkMonitor; + private HostMonitor hostMonitor; + + private VMMonitorController vmMonitor; + private MenuRegistry menuRegistry; private ActionListener menuListener = new ActionListener() @@ -177,9 +173,6 @@ private HostTreeDecoratorRegistry hostDecoratorRegistry; private VMTreeDecoratorRegistry vmDecoratorRegistry; - private ActionListener hostDecoratorListener = new DecoratorProviderExtensionListener(hostTreeDecorators); - private ActionListener vmDecoratorListener = new DecoratorProviderExtensionListener(vmTreeDecorators); - private VMInformationRegistry vmInfoRegistry; private ActionListener vmInfoRegistryListener = new ActionListener () @@ -187,11 +180,10 @@ public void actionPerformed(com.redhat.thermostat.common.ActionEvent actionEvent) { - updateView(); + // TODO + //updateView(); }; }; - - private boolean showHistory; private VmInformationControllerProvider vmInfoControllerProvider; @@ -246,6 +238,8 @@ VmInformationViewProvider.class, AgentInformationViewProvider.class, ClientConfigViewProvider.class, + HostMonitor.class, + NetworkMonitor.class, }; depTracker = new MultipleServiceTracker(context, deps, new MultipleServiceTracker.Action() { @@ -272,14 +266,16 @@ clientConfigViewProvider = (ClientConfigViewProvider) services.get(ClientConfigViewProvider.class.getName()); Objects.requireNonNull(clientConfigViewProvider); + networkMonitor = (NetworkMonitor) services.get(NetworkMonitor.class.getName()); + hostMonitor = (HostMonitor) services.get(HostMonitor.class.getName()); + initView(); vmInfoControllerProvider = new VmInformationControllerProvider(); - initializeTimer(); - - updateView(); - + vmMonitor = initMonitors(); + vmMonitor.start(); + installListenersAndStartRegistries(); registerProgressNotificator(context); @@ -297,6 +293,12 @@ depTracker.open(); } + VMMonitorController initMonitors() { + VMMonitorController vmMonitor = + new VMMonitorController(networkMonitor, hostMonitor, view); + return vmMonitor; + } + /* * This method is for testing purposes only */ @@ -312,72 +314,43 @@ /** * This method is for testing purposes only - */ - List> getVmTreeDecorators() { - return vmTreeDecorators; - } - - /** - * This method is for testing purposes only */ ActionListener getMenuListener() { return menuListener; } - private void initializeTimer() { - backgroundUpdater = appSvc.getTimerFactory().createTimer(); - backgroundUpdater.setAction(new Runnable() { - @Override - public void run() { - doUpdateTreeAsync(); - } - }); - backgroundUpdater.setInitialDelay(0); - backgroundUpdater.setDelay(3); - backgroundUpdater.setTimeUnit(TimeUnit.SECONDS); - backgroundUpdater.setSchedulingType(SchedulingType.FIXED_RATE); - } - - private void startBackgroundUpdates() { - backgroundUpdater.start(); - } - - public void stopBackgroundUpdates() { - backgroundUpdater.stop(); - } - @Override public void setHostVmTreeFilter(String filter) { this.hostFilter.setPattern(filter); this.vmFilter.setPattern(filter); - doUpdateTreeAsync(); - } - - public void doUpdateTreeAsync() { - HostsVMsLoader loader = new DefaultHostsVMsLoader(hostInfoDAO, vmInfoDAO, !showHistory); - view.updateTree(hostFilters, vmFilters, hostTreeDecorators, vmTreeDecorators, loader); } private void initView() { view.setWindowTitle(appInfo.getName()); + + view.getHostTreeController().addReferenceSelectionChangeListener(new + ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + updateView((Ref) actionEvent.getPayload()); + } + }); + view.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { MainView.Action action = evt.getActionId(); switch (action) { + + case HIDDEN: case VISIBLE: - startBackgroundUpdates(); - break; - case HIDDEN: - stopBackgroundUpdates(); break; - case HOST_VM_SELECTION_CHANGED: - updateView(); - break; + case HOST_VM_TREE_FILTER: - String filter = view.getHostVmTreeFilterText(); - setHostVmTreeFilter(filter); + // TODO +// String filter = view.getHostVmTreeFilterText(); +// setHostVmTreeFilter(filter); break; case SHOW_AGENT_CONFIG: showAgentConfiguration(); @@ -386,7 +359,8 @@ showConfigureClientPreferences(); break; case SWITCH_HISTORY_MODE: - switchHistoryMode(); + // TODO + //switchHistoryMode(); break; case SHOW_ABOUT_DIALOG: showAboutDialog(); @@ -435,9 +409,15 @@ vmFilterRegistry.addActionListener(vmFilterListener); vmFilterRegistry.start(); + HostTreeController hostTreeController = view.getHostTreeController(); + + DecoratorProviderExtensionListener hostDecoratorListener = + hostTreeController.getHostDecoratorListener(); hostDecoratorRegistry.addActionListener(hostDecoratorListener); hostDecoratorRegistry.start(); - + + DecoratorProviderExtensionListener vmDecoratorListener = + hostTreeController.getVmDecoratorListener(); vmDecoratorRegistry.addActionListener(vmDecoratorListener); vmDecoratorRegistry.start(); @@ -463,12 +443,16 @@ vmFilterListener = null; vmFilterRegistry.stop(); + HostTreeController hostTreeController = view.getHostTreeController(); + + DecoratorProviderExtensionListener hostDecoratorListener = + hostTreeController.getHostDecoratorListener(); hostDecoratorRegistry.removeActionListener(hostDecoratorListener); - hostDecoratorListener = null; hostDecoratorRegistry.stop(); + DecoratorProviderExtensionListener vmDecoratorListener = + hostTreeController.getVmDecoratorListener(); vmDecoratorRegistry.removeActionListener(vmDecoratorListener); - vmDecoratorListener = null; vmDecoratorRegistry.stop(); vmInfoRegistry.removeActionListener(vmInfoRegistryListener); @@ -477,47 +461,48 @@ } private void showContextMenu(ActionEvent evt) { - List toShow = new ArrayList<>(); - - Ref ref = view.getSelectedHostOrVm(); - if (ref instanceof HostRef) { - HostRef vm = (HostRef) ref; - - logger.log(Level.INFO, "registering applicable HostContextActions actions to show"); - - for (HostContextAction action : hostContextActionTracker.getHostContextActions()) { - if (action.getFilter().matches(vm)) { - toShow.add(action); - } - } - } else if (ref instanceof VmRef) { - VmRef vm = (VmRef) ref; - - logger.log(Level.INFO, "registering applicable VMContextActions actions to show"); - - for (VMContextAction action : vmContextActionTracker.getVmContextActions()) { - if (action.getFilter().matches(vm)) { - toShow.add(action); - } - } - } - - view.showContextActions(toShow, (MouseEvent) evt.getPayload()); + // TODO +// List toShow = new ArrayList<>(); +// +// Ref ref = view.getSelectedHostOrVm(); +// if (ref instanceof HostRef) { +// HostRef vm = (HostRef) ref; +// +// logger.log(Level.INFO, "registering applicable HostContextActions actions to show"); +// +// for (HostContextAction action : hostContextActionTracker.getHostContextActions()) { +// if (action.getFilter().matches(vm)) { +// toShow.add(action); +// } +// } +// } else if (ref instanceof VmRef) { +// VmRef vm = (VmRef) ref; +// +// logger.log(Level.INFO, "registering applicable VMContextActions actions to show"); +// +// for (VMContextAction action : vmContextActionTracker.getVmContextActions()) { +// if (action.getFilter().matches(vm)) { +// toShow.add(action); +// } +// } +// } +// +// view.showContextActions(toShow, (MouseEvent) evt.getPayload()); } private void handleVMHooks(ActionEvent event) { - Object payload = event.getPayload(); - try { - if (payload instanceof HostContextAction) { - HostContextAction action = (HostContextAction) payload; - action.execute((HostRef) view.getSelectedHostOrVm()); - } else if (payload instanceof VMContextAction) { - VMContextAction action = (VMContextAction) payload; - action.execute((VmRef) view.getSelectedHostOrVm()); - } - } catch (Throwable error) { - logger.log(Level.SEVERE, "error invocating context action", error); - } +// Object payload = event.getPayload(); +// try { +// if (payload instanceof HostContextAction) { +// HostContextAction action = (HostContextAction) payload; +// action.execute((HostRef) view.getSelectedHostOrVm()); +// } else if (payload instanceof VMContextAction) { +// VMContextAction action = (VMContextAction) payload; +// action.execute((VmRef) view.getSelectedHostOrVm()); +// } +// } catch (Throwable error) { +// logger.log(Level.SEVERE, "error invocating context action", error); +// } } @Override @@ -552,15 +537,7 @@ controller.showDialog(); } - private void switchHistoryMode() { - showHistory = !showHistory; - doUpdateTreeAsync(); - } - - private void updateView() { - // this is quite an ugly method. there must be a cleaner way to do this - Ref ref = view.getSelectedHostOrVm(); - + private void updateView(Ref ref) { if (ref == null) { SummaryController controller = createSummaryController(); view.setSubView(controller.getView()); @@ -608,53 +585,12 @@ switch (actionEvent.getActionId()) { case SERVICE_ADDED: extensionList.add(filter); - doUpdateTreeAsync(); + //doUpdateTreeAsync(); break; case SERVICE_REMOVED: extensionList.remove(filter); - doUpdateTreeAsync(); - break; - - default: - logger.log(Level.WARNING, "received unknown event from ExtensionRegistry: " + - actionEvent.getActionId()); - break; - } - } - } - - private class DecoratorProviderExtensionListener implements ActionListener { - - private final CopyOnWriteArrayList> extensionList; - - public DecoratorProviderExtensionListener(CopyOnWriteArrayList> addRemoveExtensionsFrom) { - this.extensionList = addRemoveExtensionsFrom; - } - - @SuppressWarnings("unchecked") - @Override - public void actionPerformed(ActionEvent actionEvent) { - - Object payload = actionEvent.getPayload(); - DecoratorProvider decorator = null; - - try { - decorator = (DecoratorProvider) payload; - } catch (ClassCastException cce) { - throw new IllegalArgumentException("unexpected payload type. " + payload.getClass().getName() + "not allowed here.", cce); - } - - - switch (actionEvent.getActionId()) { - case SERVICE_ADDED: - extensionList.add(decorator); - doUpdateTreeAsync(); - break; - - case SERVICE_REMOVED: - extensionList.remove(decorator); - doUpdateTreeAsync(); + //doUpdateTreeAsync(); break; default: diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VMMonitorController.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VMMonitorController.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal; + +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.VmRef; +import com.redhat.thermostat.storage.monitor.HostMonitor; +import com.redhat.thermostat.storage.monitor.NetworkMonitor; +import com.redhat.thermostat.storage.monitor.NetworkMonitor.Action; + +class VMMonitorController { + + private NetworkMonitor networkMonitor; + private HostMonitor hostMonitor; + private MainView view; + + private HostChangeListener hostListener; + + public VMMonitorController(NetworkMonitor networkMonitor, + HostMonitor hostMonitor, MainView view) + { + this.hostMonitor = hostMonitor; + this.networkMonitor = networkMonitor; + this.view = view; + this.hostListener = new HostChangeListener(); + } + + void start() { + networkMonitor.addNetworkChangeListener(new NetworkChangeListener()); + } + + class NetworkChangeListener implements ActionListener + { + @Override + public void actionPerformed(ActionEvent actionEvent) { + HostRef host = (HostRef) actionEvent.getPayload(); + switch (actionEvent.getActionId()) { + case HOST_ADDED: + view.getHostTreeController().addHost(host); + hostMonitor.addHostChangeListener(host, hostListener); + break; + + case HOST_REMOVED: + view.getHostTreeController().removeHost(host); + hostMonitor.removeHostChangeListener(host, hostListener); + break; + + default: + break; + } + } + } + + class HostChangeListener implements ActionListener + { + @Override + public void actionPerformed(ActionEvent actionEvent) + { + VmRef vm = (VmRef) actionEvent.getPayload(); + switch (actionEvent.getActionId()) { + case VM_ADDED: + view.getHostTreeController().addVM(vm); + break; + + case VM_REMOVED: + view.getHostTreeController().removeVM(vm); + + default: + break; + } + } + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/components/ThermostatGlassPaneLayout.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/components/ThermostatGlassPaneLayout.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.components; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Rectangle; + +import com.redhat.thermostat.client.swing.components.AbstractLayout; +import com.redhat.thermostat.client.swing.components.OverlayPanel; + +public class ThermostatGlassPaneLayout extends AbstractLayout { + + private static final int GRIP_SIZE = 16; + + @Override + protected void doLayout(Container parent) { + Component[] children = parent.getComponents(); + for (Component _child : children) { + if (!_child.isVisible()) { + continue; + } + + if (_child instanceof OverlayPanel) { + handleOverlay(parent, (OverlayPanel) _child); + } + } + } + + private void handleOverlay(Container parent, OverlayPanel child) { + + // limit the size to some reasonable default so that + // the panel doesn't go offscreen if it grows too much + Dimension preferredSize = child.getPreferredSize(); + if (preferredSize.height > 300) { + preferredSize.height = 300; + } + + // FIXME: the GRIP_SIZE magic number is referred to StatusBar grip icon + // size. There's no way we can access it at the moment, so we + // just rely on the fact that we know it's a 16x16 icon... + // We should probably set this information somewhere so that + // the layout will still work in the unlikely case this icon should + // ever change + int x = parent.getWidth() - preferredSize.width + + child.getInsets().left - GRIP_SIZE + 2; + int y = parent.getHeight() - preferredSize.height + GRIP_SIZE; + Rectangle bounds = + new Rectangle(x, y, preferredSize.width, preferredSize.height); + + child.setSize(preferredSize); + child.setBounds(bounds); + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/progress/AggregateProgressBarOverlayLayout.java --- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/progress/AggregateProgressBarOverlayLayout.java Mon Sep 30 16:38:49 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright 2012, 2013 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * . - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.client.swing.internal.progress; - -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Rectangle; - -import com.redhat.thermostat.client.swing.components.AbstractLayout; -import com.redhat.thermostat.client.swing.components.OverlayPanel; - -public class AggregateProgressBarOverlayLayout extends AbstractLayout { - - @Override - protected void doLayout(Container parent) { - Component[] children = parent.getComponents(); - for (Component _child : children) { - if (!(_child instanceof OverlayPanel)) { - continue; - } - - OverlayPanel child = (OverlayPanel) _child; - if (!child.isVisible()) { - continue; - } - - // limit the size to some reasonable default so that - // the panel doesn't go offscreen if it grows too much - Dimension preferredSize = child.getPreferredSize(); - if (preferredSize.height > 300) { - preferredSize.height = 300; - } - - // FIXME: the magic number is referred to StatusBar grip icon - // size. There's no way we can access it at the moment, so we - // just rely on the fact that we know it's a 16x16 icon... - // We should probably set this information somewhere so that - // the layout will still work in the unlikely case this icon should - // ever change - int x = parent.getWidth() - preferredSize.width + - child.getInsets().left - 16 + 2; - int y = parent.getHeight() - preferredSize.height + 16; - Rectangle bounds = - new Rectangle(x, y, preferredSize.width, preferredSize.height); - - child.setSize(preferredSize); - child.setBounds(bounds); - } - } -} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/BaseIcon.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/BaseIcon.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Paint; +import java.awt.image.BufferedImage; +import java.beans.Transient; + +import com.redhat.thermostat.client.swing.GraphicsUtils; +import com.redhat.thermostat.client.swing.components.Icon; + +@SuppressWarnings("serial") +class BaseIcon extends Icon { + + private boolean selected; + private Icon source; + + public BaseIcon(boolean selected, Icon source) { + this.selected = selected; + this.source = source; + } + + @Override + public synchronized void paintIcon(Component c, Graphics g, int x, int y) { + GraphicsUtils utils = GraphicsUtils.getInstance(); + Graphics2D graphics = utils.createAAGraphics(g); + graphics.setPaint(getPaint()); + graphics.fillRect(x, y, getIconWidth(), getIconHeight()); + graphics.dispose(); + } + + @Override + public int getIconHeight() { + return source.getIconHeight(); + } + + @Override + public int getIconWidth() { + return source.getIconWidth(); + } + + private Paint getPaint() { + UIDefaults palette = UIDefaults.getInstance(); + Color color = palette.getComponentFGColor(); + if (selected) { + color = palette.getSelectedComponentFGColor(); + } + return color; + } + + @Override + @Transient + public Image getImage() { + BufferedImage image = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g = (Graphics2D) image.getGraphics(); + paintIcon(null, g, 0, 0); + g.dispose(); + return image; + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/HostTreeComponentFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/HostTreeComponentFactory.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import com.redhat.thermostat.client.swing.internal.accordion.AccordionComponent; +import com.redhat.thermostat.client.swing.internal.accordion.AccordionComponentFactory; +import com.redhat.thermostat.client.swing.internal.accordion.TitledPane; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorManager; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.VmRef; + +public class HostTreeComponentFactory implements AccordionComponentFactory{ + + private DecoratorManager decoratorManager; + + public HostTreeComponentFactory(DecoratorManager decoratorManager) { + this.decoratorManager = decoratorManager; + } + + @Override + public TitledPane createHeader(HostRef header) { + ReferenceTitle pane = new ReferenceTitle(header); + decoratorManager.registerAndSetIcon(pane); + return pane; + } + + @Override + public AccordionComponent createComponent(HostRef header, VmRef component) { + ReferenceComponent refComponent = new ReferenceComponent(component); + decoratorManager.registerAndSetIcon(refComponent); + return refComponent; + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponent.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,154 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import com.redhat.thermostat.client.swing.GraphicsUtils; +import com.redhat.thermostat.client.swing.components.CompositeIcon; +import com.redhat.thermostat.client.swing.components.Icon; +import com.redhat.thermostat.client.swing.components.ShadowLabel; +import com.redhat.thermostat.client.swing.internal.accordion.AccordionComponent; +import com.redhat.thermostat.client.ui.Palette; +import com.redhat.thermostat.storage.core.Ref; + +@SuppressWarnings("serial") +public class ReferenceComponent extends JPanel implements AccordionComponent, ReferenceProvider { + + private ShadowLabel mainLabel; + private JLabel iconLabel; + + private boolean highlight; + + private boolean selected; + + private Icon selectedIcon; + private Icon icon; + + private Ref vm; + + public ReferenceComponent(Ref vm) { + + this.vm = vm; + + setLayout(new BorderLayout()); + + mainLabel = new ShadowLabel(); + mainLabel.setForeground(Palette.DROID_GRAY.getColor()); + + mainLabel.setText(vm.getName()); + add(mainLabel, BorderLayout.CENTER); + iconLabel = new JLabel(); + iconLabel.setText(" "); + add(iconLabel, BorderLayout.WEST); + } + + @Override + public Component getUiComponent() { + return this; + } + + @Override + public void setSelected(boolean selected) { + this.selected = selected; + setState(); + } + + private void setState() { + UIDefaults palette = UIDefaults.getInstance(); + if (selected) { + mainLabel.setForeground(palette.getSelectedComponentFGColor()); + mainLabel.setIcon(selectedIcon); + } else if (!highlight) { + mainLabel.setForeground(palette.getComponentFGColor()); + mainLabel.setIcon(icon); + } + repaint(); + } + + @Override + public boolean isSelected() { + return selected; + } + + @Override + public Ref getReference() { + return vm; + } + + @Override + protected void paintComponent(Graphics g) { + + super.paintComponent(g); + + UIDefaults palette = UIDefaults.getInstance(); + + GraphicsUtils utils = GraphicsUtils.getInstance(); + Graphics2D graphics = utils.createAAGraphics(g); + if (isSelected()) { + + Color start = utils.deriveWithAlpha(palette.getSelectedComponentBGColor(), 0.6f); + Color stop = utils.deriveWithAlpha(palette.getSelectedComponentBGColor(), 0.80f); + utils.setGradientPaint(graphics, 0, getHeight(), start, stop); + + } else { + graphics.setColor(getBackground()); + } + + Rectangle bounds = graphics.getClipBounds(); + graphics.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); + graphics.dispose(); + } + + public void setIcon(Icon icon) { + this.icon = icon; + this.selectedIcon = new CompositeIcon(icon, new BaseIcon(true, icon)); + setState(); + } + + public Icon getIcon() { + return icon; + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponentPainter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceComponentPainter.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,78 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +import com.redhat.thermostat.client.swing.GraphicsUtils; +import com.redhat.thermostat.client.swing.internal.accordion.AccordionComponent; +import com.redhat.thermostat.client.swing.internal.accordion.TitledPanePainter; + +public class ReferenceComponentPainter implements TitledPanePainter { + + @Override + public Color getSelectedForeground() { + return UIDefaults.getInstance().getSelectedComponentFGColor(); + } + + @Override + public Color getUnselectedForeground() { + return UIDefaults.getInstance().getComponentFGColor(); + } + + @Override + public void paint(Graphics2D g, AccordionComponent component, int width, int height) { + UIDefaults palette = UIDefaults.getInstance(); + + GraphicsUtils utils = GraphicsUtils.getInstance(); + Graphics2D graphics = utils.createAAGraphics(g); + if (component.isSelected()) { + + Color start = utils.deriveWithAlpha(palette.getSelectedComponentBGColor(), 0.6f); + Color stop = utils.deriveWithAlpha(palette.getSelectedComponentBGColor(), 0.80f); + utils.setGradientPaint(graphics, 0, component.getUiComponent().getHeight(), start, stop); + } else { + graphics.setColor(component.getUiComponent().getBackground()); + } + + Rectangle bounds = graphics.getClipBounds(); + graphics.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); + graphics.dispose(); + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceProvider.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import com.redhat.thermostat.storage.core.Ref; + +public interface ReferenceProvider { + Ref getReference(); +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceTitle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/ReferenceTitle.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import com.redhat.thermostat.client.swing.components.Icon; +import com.redhat.thermostat.client.swing.internal.accordion.TitledPane; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.Ref; + +@SuppressWarnings("serial") +public class ReferenceTitle extends TitledPane implements ReferenceProvider { + + private HostRef ref; + + public ReferenceTitle(HostRef ref) { + super(ref.getHostName(), new ReferenceComponentPainter(), new ReferenceComponent(ref)); + this.ref = ref; + } + + @Override + public Ref getReference() { + return ref; + } + + public void setIcon(Icon icon) { + ((ReferenceComponent) getTitleComponent()).setIcon(icon); + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/UIDefaults.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/UIDefaults.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,67 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist; + +import java.awt.Color; + +import com.redhat.thermostat.client.ui.Palette; + +/** + * + */ +public class UIDefaults { + private static final UIDefaults palette = new UIDefaults(); + public static UIDefaults getInstance() { + return palette; + } + + public Color getSelectedComponentFGColor() { + return Palette.DROID_GRAY.getColor(); + } + + public Color getComponentFGColor() { + return Palette.DROID_BLACK.getColor(); + } + + public Color getSelectedComponentBGColor() { + return Palette.AZUREUS.getColor(); + } + + public int getIconSize() { + return 24; + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorManager.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,160 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist.controller; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.util.HashMap; +import java.util.Map; + +import com.redhat.thermostat.client.swing.components.EmptyIcon; +import com.redhat.thermostat.client.swing.components.Icon; +import com.redhat.thermostat.client.swing.internal.vmlist.ReferenceComponent; +import com.redhat.thermostat.client.swing.internal.vmlist.ReferenceTitle; +import com.redhat.thermostat.client.swing.internal.vmlist.UIDefaults; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorProviderExtensionListener.Action; +import com.redhat.thermostat.client.ui.Decorator; +import com.redhat.thermostat.client.ui.DecoratorProvider; +import com.redhat.thermostat.client.ui.IconDescriptor; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.Ref; +import com.redhat.thermostat.storage.core.VmRef; + +public class DecoratorManager { + + private DecoratorProviderExtensionListener hostDecorator = new DecoratorProviderExtensionListener<>(); + private DecoratorProviderExtensionListener vmDecorator = new DecoratorProviderExtensionListener<>(); + + private Map decoratorsCache = new HashMap<>(); + + public void registerAndSetIcon(final ReferenceComponent component) { + component.setIcon(createIcon(vmDecorator, (VmRef) component.getReference())); + // FIXME: this is a leak + vmDecorator.addDecoratorChangeListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + component.setIcon(createIcon(vmDecorator, (VmRef) component.getReference())); + } + }); + } + + public void registerAndSetIcon(final ReferenceTitle pane) { + pane.setIcon(createIcon(hostDecorator, (HostRef) pane.getReference())); + // FIXME: this is a leak + hostDecorator.addDecoratorChangeListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + pane.setIcon(createIcon(hostDecorator, (HostRef) pane.getReference())); + } + }); + } + + private Icon createIcon(DecoratorProviderExtensionListener listener, R ref) + { + UIDefaults uiDefaults = UIDefaults.getInstance(); + int size = uiDefaults.getIconSize(); + Icon canvas = new EmptyIcon(size, size); + + // FIXME: this logic is broken, since we simply iterate over + // icon locations, instead we need to at least sort them + // in painter's order + for (DecoratorProvider provider : listener.getDecorators()) { + + if (!provider.getFilter().matches(ref)) { + continue; + } + + Decorator decorator = provider.getDecorator(); + Icon icon = getIconFromCache(decorator); + if (icon == null) { + continue; + } + + switch (decorator.getQuadrant()) { + case MAIN: + case TOP_LEFT: + canvas = createCustomIcon(canvas, icon, 0); + break; + + case BOTTOM_LEFT: + int y = canvas.getIconHeight() - icon.getIconHeight(); + canvas = createCustomIcon(canvas, icon, y); + break; + + default: + // FIXME: log me? + break; + } + + } + + return canvas; + } + + Icon getIconFromCache(Decorator decorator) { + Icon icon = decoratorsCache.get(decorator); + if (icon == null) { + IconDescriptor iconDescriptor = decorator.getIconDescriptor(); + if (iconDescriptor != null) { + icon = new Icon(iconDescriptor); + decoratorsCache.put(decorator, icon); + } + } + return icon; + } + + private Icon createCustomIcon(Icon source, Icon newIcon, int y) { + BufferedImage image = new BufferedImage(source.getIconWidth(), + source.getIconHeight(), + BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = (Graphics2D) image.getGraphics(); + source.paintIcon(null, graphics, 0, 0); + graphics.drawImage(newIcon.getImage(), 0, y, null); + + return new Icon(image); + } + + DecoratorProviderExtensionListener getHostDecoratorListener() { + return hostDecorator; + } + + DecoratorProviderExtensionListener getVmDecoratorListener() { + return vmDecorator; + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorProviderExtensionListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/DecoratorProviderExtensionListener.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist.controller; + +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.client.ui.DecoratorProvider; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.ActionNotifier; +import com.redhat.thermostat.common.ThermostatExtensionRegistry; +import com.redhat.thermostat.storage.core.Ref; + +/* + * Provide an implementation of a listener for Registry update. This listener + * is only to be used to listen for DecoratorProvider changes and its sole + * purpouse is to re-route the generic VmRef or HostRef DecoratorProvider + * changes to the actual Decoration Manager. + */ +public class DecoratorProviderExtensionListener implements ActionListener +{ + public enum Action { + DECORATOR_ADDED, + DECORATOR_REMOVED, + } + + private final ActionNotifier decoratorChangeNotifier; + + private Logger logger = Logger.getLogger(DecoratorProviderExtensionListener.class.getSimpleName()); + + private CopyOnWriteArrayList> decorators; + + public DecoratorProviderExtensionListener() { + this.decoratorChangeNotifier = new ActionNotifier<>(this); + decorators = new CopyOnWriteArrayList<>(); + } + + public void addDecoratorChangeListener(ActionListener listener) { + decoratorChangeNotifier.addActionListener(listener); + } + + public void removeDecoratorChangeListener(ActionListener listener) { + decoratorChangeNotifier.removeActionListener(listener); + } + + @SuppressWarnings("unchecked") + @Override + public void actionPerformed(ActionEvent actionEvent) + { + Object payload = actionEvent.getPayload(); + if (! (payload instanceof DecoratorProvider)) { + throw new IllegalArgumentException("unexpected payload type. " + + payload.getClass().getName() + + "not allowed here."); + } + + decorators.add((DecoratorProvider) payload); + + switch (actionEvent.getActionId()) { + case SERVICE_ADDED: + decoratorChangeNotifier.fireAction(Action.DECORATOR_ADDED, payload); + break; + + case SERVICE_REMOVED: + decoratorChangeNotifier.fireAction(Action.DECORATOR_REMOVED, payload); + break; + + default: + logger.log(Level.WARNING, "received unknown event from ExtensionRegistry: " + + actionEvent.getActionId()); + break; + } + } + + CopyOnWriteArrayList> getDecorators() { + return decorators; + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/HostTreeController.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/vmlist/controller/HostTreeController.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,127 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal.vmlist.controller; + +import javax.swing.SwingUtilities; + +import com.redhat.thermostat.client.swing.internal.accordion.Accordion; +import com.redhat.thermostat.client.swing.internal.accordion.AccordionItemSelectedChangeListener; +import com.redhat.thermostat.client.swing.internal.accordion.AccordionModel; +import com.redhat.thermostat.client.swing.internal.accordion.ItemSelectedEvent; +import com.redhat.thermostat.client.swing.internal.vmlist.ReferenceProvider; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.common.ActionNotifier; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.core.VmRef; + +public class HostTreeController { + + public static enum ReferenceSelection { + ITEM_SELECTED; + } + + private DecoratorManager decoratorManager; + + private final ActionNotifier referenceNotifier; + + private AccordionModel model; + + public HostTreeController(Accordion accordion, DecoratorManager decoratorManager) { + this.decoratorManager = decoratorManager; + referenceNotifier = new ActionNotifier<>(this); + this.model = accordion.getModel(); + accordion.addAccordionItemSelectedChangeListener(new AccordionItemSelectedChangeListener() { + @Override + public void itemSelected(ItemSelectedEvent event) { + ReferenceProvider provider = (ReferenceProvider) event.getSelected(); + referenceNotifier.fireAction(ReferenceSelection.ITEM_SELECTED, provider.getReference()); + } + }); + } + + public void addReferenceSelectionChangeListener(ActionListener listener) { + referenceNotifier.addActionListener(listener); + } + + public void removeReferenceSelectionChangeListener(ActionListener listener) { + referenceNotifier.removeActionListener(listener); + } + + public void addHost(final HostRef host) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + model.addHeader(host); + } + }); + } + + public void removeHost(final HostRef host) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + model.removeHeader(host); + } + }); + } + + public void addVM(final VmRef vm) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + model.addComponent(vm.getHostRef(), vm); + } + }); + } + + public void removeVM(final VmRef vm) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + model.removeComponent(vm.getHostRef(), vm); + } + }); + } + + public DecoratorProviderExtensionListener getHostDecoratorListener() { + return decoratorManager.getHostDecoratorListener(); + } + + public DecoratorProviderExtensionListener getVmDecoratorListener() { + return decoratorManager.getVmDecoratorListener(); + } +} \ No newline at end of file diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java --- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java Mon Sep 30 16:38:50 2013 +0200 @@ -39,22 +39,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.awt.event.MouseEvent; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import org.fest.swing.edt.FailOnThreadViolationRepaintManager; import org.junit.After; @@ -67,7 +59,6 @@ import com.redhat.thermostat.client.core.Filter; import com.redhat.thermostat.client.core.progress.ProgressNotifier; import com.redhat.thermostat.client.core.views.AgentInformationViewProvider; -import com.redhat.thermostat.client.core.views.BasicView; import com.redhat.thermostat.client.core.views.ClientConfigViewProvider; import com.redhat.thermostat.client.core.views.HostInformationView; import com.redhat.thermostat.client.core.views.HostInformationViewProvider; @@ -75,8 +66,8 @@ import com.redhat.thermostat.client.core.views.SummaryViewProvider; import com.redhat.thermostat.client.core.views.VmInformationView; import com.redhat.thermostat.client.core.views.VmInformationViewProvider; -import com.redhat.thermostat.client.ui.ContextAction; -import com.redhat.thermostat.client.ui.DecoratorProvider; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.DecoratorProviderExtensionListener; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController; import com.redhat.thermostat.client.ui.HostContextAction; import com.redhat.thermostat.client.ui.MenuAction; import com.redhat.thermostat.client.ui.MenuRegistry; @@ -87,25 +78,24 @@ import com.redhat.thermostat.common.ThermostatExtensionRegistry; import com.redhat.thermostat.common.ThermostatExtensionRegistry.Action; import com.redhat.thermostat.common.Timer; -import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.TimerFactory; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.storage.core.HostRef; -import com.redhat.thermostat.storage.core.HostsVMsLoader; import com.redhat.thermostat.storage.core.VmRef; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.dao.BackendInfoDAO; import com.redhat.thermostat.storage.dao.HostInfoDAO; import com.redhat.thermostat.storage.dao.VmInfoDAO; -import com.redhat.thermostat.storage.model.VmInfo; -import com.redhat.thermostat.test.Bug; +import com.redhat.thermostat.storage.monitor.HostMonitor; +import com.redhat.thermostat.storage.monitor.NetworkMonitor; import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.utils.keyring.Keyring; public class MainWindowControllerImplTest { private ActionListener l; - + private ActionListener hostTreeListener; + private MainWindowControllerImpl controller; private MainView view; @@ -125,12 +115,6 @@ private VMTreeDecoratorRegistry vmDecoratorRegistry; private VMInformationRegistry vmInfoRegistry; private MenuRegistry menus; - - @SuppressWarnings("unused") - private ActionListener hostFiltersListener; - @SuppressWarnings("unused") - private ActionListener vmFiltersListener; - private ActionListener decoratorsListener; private StubBundleContext context; private CountDownLatch shutdown; @@ -138,6 +122,11 @@ private VmInformationView vmInfoView; private VmInformationViewProvider vmInfoViewProvider; + private HostTreeController treeController; + + private DecoratorProviderExtensionListener hostDecorators; + private DecoratorProviderExtensionListener vmDecorators; + @BeforeClass public static void setUpOnce() { // TODO remove when controller uses mocked objects rather than real swing objects @@ -190,11 +179,27 @@ ClientConfigViewProvider clientConfigViewProvider = mock(ClientConfigViewProvider.class); context.registerService(ClientConfigViewProvider.class, clientConfigViewProvider, null); + HostMonitor hostMonitor = mock(HostMonitor.class); + context.registerService(HostMonitor.class, hostMonitor, null); + NetworkMonitor networkMonitor = mock(NetworkMonitor.class); + context.registerService(NetworkMonitor.class, networkMonitor, null); + // Setup View view = mock(MainView.class); ArgumentCaptor grabListener = ArgumentCaptor.forClass(ActionListener.class); doNothing().when(view).addActionListener(grabListener.capture()); + hostDecorators = mock(DecoratorProviderExtensionListener.class); + vmDecorators = mock(DecoratorProviderExtensionListener.class); + + treeController = mock(HostTreeController.class); + ArgumentCaptor hostTreeCaptor = ArgumentCaptor.forClass(ActionListener.class); + when(view.getHostTreeController()).thenReturn(treeController); + when(treeController.getHostDecoratorListener()).thenReturn(hostDecorators); + when(treeController.getVmDecoratorListener()).thenReturn(vmDecorators); + + doNothing().when(treeController).addReferenceSelectionChangeListener(hostTreeCaptor.capture()); + ProgressNotifier notifier = mock(ProgressNotifier.class); when(view.getNotifier()).thenReturn(notifier); @@ -230,15 +235,14 @@ setUpVMContextActions(); controller = new MainWindowControllerImpl(context, appSvc, view, registryFactory, shutdown); + l = grabListener.getValue(); - - hostFiltersListener = grabHostFiltersListener.getValue(); - vmFiltersListener = grabVmFiltersListener.getValue(); - decoratorsListener = grabDecoratorsListener.getValue(); + hostTreeListener = hostTreeCaptor.getValue(); } private void setUpHostContextActions() { hostContextAction1 = mock(HostContextAction.class); + @SuppressWarnings("unchecked") Filter hostFilter1 = mock(Filter.class); when(hostFilter1.matches(isA(HostRef.class))).thenReturn(true); @@ -249,6 +253,7 @@ context.registerService(HostContextAction.class, hostContextAction1, null); } + @SuppressWarnings({ "rawtypes", "unchecked" }) private void setUpVMContextActions() { vmContextAction1 = mock(VMContextAction.class); Filter action1Filter = mock(Filter.class); @@ -280,144 +285,36 @@ l = null; } - @SuppressWarnings("unchecked") @Test - public void verifyDecoratorsAdded() { + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void verifyDecoratorsRegisteredAndStarted() { - List> currentDecoratros = controller.getVmTreeDecorators(); - assertEquals(0, currentDecoratros.size()); - - ActionEvent event = - new ActionEvent(vmDecoratorRegistry, - ThermostatExtensionRegistry.Action.SERVICE_ADDED); + ArgumentCaptor captor1 = ArgumentCaptor.forClass(ActionListener.class); + ArgumentCaptor captor2 = ArgumentCaptor.forClass(ActionListener.class); + + verify(view, atLeastOnce()).getHostTreeController(); + verify(treeController).getHostDecoratorListener(); + verify(treeController).getVmDecoratorListener(); - DecoratorProvider payload = mock(DecoratorProvider.class); - event.setPayload(payload); + verify(hostDecoratorRegistry).addActionListener(captor1.capture()); + verify(vmDecoratorRegistry).addActionListener(captor2.capture()); - decoratorsListener.actionPerformed(event); + verify(hostDecoratorRegistry).start(); + verify(vmDecoratorRegistry).start(); - currentDecoratros = controller.getVmTreeDecorators(); - assertEquals(1, currentDecoratros.size()); - assertEquals(payload, currentDecoratros.get(0)); + ActionListener l1 = captor1.getValue(); + ActionListener l2 = captor2.getValue(); - verify(view).updateTree(any(List.class), isA(List.class), isA(List.class), any(List.class), any(HostsVMsLoader.class)); + assertEquals(hostDecorators, l1); + assertEquals(vmDecorators, l2); } @Test - public void verifyThatHiddenEventStopsController() { - - l.actionPerformed(new ActionEvent(view, MainView.Action.HIDDEN)); - - verify(mainWindowTimer).stop(); - } - - @SuppressWarnings("unchecked") - @Test - public void verifyThatHostsVmsFilterChangeUpdatesTree() { - - when(view.getHostVmTreeFilterText()).thenReturn("test"); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_TREE_FILTER)); - - verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), isA(HostsVMsLoader.class)); - } - - @Test - public void verifyTimerGetsStartedOnBecomingVisible() { - l.actionPerformed(new ActionEvent(view, MainView.Action.VISIBLE)); - - verify(mainWindowTimer).setDelay(3); - verify(mainWindowTimer).setTimeUnit(TimeUnit.SECONDS); - verify(mainWindowTimer).setSchedulingType(SchedulingType.FIXED_RATE); - verify(mainWindowTimer).start(); - } - - @Test public void verifyShowMainWindowActuallyCallsView() { controller.showMainMainWindow(); verify(view).showMainWindow(); } - - @Test - public void verifySubViewIsSetByDefault() throws InvocationTargetException, InterruptedException { - verify(view).setSubView(any(BasicView.class)); - } - - @SuppressWarnings("unchecked") - @Test - public void verifyUpdateHostsVMsLoadsCorrectHosts() { - - Collection expectedHosts = new ArrayList<>(); - expectedHosts.add(new HostRef("123", "fluffhost1")); - expectedHosts.add(new HostRef("456", "fluffhost2")); - - when(mockHostsDAO.getAliveHosts()).thenReturn(expectedHosts); - - controller.doUpdateTreeAsync(); - - ArgumentCaptor arg = ArgumentCaptor.forClass(HostsVMsLoader.class); - verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture()); - HostsVMsLoader loader = arg.getValue(); - - Collection actualHosts = loader.getHosts(); - assertEqualCollection(expectedHosts, actualHosts); - } - @SuppressWarnings("unchecked") - @Test - public void verifyHistoryModeUpdateHostsVMCorrectly() { - - Collection liveHost = new ArrayList<>(); - liveHost.add(new HostRef("123", "fluffhost1")); - liveHost.add(new HostRef("456", "fluffhost2")); - - Collection allHosts = new ArrayList<>(); - allHosts.addAll(liveHost); - allHosts.add(new HostRef("789", "fluffhost3")); - - when(mockHostsDAO.getAliveHosts()).thenReturn(liveHost); - when(mockHostsDAO.getHosts()).thenReturn(allHosts); - - controller.doUpdateTreeAsync(); - - ArgumentCaptor arg = ArgumentCaptor.forClass(HostsVMsLoader.class); - verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture()); - HostsVMsLoader loader = arg.getValue(); - - Collection actualHosts = loader.getHosts(); - assertEqualCollection(liveHost, actualHosts); - - l.actionPerformed(new ActionEvent(view, MainView.Action.SWITCH_HISTORY_MODE)); - ArgumentCaptor argCaptor = ArgumentCaptor.forClass(HostsVMsLoader.class); - // actionPerformed triggers updateTree - verify(view, times(2)).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), argCaptor.capture()); - loader = argCaptor.getValue(); - - actualHosts = loader.getHosts(); - assertEqualCollection(allHosts, actualHosts); - } - - @SuppressWarnings("unchecked") - @Test - public void verifyUpdateHostsVMsLoadsCorrectVMs() { - - Collection expectedVMs = new ArrayList<>(); - HostRef host = new HostRef("123", "fluffhost1"); - expectedVMs.add(new VmRef(host, "321", 123, "vm1")); - expectedVMs.add(new VmRef(host, "654", 456, "vm2")); - - when(mockVmsDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs); - - controller.doUpdateTreeAsync(); - - ArgumentCaptor arg = ArgumentCaptor.forClass(HostsVMsLoader.class); - verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture()); - HostsVMsLoader loader = arg.getValue(); - - Collection actualVMs = loader.getVMs(host); - assertEqualCollection(expectedVMs, actualVMs); - } - @Test public void verifyUpdateHostsVMsLoadsCorrectVMWithFilter() { @@ -436,183 +333,183 @@ assertFalse(filter.matches(ref2)); } - private void assertEqualCollection(Collection expected, Collection actual) { - assertEquals(expected.size(), actual.size()); - assertTrue(expected.containsAll(actual)); - } - - @Test - @Bug(id="954", - summary="Thermostat GUI client should remember my last panel selected", - url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954") - public void verifyOpenSameHostVMTab() throws Exception { - - VmRef vmRef = mock(VmRef.class); - when(vmRef.getName()).thenReturn("testvm"); - when(vmRef.getVmId()).thenReturn("testvmid"); - HostRef ref = mock(HostRef.class); - when(ref.getAgentId()).thenReturn("agentId"); - when(vmRef.getHostRef()).thenReturn(ref); - - when(view.getSelectedHostOrVm()).thenReturn(vmRef); - - when(vmInfoView.getSelectedChildID()).thenReturn(3); - when(vmInfoView.selectChildID(anyInt())).thenReturn(true); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); - - ArgumentCaptor arg = ArgumentCaptor.forClass(Integer.class); - verify(vmInfoView).selectChildID(arg.capture()); - verify(vmInfoView, times(0)).getSelectedChildID(); - - int id = arg.getValue(); - - assertEquals(0, id); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); - - arg = ArgumentCaptor.forClass(Integer.class); - verify(vmInfoView, times(1)).getSelectedChildID(); - verify(vmInfoView, times(2)).selectChildID(arg.capture()); - id = arg.getValue(); - - assertEquals(3, id); - } - - @Test - public void verifyOpenSameHostVMTab2() { - - VmRef vmRef1 = mock(VmRef.class); - VmRef vmRef2 = mock(VmRef.class); - when(view.getSelectedHostOrVm()).thenReturn(vmRef1).thenReturn(vmRef1).thenReturn(vmRef2).thenReturn(vmRef1); - - when(vmRef1.getName()).thenReturn("testvm"); - when(vmRef1.getVmId()).thenReturn("testvmid"); - HostRef ref = mock(HostRef.class); - when(ref.getAgentId()).thenReturn("agentId"); - when(vmRef1.getHostRef()).thenReturn(ref); - - when(vmRef2.getName()).thenReturn("testvm"); - when(vmRef2.getVmId()).thenReturn("testvmid"); - when(vmRef2.getHostRef()).thenReturn(ref); - - VmInformationView vmInfoView2 = mock(VmInformationView.class); - - when(vmInfoView.getSelectedChildID()).thenReturn(2).thenReturn(2); - when(vmInfoView2.getSelectedChildID()).thenReturn(3); - - when(vmInfoView.selectChildID(0)).thenReturn(true); - when(vmInfoView.selectChildID(2)).thenReturn(true); - when(vmInfoView.selectChildID(3)).thenReturn(false); - - when(vmInfoView2.selectChildID(0)).thenReturn(true); - when(vmInfoView2.selectChildID(2)).thenReturn(true); - when(vmInfoView2.selectChildID(3)).thenReturn(true); - - when(vmInfoViewProvider.createView()).thenReturn(vmInfoView) - .thenReturn(vmInfoView2).thenReturn(vmInfoView2) - .thenReturn(vmInfoView); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); - - ArgumentCaptor arg = ArgumentCaptor.forClass(Integer.class); - verify(vmInfoView).selectChildID(arg.capture()); - verify(vmInfoView, times(0)).getSelectedChildID(); - - int id = arg.getValue(); - - assertEquals(0, id); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); - - arg = ArgumentCaptor.forClass(Integer.class); - verify(vmInfoView).getSelectedChildID(); - verify(vmInfoView2, times(1)).selectChildID(arg.capture()); - id = arg.getValue(); - - assertEquals(2, id); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); - - arg = ArgumentCaptor.forClass(Integer.class); - verify(vmInfoView2, times(1)).getSelectedChildID(); - verify(vmInfoView2, times(2)).selectChildID(arg.capture()); - id = arg.getValue(); - - assertEquals(3, id); - - l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); - - arg = ArgumentCaptor.forClass(Integer.class); - verify(vmInfoView2, times(2)).getSelectedChildID(); - verify(vmInfoView, times(3)).selectChildID(arg.capture()); - id = arg.getValue(); - - assertEquals(2, id); - } - - @Test - public void verifyHostActionsAreShown() { - HostRef host = mock(HostRef.class); - when(view.getSelectedHostOrVm()).thenReturn(host); - - MouseEvent uiEvent = mock(MouseEvent.class); - ActionEvent viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_HOST_VM_CONTEXT_MENU); - viewEvent.setPayload(uiEvent); - - l.actionPerformed(viewEvent); - - List actions = new ArrayList<>(); - actions.add(hostContextAction1); - - verify(view).showContextActions(actions, uiEvent); - } - - @Test - public void verityVMActionsAreShown() { - VmInfo vmInfo = new VmInfo("foo", "123", 0, 1, 2, null, null, null, null, null, null, null, null, null, null, null, -1, null); - when(mockVmsDAO.getVmInfo(isA(VmRef.class))).thenReturn(vmInfo); - - VmRef ref = mock(VmRef.class); - when(view.getSelectedHostOrVm()).thenReturn(ref); - - MouseEvent uiEvent = mock(MouseEvent.class); - ActionEvent viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_HOST_VM_CONTEXT_MENU); - viewEvent.setPayload(uiEvent); - - l.actionPerformed(viewEvent); - - List actions = new ArrayList<>(); - actions.add(vmContextAction1); - - verify(view).showContextActions(actions, uiEvent); - } - - @Test - public void verifyHostActionsAreExecuted() { - HostRef hostRef = mock(HostRef.class); - when(view.getSelectedHostOrVm()).thenReturn(hostRef); - - ActionEvent event = new ActionEvent<>(view, MainView.Action.HOST_VM_CONTEXT_ACTION); - event.setPayload(hostContextAction1); - l.actionPerformed(event); - - verify(hostContextAction1, times(1)).execute(hostRef); - } - - @Test - public void verityVMActionsAreExecuted() { - - VmRef vmRef = mock(VmRef.class); - when(view.getSelectedHostOrVm()).thenReturn(vmRef); - - ActionEvent event = new ActionEvent<>(view, MainView.Action.HOST_VM_CONTEXT_ACTION); - event.setPayload(vmContextAction1); - l.actionPerformed(event); - - verify(vmContextAction1, times(1)).execute(any(VmRef.class)); - verify(vmContextAction2, times(0)).execute(any(VmRef.class)); - } +// private void assertEqualCollection(Collection expected, Collection actual) { +// assertEquals(expected.size(), actual.size()); +// assertTrue(expected.containsAll(actual)); +// } +// +// @Test +// @Bug(id="954", +// summary="Thermostat GUI client should remember my last panel selected", +// url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954") +// public void verifyOpenSameHostVMTab() throws Exception { +// +// VmRef vmRef = mock(VmRef.class); +// when(vmRef.getName()).thenReturn("testvm"); +// when(vmRef.getVmId()).thenReturn("testvmid"); +// HostRef ref = mock(HostRef.class); +// when(ref.getAgentId()).thenReturn("agentId"); +// when(vmRef.getHostRef()).thenReturn(ref); +// +// when(view.getSelectedHostOrVm()).thenReturn(vmRef); +// +// when(vmInfoView.getSelectedChildID()).thenReturn(3); +// when(vmInfoView.selectChildID(anyInt())).thenReturn(true); +// +// l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(Integer.class); +// verify(vmInfoView).selectChildID(arg.capture()); +// verify(vmInfoView, times(0)).getSelectedChildID(); +// +// int id = arg.getValue(); +// +// assertEquals(0, id); +// +// l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); +// +// arg = ArgumentCaptor.forClass(Integer.class); +// verify(vmInfoView, times(1)).getSelectedChildID(); +// verify(vmInfoView, times(2)).selectChildID(arg.capture()); +// id = arg.getValue(); +// +// assertEquals(3, id); +// } +// +// @Test +// public void verifyOpenSameHostVMTab2() { +// +// VmRef vmRef1 = mock(VmRef.class); +// VmRef vmRef2 = mock(VmRef.class); +// when(view.getSelectedHostOrVm()).thenReturn(vmRef1).thenReturn(vmRef1).thenReturn(vmRef2).thenReturn(vmRef1); +// +// when(vmRef1.getName()).thenReturn("testvm"); +// when(vmRef1.getVmId()).thenReturn("testvmid"); +// HostRef ref = mock(HostRef.class); +// when(ref.getAgentId()).thenReturn("agentId"); +// when(vmRef1.getHostRef()).thenReturn(ref); +// +// when(vmRef2.getName()).thenReturn("testvm"); +// when(vmRef2.getVmId()).thenReturn("testvmid"); +// when(vmRef2.getHostRef()).thenReturn(ref); +// +// VmInformationView vmInfoView2 = mock(VmInformationView.class); +// +// when(vmInfoView.getSelectedChildID()).thenReturn(2).thenReturn(2); +// when(vmInfoView2.getSelectedChildID()).thenReturn(3); +// +// when(vmInfoView.selectChildID(0)).thenReturn(true); +// when(vmInfoView.selectChildID(2)).thenReturn(true); +// when(vmInfoView.selectChildID(3)).thenReturn(false); +// +// when(vmInfoView2.selectChildID(0)).thenReturn(true); +// when(vmInfoView2.selectChildID(2)).thenReturn(true); +// when(vmInfoView2.selectChildID(3)).thenReturn(true); +// +// when(vmInfoViewProvider.createView()).thenReturn(vmInfoView) +// .thenReturn(vmInfoView2).thenReturn(vmInfoView2) +// .thenReturn(vmInfoView); +// +// l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); +// +// ArgumentCaptor arg = ArgumentCaptor.forClass(Integer.class); +// verify(vmInfoView).selectChildID(arg.capture()); +// verify(vmInfoView, times(0)).getSelectedChildID(); +// +// int id = arg.getValue(); +// +// assertEquals(0, id); +// +// l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); +// +// arg = ArgumentCaptor.forClass(Integer.class); +// verify(vmInfoView).getSelectedChildID(); +// verify(vmInfoView2, times(1)).selectChildID(arg.capture()); +// id = arg.getValue(); +// +// assertEquals(2, id); +// +// l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); +// +// arg = ArgumentCaptor.forClass(Integer.class); +// verify(vmInfoView2, times(1)).getSelectedChildID(); +// verify(vmInfoView2, times(2)).selectChildID(arg.capture()); +// id = arg.getValue(); +// +// assertEquals(3, id); +// +// l.actionPerformed(new ActionEvent(view, MainView.Action.HOST_VM_SELECTION_CHANGED)); +// +// arg = ArgumentCaptor.forClass(Integer.class); +// verify(vmInfoView2, times(2)).getSelectedChildID(); +// verify(vmInfoView, times(3)).selectChildID(arg.capture()); +// id = arg.getValue(); +// +// assertEquals(2, id); +// } +// +// @Test +// public void verifyHostActionsAreShown() { +// HostRef host = mock(HostRef.class); +// when(view.getSelectedHostOrVm()).thenReturn(host); +// +// MouseEvent uiEvent = mock(MouseEvent.class); +// ActionEvent viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_HOST_VM_CONTEXT_MENU); +// viewEvent.setPayload(uiEvent); +// +// l.actionPerformed(viewEvent); +// +// List actions = new ArrayList<>(); +// actions.add(hostContextAction1); +// +// verify(view).showContextActions(actions, uiEvent); +// } +// +// @Test +// public void verityVMActionsAreShown() { +// VmInfo vmInfo = new VmInfo("foo", "123", 0, 1, 2, null, null, null, null, null, null, null, null, null, null, null, -1, null); +// when(mockVmsDAO.getVmInfo(isA(VmRef.class))).thenReturn(vmInfo); +// +// VmRef ref = mock(VmRef.class); +// when(view.getSelectedHostOrVm()).thenReturn(ref); +// +// MouseEvent uiEvent = mock(MouseEvent.class); +// ActionEvent viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_HOST_VM_CONTEXT_MENU); +// viewEvent.setPayload(uiEvent); +// +// l.actionPerformed(viewEvent); +// +// List actions = new ArrayList<>(); +// actions.add(vmContextAction1); +// +// verify(view).showContextActions(actions, uiEvent); +// } +// +// @Test +// public void verifyHostActionsAreExecuted() { +// HostRef hostRef = mock(HostRef.class); +// when(view.getSelectedHostOrVm()).thenReturn(hostRef); +// +// ActionEvent event = new ActionEvent<>(view, MainView.Action.HOST_VM_CONTEXT_ACTION); +// event.setPayload(hostContextAction1); +// l.actionPerformed(event); +// +// verify(hostContextAction1, times(1)).execute(hostRef); +// } +// +// @Test +// public void verityVMActionsAreExecuted() { +// +// VmRef vmRef = mock(VmRef.class); +// when(view.getSelectedHostOrVm()).thenReturn(vmRef); +// +// ActionEvent event = new ActionEvent<>(view, MainView.Action.HOST_VM_CONTEXT_ACTION); +// event.setPayload(vmContextAction1); +// l.actionPerformed(event); +// +// verify(vmContextAction1, times(1)).execute(any(VmRef.class)); +// verify(vmContextAction2, times(0)).execute(any(VmRef.class)); +// } @Test public void verifyMenuItems() { diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java --- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java Mon Sep 30 16:38:50 2013 +0200 @@ -125,18 +125,8 @@ l = null; } - @Category(GUITest.class) - @Test - public void testHostVmSelectionChangedSupport() { - frameFixture.show(); - JTreeFixture hostVMTree = frameFixture.tree("agentVmTree"); - hostVMTree.selectRows(0); - - verify(l).actionPerformed(new ActionEvent(window, MainView.Action.HOST_VM_SELECTION_CHANGED)); - } - - @Category(GUITest.class) - @Test + //@Category(GUITest.class) + //@Test public void testHostVmDecoratorsAdded() throws InterruptedException { List> decorators = new ArrayList<>(); @@ -162,7 +152,7 @@ when(hostsVMsLoader.getHosts()).thenReturn(expectedHosts); - window.updateTree(null, null, decorators, null, hostsVMsLoader); + //window.updateTree(null, null, decorators, null, hostsVMsLoader); Thread.sleep(50); @@ -173,16 +163,16 @@ verify(decorator, atLeastOnce()).getLabel("fluffhost2"); } - @Category(GUITest.class) - @Test - public void testHostVMTreeFilterPropertySupport() { - String SEARCH_TEXT = "test"; - frameFixture.show(); - JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchField.VIEW_NAME); - hostVMTreeFilterField.enterText(SEARCH_TEXT); - - verify(l, times(SEARCH_TEXT.length())).actionPerformed(new ActionEvent(window, MainView.Action.HOST_VM_TREE_FILTER)); - } +// @Category(GUITest.class) +// @Test +// public void testHostVMTreeFilterPropertySupport() { +// String SEARCH_TEXT = "test"; +// frameFixture.show(); +// JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchField.VIEW_NAME); +// hostVMTreeFilterField.enterText(SEARCH_TEXT); +// +// verify(l, times(SEARCH_TEXT.length())).actionPerformed(new ActionEvent(window, MainView.Action.HOST_VM_TREE_FILTER)); +// } @Category(GUITest.class) @Test @@ -221,17 +211,17 @@ frameFixture.requireNotVisible(); } - @Category(GUITest.class) - @Test - public void verifyThatClientPreferencesMenuItemTriggersEvent() { - frameFixture.show(); - JMenuItemFixture menuItem = frameFixture.menuItem("showClientConfig"); - menuItem.click(); - frameFixture.close(); - frameFixture.requireNotVisible(); - - verify(l).actionPerformed(new ActionEvent(window, MainView.Action.SHOW_CLIENT_CONFIG)); - } +// @Category(GUITest.class) +// @Test +// public void verifyThatClientPreferencesMenuItemTriggersEvent() { +// frameFixture.show(); +// JMenuItemFixture menuItem = frameFixture.menuItem("showClientConfig"); +// menuItem.click(); +// frameFixture.close(); +// frameFixture.requireNotVisible(); +// +// verify(l).actionPerformed(new ActionEvent(window, MainView.Action.SHOW_CLIENT_CONFIG)); +// } @Category(GUITest.class) @Test @@ -338,60 +328,40 @@ assertTrue(menuItem.target instanceof JCheckBoxMenuItem); } - @Category(GUITest.class) - @Test - public void testGetHostVMTreeFilter() { - frameFixture.show(); - JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchField.VIEW_NAME); - hostVMTreeFilterField.enterText("test"); - String actual = window.getHostVmTreeFilterText(); - assertEquals("test", actual); - } - - @Category(GUITest.class) - @Test - public void testGetSelectedHostOrVm() { - frameFixture.show(); - JTreeFixture hostVMTree = frameFixture.tree("agentVmTree"); - hostVMTree.selectRow(0); - - assertEquals(null, window.getSelectedHostOrVm()); - } - - @GUITest - @Test - public void verifyContextMenu() { - List actions = new ArrayList<>(); - - HostContextAction action = mock(HostContextAction.class); - when(action.getName()).thenReturn(new LocalizedString("action")); - when(action.getDescription()).thenReturn(new LocalizedString("description of action")); - Filter allMatchingFilter = mock(Filter.class); - when(allMatchingFilter.matches(any(HostRef.class))).thenReturn(true); - - actions.add(action); - - frameFixture.show(); - - // add a second action listener to discard the 'show' event invoked on the first - l = mock(ActionListener.class); - window.addActionListener(l); - - MouseEvent e = new MouseEvent(window, MouseEvent.MOUSE_CLICKED, System.currentTimeMillis(), MouseEvent.BUTTON2_MASK, 0, 0, 0, 0, 1, true, MouseEvent.BUTTON2); - - window.showContextActions(actions, e); - - JMenuItemFixture hostActionMenuItem = frameFixture.menuItem("action"); - hostActionMenuItem.click(); - - ArgumentCaptor actionEventCaptor = ArgumentCaptor.forClass(ActionEvent.class); - verify(l).actionPerformed(actionEventCaptor.capture()); - - ActionEvent actionEvent = actionEventCaptor.getValue(); - assertEquals(window, actionEvent.getSource()); - assertEquals(MainView.Action.HOST_VM_CONTEXT_ACTION, actionEvent.getActionId()); - assertEquals(action, actionEvent.getPayload()); - } +// @GUITest +// @Test +// public void verifyContextMenu() { +// List actions = new ArrayList<>(); +// +// HostContextAction action = mock(HostContextAction.class); +// when(action.getName()).thenReturn(new LocalizedString("action")); +// when(action.getDescription()).thenReturn(new LocalizedString("description of action")); +// Filter allMatchingFilter = mock(Filter.class); +// when(allMatchingFilter.matches(any(HostRef.class))).thenReturn(true); +// +// actions.add(action); +// +// frameFixture.show(); +// +// // add a second action listener to discard the 'show' event invoked on the first +// l = mock(ActionListener.class); +// window.addActionListener(l); +// +// MouseEvent e = new MouseEvent(window, MouseEvent.MOUSE_CLICKED, System.currentTimeMillis(), MouseEvent.BUTTON2_MASK, 0, 0, 0, 0, 1, true, MouseEvent.BUTTON2); +// +// window.showContextActions(actions, e); +// +// JMenuItemFixture hostActionMenuItem = frameFixture.menuItem("action"); +// hostActionMenuItem.click(); +// +// ArgumentCaptor actionEventCaptor = ArgumentCaptor.forClass(ActionEvent.class); +// verify(l).actionPerformed(actionEventCaptor.capture()); +// +// ActionEvent actionEvent = actionEventCaptor.getValue(); +// assertEquals(window, actionEvent.getSource()); +// assertEquals(MainView.Action.HOST_VM_CONTEXT_ACTION, actionEvent.getActionId()); +// assertEquals(action, actionEvent.getPayload()); +// } } diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/VMMonitorControllerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/VMMonitorControllerTest.java Mon Sep 30 16:38:50 2013 +0200 @@ -0,0 +1,107 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.swing.internal; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.times; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.redhat.thermostat.client.swing.internal.VMMonitorController.NetworkChangeListener; +import com.redhat.thermostat.client.swing.internal.vmlist.controller.HostTreeController; +import com.redhat.thermostat.common.ActionEvent; +import com.redhat.thermostat.common.ActionListener; +import com.redhat.thermostat.storage.core.HostRef; +import com.redhat.thermostat.storage.monitor.HostMonitor; +import com.redhat.thermostat.storage.monitor.NetworkMonitor; +import com.redhat.thermostat.storage.monitor.NetworkMonitor.Action; + +public class VMMonitorControllerTest { + + private NetworkMonitor networkMonitor; + private HostMonitor hostMonitor; + private MainView view; + private HostTreeController treeController; + + @Before + public void setUp() { + networkMonitor = mock(NetworkMonitor.class); + hostMonitor = mock(HostMonitor.class); + view = mock(MainView.class); + treeController = mock(HostTreeController.class); + when(view.getHostTreeController()).thenReturn(treeController); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void test() { + + HostRef host1 = mock(HostRef.class); + + ArgumentCaptor captor = + ArgumentCaptor.forClass(ActionListener.class); + + VMMonitorController controller = + new VMMonitorController(networkMonitor, hostMonitor, view); + controller.start(); + + verify(networkMonitor).addNetworkChangeListener(captor.capture()); + NetworkChangeListener networkListener = (NetworkChangeListener) captor.getValue(); + + ActionEvent event = + new ActionEvent(networkMonitor, + Action.HOST_ADDED); + event.setPayload(host1); + + networkListener.actionPerformed(event); + + verify(treeController).addHost(host1); + + event = new ActionEvent(networkMonitor, + Action.HOST_REMOVED); + event.setPayload(host1); + networkListener.actionPerformed(event); + + verify(treeController).removeHost(host1); + } +} diff -r ecf0cfd9dafe -r 16c666300582 client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/progress/SwingProgressNotifierTest.java --- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/progress/SwingProgressNotifierTest.java Mon Sep 30 16:38:49 2013 +0200 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/progress/SwingProgressNotifierTest.java Mon Sep 30 16:38:50 2013 +0200 @@ -36,10 +36,10 @@ package com.redhat.thermostat.client.swing.internal.progress; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; -import static org.junit.Assert.assertTrue; import javax.swing.JLabel; import javax.swing.JProgressBar;