Mercurial > hg > release > thermostat-0.4
changeset 585:23f5dedff60d
Merge
author | Roman Kennke <rkennke@redhat.com> |
---|---|
date | Tue, 04 Sep 2012 21:19:29 +0200 |
parents | d480b69be1d7 (current diff) ed3f6e0a3867 (diff) |
children | 5786978e31e0 |
files | |
diffstat | 10 files changed, 468 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java Tue Sep 04 20:58:27 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java Tue Sep 04 21:19:29 2012 +0200 @@ -84,6 +84,8 @@ void setSubView(BasicView view); + void setStatusBarPrimaryStatus(String primaryStatus); + /** * Adds a menu item to the window. Assumes the menu path is valid (has a * non-zero length) and doesn't collide with existing menus.
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java Tue Sep 04 20:58:27 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java Tue Sep 04 21:19:29 2012 +0200 @@ -398,11 +398,14 @@ HostRef hostRef = (HostRef) ref; HostInformationController hostController = facadeFactory.getHostController(hostRef); view.setSubView(hostController.getView()); + view.setStatusBarPrimaryStatus("host: " + hostRef.getHostName() + ", id: " + hostRef.getAgentId()); } else if (ref instanceof VmRef) { VmRef vmRef = (VmRef) ref; VmInformationController vmInformation = vmInfoControllerProvider.getVmInfoController(vmRef); view.setSubView(vmInformation.getView()); + view.setStatusBarPrimaryStatus("vm: " + vmRef.getName() + ", pid: " + vmRef.getStringID() + + ", host: " + vmRef.getAgent().getHostName()); } else { throw new IllegalArgumentException("unknown type of ref"); }
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java Tue Sep 04 20:58:27 2012 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java Tue Sep 04 21:19:29 2012 +0200 @@ -110,6 +110,7 @@ import com.redhat.thermostat.common.dao.VmRef; import com.redhat.thermostat.common.utils.StringUtils; import com.redhat.thermostat.swing.EdtHelper; +import com.redhat.thermostat.swing.StatusBar; public class MainWindow extends JFrame implements MainView { @@ -318,6 +319,7 @@ private ActionNotifier<Action> actionNotifier = new ActionNotifier<>(this); private JPopupMenu vmContextMenu; + private StatusBar statusBar; private final DefaultMutableTreeNode publishedRoot = new DefaultMutableTreeNode(localize(LocaleResources.MAIN_WINDOW_TREE_ROOT_NAME)); @@ -368,6 +370,9 @@ //agentVmTree.setLargeModel(true); agentVmTree.setRowHeight(25); + statusBar = new StatusBar(); + getContentPane().add(statusBar, BorderLayout.SOUTH); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener(shutdownAction); @@ -466,7 +471,7 @@ registerContextActionListener(agentVmTree); JScrollPane treeScrollPane = new JScrollPane(agentVmTree); - + navigationPanel.add(treeScrollPane); JPanel detailsPanel = createDetailsPanel(); @@ -477,7 +482,7 @@ splitPane.add(navigationPanel); splitPane.add(detailsPanel); - add(splitPane); + getContentPane().add(splitPane); } private void registerContextActionListener(JTree agentVmTree2) { @@ -714,6 +719,16 @@ } @Override + public void setStatusBarPrimaryStatus(final String primaryStatus) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + statusBar.setPrimaryStatus(primaryStatus); + } + }); + } + + @Override public void setSubView(final BasicView view) { if (view instanceof SwingComponent) { final SwingComponent swingComp = (SwingComponent)view;
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java Tue Sep 04 20:58:27 2012 +0200 +++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java Tue Sep 04 21:19:29 2012 +0200 @@ -398,6 +398,12 @@ public void verifyOpenSameHostVMTab() { VmRef vmRef = mock(VmRef.class); + when(vmRef.getName()).thenReturn("testvm"); + when(vmRef.getIdString()).thenReturn("testvmid"); + HostRef ref = mock(HostRef.class); + when(ref.getAgentId()).thenReturn("agentId"); + when(vmRef.getAgent()).thenReturn(ref); + when(view.getSelectedHostOrVm()).thenReturn(vmRef); VmInformationController vmInformationController = mock(VmInformationController.class); @@ -427,11 +433,21 @@ @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.getIdString()).thenReturn("testvmid"); + HostRef ref = mock(HostRef.class); + when(ref.getAgentId()).thenReturn("agentId"); + when(vmRef1.getAgent()).thenReturn(ref); + + when(vmRef2.getName()).thenReturn("testvm"); + when(vmRef2.getIdString()).thenReturn("testvmid"); + when(vmRef2.getAgent()).thenReturn(ref); + VmInformationController vmInformationController1 = mock(VmInformationController.class); VmInformationController vmInformationController2 = mock(VmInformationController.class);
--- a/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/internal/VMKilledListener.java Tue Sep 04 20:58:27 2012 +0200 +++ b/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/internal/VMKilledListener.java Tue Sep 04 21:19:29 2012 +0200 @@ -45,29 +45,32 @@ public class VMKilledListener implements RequestResponseListener { - private static final Logger logger = Logger.getLogger(VMKilledListener.class.getName()); + private static final Logger logger = Logger + .getLogger(VMKilledListener.class.getName()); @Override public void fireComplete(Request request, Response response) { switch (response.getType()) { - case NOOP: // fall-through - case EXCEPTION: // fall-through - case NOK: { - logger.log(Level.SEVERE, "Unknown response from kill VM request."); + case EXCEPTION: + logger.log(Level.SEVERE, + "Exception response from kill VM request. Command channel failure?"); break; - } case ERROR: - logger.log(Level.SEVERE, "Kill request error for VM ID " + request.getParameter("vm-id")); + logger.log(Level.SEVERE, + "Kill request error for VM ID " + + request.getParameter("vm-id")); break; - case PONG: // fall-through, also OK :) + case PONG: // fall-through, also OK :) case OK: // TODO: Report this to user somehow (notification?) - logger.log(Level.INFO, "VM with id " + request.getParameter("vm-id") + " killed on host " + request.getTarget().toString()); + logger.log(Level.INFO, + "VM with id " + request.getParameter("vm-id") + + " killed on host " + + request.getTarget().toString()); break; default: logger.log(Level.WARNING, "Unknown result from KILL VM command."); break; } } - }
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/GraphicsUtils.java Tue Sep 04 20:58:27 2012 +0200 +++ b/client/swing-components/src/main/java/com/redhat/thermostat/swing/GraphicsUtils.java Tue Sep 04 21:19:29 2012 +0200 @@ -75,6 +75,11 @@ SwingUtilities2.drawString(component, graphics, string, x, y); } + public void drawString(JComponent component, Graphics2D graphics, String string, Color foreground, int x, int y) { + graphics.setColor(foreground); + SwingUtilities2.drawString(component, graphics, string, x, y); + } + public FontMetrics getFontMetrics(JComponent component, Font font) { return SwingUtilities2.getFontMetrics(component, font); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing-components/src/main/java/com/redhat/thermostat/swing/StatusBar.java Tue Sep 04 21:19:29 2012 +0200 @@ -0,0 +1,140 @@ +/* + * Copyright 2012 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 + * <http://www.gnu.org/licenses/>. + * + * 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.swing; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.beans.Transient; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +@SuppressWarnings("serial") +public class StatusBar extends JPanel { + + // some of this code is inspired by the book + // Swing Hacks: Tips & Tools for Building Killer GUIs + // By Joshua Marinacci, Chris Adamson + // ISBN: 0-596-00907-0 + // website: http://www.oreilly.com/catalog/swinghks/ + + public static final String PRIMARY_STATUS_PROPERTY = "primaryStatus"; + + private Dimension preferredSize; + + private String primaryStatus = ""; + private JLabel primaryStatusLabel; + private JLabel iconLabel; + + public StatusBar() { + super(); + setLayout(new BorderLayout(0, 0)); + + primaryStatusLabel = new JLabel(primaryStatus); + primaryStatusLabel.setName("primaryStatusLabel"); + primaryStatusLabel.setFont(getFont().deriveFont(10.0f)); + primaryStatusLabel.setHorizontalAlignment(JLabel.LEADING); + primaryStatusLabel.setVerticalAlignment(JLabel.CENTER); + + add(primaryStatusLabel, BorderLayout.WEST); + + iconLabel = new JLabel(""); + ImageIcon grip = new ImageIcon(getClass().getResource("/icons/resize-grip.png")); + iconLabel.setIcon(grip); + + iconLabel.setMinimumSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight())); + iconLabel.setPreferredSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight())); + iconLabel.setVerticalAlignment(JLabel.BOTTOM); + + add(iconLabel, BorderLayout.EAST); + preferredSize = new Dimension(700, grip.getIconHeight() + 5); + } + + @Override + @Transient + public Dimension getMinimumSize() { + if (isMinimumSizeSet()) { + return super.getMinimumSize(); + } + return preferredSize; + } + + @Override + @Transient + public Dimension getPreferredSize() { + if (isPreferredSizeSet()) { + return super.getPreferredSize(); + } + return preferredSize; + } + + public void setPrimaryStatus(String primaryStatus) { + if (primaryStatus == null) throw new NullPointerException(); + + String oldPrimaryStatus = this.primaryStatus; + this.primaryStatus = primaryStatus; + primaryStatusLabel.setText(" " + primaryStatus); + + firePropertyChange(PRIMARY_STATUS_PROPERTY, oldPrimaryStatus, this.primaryStatus); + repaint(); + } + + public String getPrimaryStatus() { + return primaryStatus; + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setLayout(new BorderLayout()); + + StatusBar statusBar = new StatusBar(); + frame.getContentPane().add(statusBar, BorderLayout.SOUTH); + + frame.setSize(500, 500); + frame.setVisible(true); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing-components/src/main/resources/icons/resize-grip.svg Tue Sep 04 21:19:29 2012 +0200 @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="13" + height="13" + id="svg17653" + version="1.1" + inkscape:version="0.48.2 r9819" + sodipodi:docname="resize-grip.svg"> + <defs + id="defs17655" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="21.311078" + inkscape:cx="-8.2186936" + inkscape:cy="8.0008486" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1022" + inkscape:window-x="0" + inkscape:window-y="26" + inkscape:window-maximized="1" /> + <metadata + id="metadata17658"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer" + transform="translate(0,-3)"> + <path + transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-392.19484)" + d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z" + sodipodi:ry="1.9003495" + sodipodi:rx="1.9003495" + sodipodi:cy="617.14966" + sodipodi:cx="868.63647" + id="path5513" + style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new" + sodipodi:type="arc" /> + <path + sodipodi:type="arc" + style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new" + id="path5515" + sodipodi:cx="868.63647" + sodipodi:cy="617.14966" + sodipodi:rx="1.9003495" + sodipodi:ry="1.9003495" + d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z" + transform="matrix(0.65777374,0,0,0.65777374,-563.84354,-392.19484)" /> + <path + sodipodi:type="arc" + style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new" + id="path5517" + sodipodi:cx="868.63647" + sodipodi:cy="617.14966" + sodipodi:rx="1.9003495" + sodipodi:ry="1.9003495" + d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z" + transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-395.46756)" /> + <path + transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-398.74029)" + d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z" + sodipodi:ry="1.9003495" + sodipodi:rx="1.9003495" + sodipodi:cy="617.14966" + sodipodi:cx="868.63647" + id="path5519" + style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new" + sodipodi:type="arc" /> + <path + transform="matrix(0.65777374,0,0,0.65777374,-567.11626,-392.19484)" + d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z" + sodipodi:ry="1.9003495" + sodipodi:rx="1.9003495" + sodipodi:cy="617.14966" + sodipodi:cx="868.63647" + id="path5521" + style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new" + sodipodi:type="arc" /> + <path + transform="matrix(0.65777374,0,0,0.65777374,-563.84354,-395.46756)" + d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z" + sodipodi:ry="1.9003495" + sodipodi:rx="1.9003495" + sodipodi:cy="617.14966" + sodipodi:cx="868.63647" + id="path5523" + style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new" + sodipodi:type="arc" /> + </g> +</svg>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing-components/src/test/java/com/redhat/thermostat/swing/StatusBarTest.java Tue Sep 04 21:19:29 2012 +0200 @@ -0,0 +1,154 @@ +/* + * Copyright 2012 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 + * <http://www.gnu.org/licenses/>. + * + * 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.swing; + +import static org.junit.Assert.*; + +import java.awt.BorderLayout; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.concurrent.Semaphore; + +import javax.swing.JFrame; + +import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; + +import org.fest.swing.annotation.GUITest; +import org.fest.swing.annotation.RunsInEDT; +import org.fest.swing.edt.FailOnThreadViolationRepaintManager; +import org.fest.swing.edt.GuiActionRunner; +import org.fest.swing.edt.GuiTask; +import org.fest.swing.fixture.FrameFixture; +import org.fest.swing.fixture.JLabelFixture; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(CacioFESTRunner.class) +public class StatusBarTest { + + private JFrame frame; + private FrameFixture frameFixture; + + private StatusBar statusBar; + + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } + + @Before + public void setUp() { + GuiActionRunner.execute(new GuiTask() { + @Override + protected void executeInEDT() throws Throwable { + frame = new JFrame(); + frame.getContentPane().setLayout(new BorderLayout()); + + statusBar = new StatusBar(); + frame.getContentPane().add(statusBar, BorderLayout.SOUTH); + + frame.setSize(500, 500); + } + }); + frameFixture = new FrameFixture(frame); + } + + @After + public void tearDown() { + frameFixture.cleanUp(); + frameFixture = null; + } + + @Test + @GUITest + @RunsInEDT + public void testSetPrimaryStatusLabel() throws InterruptedException { + frameFixture.show(); + + JLabelFixture labelfixture = frameFixture.label("primaryStatusLabel"); + labelfixture.requireText(""); + + final Semaphore sem = new Semaphore(0); + GuiActionRunner.execute(new GuiTask() { + @Override + protected void executeInEDT() throws Throwable { + statusBar.setPrimaryStatus("test"); + sem.release(); + } + }); + sem.acquire(); + + // the label has an extra space at the beginning + labelfixture.requireText(" test"); + } + + @Test + @GUITest + @RunsInEDT + public void testSetPrimaryStatusLabelWithProperty() throws InterruptedException { + frameFixture.show(); + + final String[] primaryStatus = new String[2]; + + final Semaphore sem = new Semaphore(2); + statusBar.addPropertyChangeListener(StatusBar.PRIMARY_STATUS_PROPERTY, + new PropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent evt) { + primaryStatus[0] = (String) evt.getOldValue(); + primaryStatus[1] = (String) evt.getNewValue(); + sem.release(); + } + }); + + GuiActionRunner.execute(new GuiTask() { + @Override + protected void executeInEDT() throws Throwable { + statusBar.setPrimaryStatus("test"); + sem.release(); + } + }); + sem.acquire(2); + + assertEquals("", primaryStatus[0]); + assertEquals("test", primaryStatus[1]); + } +}