Mercurial > hg > release > thermostat-1.0
changeset 1285:4b729a28bcad
New component for selecting a time interval
Reviewed-by: neugens
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-October/008468.html
line wrap: on
line diff
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/BasicEventTimelineUI.java Fri Oct 18 16:57:09 2013 +0200 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/BasicEventTimelineUI.java Fri Oct 18 18:11:03 2013 -0400 @@ -55,14 +55,14 @@ import java.awt.event.HierarchyBoundsListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.util.concurrent.TimeUnit; import javax.swing.JButton; +import javax.swing.JComponent; import javax.swing.JPanel; import com.redhat.thermostat.client.swing.components.EventTimelineModel.Event; +import com.redhat.thermostat.client.swing.components.TimelineIntervalMouseHandler.TimeIntervalSelectorTarget; import com.redhat.thermostat.client.swing.components.timeline.Timeline; import com.redhat.thermostat.client.swing.internal.LocaleResources; import com.redhat.thermostat.common.model.LongRangeNormalizer; @@ -306,23 +306,15 @@ } } - private class OverviewPanel extends JPanel { + private class OverviewPanel extends JPanel implements TimeIntervalSelectorTarget { private int MOUSE_MARGIN = 10; private int left; private int right; - private boolean moving = false; - private boolean movingLeft = false; - private boolean movingRight = false; - - private int oldX = -1; - private int oldLeft = -1; - private int oldRight = -1; - public OverviewPanel() { - OverviewMotionListener chartMotionListener = new OverviewMotionListener(); + TimelineIntervalMouseHandler chartMotionListener = new TimelineIntervalMouseHandler(this); addMouseMotionListener(chartMotionListener); addMouseListener(chartMotionListener); } @@ -399,67 +391,29 @@ g.dispose(); } - class OverviewMotionListener extends MouseAdapter { - @Override - public void mouseMoved(MouseEvent e) { - if (Math.abs(e.getX() - left) < MOUSE_MARGIN) { - setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); - } else if (Math.abs(e.getX() - right) < MOUSE_MARGIN) { - setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); - } else if ((e.getX() > MOUSE_MARGIN + left) && (e.getX() < right - MOUSE_MARGIN)) { - setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); - } else { - setCursor(Cursor.getDefaultCursor()); - } - - } + @Override + public int getSelectionMargin() { + return MOUSE_MARGIN; + } - @Override - public void mouseDragged(MouseEvent e) { - if (moving || movingLeft || movingRight) { - - int newLeft = oldLeft; - int newRight = oldRight; - if (movingLeft) { - newLeft = e.getX(); - } else if (movingRight) { - newRight = e.getX(); - } else if (moving) { - long delta = e.getX() - oldX; - newLeft += delta; - newRight += delta; - } + @Override + public int getLeftSelectionPosition() { + return left; + } - Range<Long> range = new Range<Long>(positionToTimeStamp(newLeft), positionToTimeStamp(newRight)); - - eventTimeline.getModel().setDetailRange(range); - - refresh(); - } - } - - @Override - public void mouseReleased(MouseEvent e) { - moving = movingLeft = movingRight = false; - oldLeft = oldRight = oldX = -1; - } + @Override + public int getRightSelectionPosition() { + return right; + } - @Override - public void mousePressed(MouseEvent e) { - if (Math.abs(e.getX() - left) < MOUSE_MARGIN) { - movingLeft = true; - } else if (Math.abs(e.getX() - right) < MOUSE_MARGIN) { - movingRight = true; - } else if ((e.getX() > left + MOUSE_MARGIN) && (e.getX() < right - MOUSE_MARGIN)) { - moving = true; - } - Range<Long> range = eventTimeline.getModel().getDetailRange(); - oldLeft = timeStampToPosition(range.getMin()); - oldRight = timeStampToPosition(range.getMax()); - oldX = e.getX(); - } - - // TODO implement wheel scrolling + @Override + public void updateSelectionPosition(int newLeft, int newRight) { + left = newLeft; + right = newRight; + Range<Long> range = new Range<Long>(positionToTimeStamp(left), positionToTimeStamp(right)); + eventTimeline.getModel().setDetailRange(range); + refresh(); } } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/TimelineIntervalMouseHandler.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,118 @@ +/* + * 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 <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.client.swing.components; + +import java.awt.Cursor; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +class TimelineIntervalMouseHandler extends MouseAdapter { + + static interface TimeIntervalSelectorTarget { + void setCursor(Cursor cursor); + int getSelectionMargin(); + int getLeftSelectionPosition(); + int getRightSelectionPosition(); + void updateSelectionPosition(int left, int right); + } + + private final TimeIntervalSelectorTarget target; + + private boolean moving = false; + private boolean movingLeft = false; + private boolean movingRight = false; + + private int oldX = -1; + private int oldLeft = -1; + private int oldRight = -1; + + public TimelineIntervalMouseHandler(TimeIntervalSelectorTarget target) { + this.target = target; + } + + @Override + public void mouseMoved(MouseEvent e) { + if (Math.abs(e.getX() - target.getLeftSelectionPosition()) < target.getSelectionMargin()) { + target.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); + } else if (Math.abs(e.getX() - target.getRightSelectionPosition()) < target.getSelectionMargin()) { + target.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); + } else if ((e.getX() > target.getSelectionMargin() + target.getLeftSelectionPosition()) && (e.getX() < target.getRightSelectionPosition() - target.getSelectionMargin())) { + target.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + } else { + target.setCursor(Cursor.getDefaultCursor()); + } + + } + + @Override + public void mouseDragged(MouseEvent e) { + if (moving || movingLeft || movingRight) { + + int newLeft = oldLeft; + int newRight = oldRight; + if (movingLeft) { + newLeft = e.getX(); + } else if (movingRight) { + newRight = e.getX(); + } else if (moving) { + long delta = e.getX() - oldX; + newLeft += delta; + newRight += delta; + } + + target.updateSelectionPosition(newLeft, newRight); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + moving = movingLeft = movingRight = false; + oldLeft = oldRight = oldX = -1; + } + + @Override + public void mousePressed(MouseEvent e) { + if (Math.abs(e.getX() - target.getLeftSelectionPosition()) < target.getSelectionMargin()) { + movingLeft = true; + } else if (Math.abs(e.getX() - target.getRightSelectionPosition()) < target.getSelectionMargin()) { + movingRight = true; + } else if ((e.getX() > target.getLeftSelectionPosition() + target.getSelectionMargin()) && (e.getX() < target.getRightSelectionPosition() - target.getSelectionMargin())) { + moving = true; + } + oldLeft = target.getLeftSelectionPosition(); + oldRight = target.getRightSelectionPosition(); + oldX = e.getX(); + } + + // TODO implement wheel scrolling +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/TimelineIntervalSelector.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,79 @@ +/* + * 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 <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.client.swing.components; + +import javax.swing.JComponent; +import javax.swing.UIManager; + +/** + * A component that allows specifying a time range to select + */ +public class TimelineIntervalSelector extends JComponent { + + private static final String uiClassID = "TimelineIntervalSelectorUI"; + + private TimelineIntervalSelectorModel model; + + public TimelineIntervalSelector() { + model = new TimelineIntervalSelectorModel(); + + updateUI(); + } + + public TimelineIntervalSelectorModel getModel() { + return model; + } + + public void setUI(TimelineIntervalSelectorUI ui) { + super.setUI(ui); + } + + @Override + public void updateUI() { + if (UIManager.get(getUIClassID()) != null) { + setUI((TimelineIntervalSelectorUI) UIManager.getUI(this)); + } else { + setUI(new TimelineIntervalSelectorUIBasic()); + } + } + + public TimelineIntervalSelectorUI getUI() { + return (TimelineIntervalSelectorUI) ui; + } + + @Override + public String getUIClassID() { + return uiClassID; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/TimelineIntervalSelectorModel.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,141 @@ +/* + * 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 <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.client.swing.components; + +import java.util.EventListener; + +import javax.swing.event.EventListenerList; + +public class TimelineIntervalSelectorModel { + + public static interface ChangeListener extends EventListener { + public void changed(); + } + + private final EventListenerList listeners = new EventListenerList(); + + private long totalMinimum = 0; + private long totalMaximum = 100; + + private long selectedMinimum = 0; + private long selectedMaximum = 10; + + public long getTotalMinimum() { + return totalMinimum; + } + + public void setTotalMinimum(long totalMinimum) { + if (this.totalMinimum != totalMinimum) { + this.totalMinimum = totalMinimum; + + if (this.totalMaximum < this.totalMinimum) { + this.totalMaximum = this.totalMinimum; + } + + if (this.selectedMaximum < this.totalMinimum){ + this.selectedMaximum = this.totalMinimum; + } + + if (this.selectedMinimum < this.totalMinimum) { + this.selectedMinimum = this.totalMinimum; + } + + fireModelChanged(); + } + } + + public long getTotalMaximum() { + return totalMaximum; + } + + public void setTotalMaximum(long totalMaximum) { + if (this.totalMaximum != totalMaximum) { + this.totalMaximum = totalMaximum; + + if (this.totalMinimum > this.totalMaximum) { + this.totalMinimum = this.totalMaximum; + } + + if (this.selectedMaximum > this.totalMaximum) { + this.selectedMaximum = this.totalMaximum; + } + + if (this.selectedMinimum > this.totalMaximum) { + this.selectedMinimum = this.totalMaximum; + } + + fireModelChanged(); + } + } + + public long getSelectedMinimum() { + return selectedMinimum; + } + + public void setSelectedMinimum(long selectedMinimum) { + if(this.selectedMinimum != selectedMinimum) { + this.selectedMinimum = selectedMinimum; + fireModelChanged(); + } + } + + public long getSelectedMaximum() { + return selectedMaximum; + } + + public void setSelectedMaximum(long selectedMaximum) { + if (this.selectedMaximum != selectedMaximum) { + this.selectedMaximum = selectedMaximum; + fireModelChanged(); + } + } + + public void addChangeListener(ChangeListener l) { + listeners.add(ChangeListener.class, l); + } + + public void removeChangeListener(ChangeListener l) { + listeners.remove(ChangeListener.class, l); + } + + private void fireModelChanged() { + Object[] listeners = this.listeners.getListenerList(); + + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == ChangeListener.class) { + ((ChangeListener) listeners[i + 1]).changed(); + } + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/TimelineIntervalSelectorUI.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,39 @@ +/* + * 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 <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.client.swing.components; + +import javax.swing.plaf.ComponentUI; + +public class TimelineIntervalSelectorUI extends ComponentUI { + // a marker class +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/TimelineIntervalSelectorUIBasic.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,213 @@ +/* + * 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 <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.client.swing.components; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; + +import com.redhat.thermostat.client.swing.components.TimelineIntervalMouseHandler.TimeIntervalSelectorTarget; +import com.redhat.thermostat.client.swing.components.TimelineIntervalSelectorModel.ChangeListener; +import com.redhat.thermostat.client.swing.components.timeline.Timeline; +import com.redhat.thermostat.common.model.Range; + +public class TimelineIntervalSelectorUIBasic extends TimelineIntervalSelectorUI implements TimeIntervalSelectorTarget { + + private static final int PREF_HEIGHT = 20; /* pixels */ + + private TimelineIntervalSelector component; + + private TimelineIntervalMouseHandler mouseListener = new TimelineIntervalMouseHandler(this); + private Timeline timeline = new Timeline(new Range<Long>(0l, 100l)); + private JPanel customPaintingPanel = new CustomPaintPanel(); + + private Component topGlue; + private Component bottomGlue; + + private ChangeListener timelineSelectionPainter = new ChangeListener() { + @Override + public void changed() { + component.repaint(); + } + }; + private ChangeListener timelineRangeUpdater = new ChangeListener() { + @Override + public void changed() { + TimelineIntervalSelectorModel model = component.getModel(); + timeline.setRange(new Range<>(model.getTotalMinimum(), model.getTotalMaximum())); + } + }; + + @Override + public void installUI(JComponent c) { + super.installUI(c); + + component = (TimelineIntervalSelector) c; + + installDefaults(); + installComponents(); + installListeners(); + + } + + protected void installDefaults() { + component.setLayout(new BoxLayout(component, BoxLayout.PAGE_AXIS)); + component.setBorder(new EmptyBorder(5,5,5,5)); + } + + protected void installComponents() { + topGlue = Box.createVerticalGlue(); + bottomGlue = Box.createVerticalGlue(); + + component.add(topGlue); + component.add(timeline); + component.add(customPaintingPanel); + component.add(bottomGlue); + } + + protected void installListeners() { + component.getModel().addChangeListener(timelineSelectionPainter); + component.getModel().addChangeListener(timelineRangeUpdater); + + component.addMouseListener(mouseListener); + component.addMouseMotionListener(mouseListener); + component.addMouseWheelListener(mouseListener); + } + + @Override + public void uninstallUI(JComponent c) { + uninstallListeners(); + uninstallComponents(); + uninstallDefaults(); + + component = null; + + super.uninstallUI(c); + } + + protected void uninstallComponents() { + component.remove(bottomGlue); + component.remove(customPaintingPanel); + component.remove(timeline); + component.remove(topGlue); + } + + protected void uninstallListeners() { + component.removeMouseWheelListener(mouseListener); + component.removeMouseMotionListener(mouseListener); + component.removeMouseListener(mouseListener); + + component.getModel().removeChangeListener(timelineRangeUpdater); + component.getModel().removeChangeListener(timelineSelectionPainter); + } + + protected void uninstallDefaults() { + component.setLayout(null); + } + + @Override + public int getLeftSelectionPosition() { + return domainToX(component.getModel().getSelectedMinimum()); + } + + @Override + public int getRightSelectionPosition() { + return domainToX(component.getModel().getSelectedMaximum()); + } + + @Override + public int getSelectionMargin() { + return 20; + } + + @Override + public void setCursor(Cursor cursor) { + component.setCursor(cursor); + } + + @Override + public void updateSelectionPosition(int left, int right) { + long min = xToDomain(left); + long max = xToDomain(right); + component.getModel().setSelectedMaximum(max); + component.getModel().setSelectedMinimum(min); + + component.repaint(); + } + + private int domainToX(long domainValue) { + long domainMin = component.getModel().getTotalMinimum(); + long domainMax = component.getModel().getTotalMaximum(); + int width = component.getWidth(); + return (int) (1.0 * (domainValue - domainMin) / (domainMax - domainMin) * width); + } + + private long xToDomain(int x) { + long domainMin = component.getModel().getTotalMinimum(); + long domainMax = component.getModel().getTotalMaximum(); + int width = component.getWidth(); + return (long) ((1.0 * x / (width) * (domainMax - domainMin)) + domainMin); + } + + private class CustomPaintPanel extends JPanel { + + @Override + public Dimension getPreferredSize() { + return new Dimension(super.getPreferredSize().height, PREF_HEIGHT); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + + Graphics2D g2 = (Graphics2D) g.create(); + + int startX = domainToX(component.getModel().getSelectedMinimum()); + int endX = domainToX(component.getModel().getSelectedMaximum()); + + g2.fillRect(startX, 0, (endX - startX), getHeight()); + + g2.dispose(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/TimelineIntervalSelectorModelTest.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,74 @@ +/* + * 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 <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.client.swing.components; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class TimelineIntervalSelectorModelTest { + + @Test + public void testChangingTotalMinimumAdjustsOtherValues() { + TimelineIntervalSelectorModel model = new TimelineIntervalSelectorModel(); + model.setTotalMinimum(0); + model.setTotalMaximum(100); + model.setSelectedMinimum(20); + model.setSelectedMaximum(80); + + model.setTotalMinimum(1000); + + assertEquals(1000, model.getTotalMinimum()); + assertTrue(model.getTotalMaximum() >= 1000); + assertTrue(model.getSelectedMinimum() >= 1000); + assertTrue(model.getSelectedMaximum() >= 1000); + } + + @Test + public void testChangingTotalMaximumAdjustsOtherValues() { + TimelineIntervalSelectorModel model = new TimelineIntervalSelectorModel(); + model.setTotalMinimum(0); + model.setTotalMaximum(100); + model.setSelectedMinimum(20); + model.setSelectedMaximum(80); + + model.setTotalMaximum(-100); + + assertEquals(-100, model.getTotalMaximum()); + assertTrue(model.getTotalMinimum() <= -100); + assertTrue(model.getSelectedMinimum() <= -100); + assertTrue(model.getSelectedMaximum() <= -100); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/TimelineIntervalSelectorTest.java Fri Oct 18 18:11:03 2013 -0400 @@ -0,0 +1,84 @@ +/* + * 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 <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.client.swing.components; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.util.concurrent.TimeUnit; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +import com.redhat.thermostat.client.swing.components.TimelineIntervalSelectorModel.ChangeListener; + +public class TimelineIntervalSelectorTest { + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JFrame mainWindow = new JFrame(); + + final TimelineIntervalSelector intervalSelector = new TimelineIntervalSelector(); + + long now = System.currentTimeMillis(); + + intervalSelector.getModel().addChangeListener(new ChangeListener() { + @Override + public void changed() { + // System.out.println(intervalSelector.getModel().getTotalMinimum()); + // System.out.println(intervalSelector.getModel().getTotalMaximum()); + // + // System.out.println(intervalSelector.getModel().getSelectedMinimum()); + // System.out.println(intervalSelector.getModel().getSelectedMaximum()); + + } + }); + + intervalSelector.getModel().setTotalMinimum(now); + intervalSelector.getModel().setTotalMaximum(now + TimeUnit.HOURS.toMillis(1)); + + intervalSelector.getModel().setSelectedMinimum(now); + intervalSelector.getModel().setSelectedMaximum(now + TimeUnit.MINUTES.toMillis(10)); + + mainWindow.add(intervalSelector, BorderLayout.CENTER); + mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + mainWindow.setVisible(true); + + } + }); + } +}