# HG changeset patch # User Tom Rodriguez # Date 1407881557 25200 # Node ID 22e0c20a34983ea25e0dba1add5c71ca582378ef # Parent 7977cb9fa21f50ca2e5900c9076c26c41259f18f improve rendering of RangeSlider diff -r 7977cb9fa21f -r 22e0c20a3498 src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java --- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java Tue Aug 12 17:45:03 2014 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java Tue Aug 12 15:12:37 2014 -0700 @@ -26,24 +26,26 @@ import com.sun.hotspot.igv.data.ChangedListener; import java.awt.*; +import java.awt.geom.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.List; -import javax.swing.JComponent; +import javax.swing.*; /** * * @author Thomas Wuerthinger */ -public class RangeSlider extends JComponent implements ChangedListener, MouseListener, MouseMotionListener { +public class RangeSlider extends JComponent implements ChangedListener, MouseListener, MouseMotionListener, Scrollable { public static final int HEIGHT = 40; - public static final int BAR_HEIGHT = 22; - public static final int BAR_SELECTION_ENDING_HEIGHT = 16; - public static final int BAR_SELECTION_HEIGHT = 10; - public static final int BAR_THICKNESS = 2; - public static final int BAR_CIRCLE_SIZE = 9; + public static final float BAR_HEIGHT = 22; + public static final float BAR_SELECTION_ENDING_HEIGHT = 16; + public static final float BAR_SELECTION_HEIGHT = 10; + public static final float BAR_THICKNESS = 2; + public static final float BAR_CIRCLE_SIZE = 9; + public static final float BAR_CIRCLE_CONNECTOR_SIZE = 6; public static final int MOUSE_ENDING_OFFSET = 3; public static final Color BACKGROUND_COLOR = Color.white; public static final Color BAR_COLOR = Color.black; @@ -90,15 +92,61 @@ return model; } + /** + * Returns the preferred size of the viewport for a view component. + * For example, the preferred size of a JList component + * is the size required to accommodate all of the cells in its list. + * However, the value of preferredScrollableViewportSize + * is the size required for JList.getVisibleRowCount rows. + * A component without any properties that would affect the viewport + * size should just return getPreferredSize here. + * + * @return the preferredSize of a JViewport whose view + * is this Scrollable + * @see JViewport#getPreferredSize + */ + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.VERTICAL) { + return 1; + } + + return (int)(BAR_CIRCLE_SIZE + BAR_CIRCLE_CONNECTOR_SIZE); + } + + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + return orientation == SwingConstants.VERTICAL ? visibleRect.height / 2 : visibleRect.width / 2; + } + + public boolean getScrollableTracksViewportWidth() { + return false; + } + + public boolean getScrollableTracksViewportHeight() { + return true; + } + @Override public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.height = HEIGHT; + d.width = Math.max(d.width, (int)(2 * BAR_CIRCLE_CONNECTOR_SIZE + getPaintingModel().getPositions().size() * (BAR_CIRCLE_SIZE + BAR_CIRCLE_CONNECTOR_SIZE))); return d; } @Override public void changed(RangeSliderModel source) { + revalidate(); + + float barStartY = getBarStartY(); + int circleCenterY = (int)(barStartY + BAR_HEIGHT / 2); + int startX = (int)getStartXPosition(model.getFirstPosition()); + int endX = (int)getEndXPosition(model.getSecondPosition()); + Rectangle r = new Rectangle(startX, circleCenterY, endX - startX, 1); + scrollRectToVisible(r); update(); } @@ -106,22 +154,22 @@ this.repaint(); } - private int getXPosition(int index) { + private float getXPosition(int index) { assert index >= 0 && index < getPaintingModel().getPositions().size(); return getXOffset() * (index + 1); } - private int getXOffset() { + private float getXOffset() { int size = getPaintingModel().getPositions().size(); - int width = getWidth(); + float width = (float)getWidth(); return (width / (size + 1)); } - private int getEndXPosition(int index) { + private float getEndXPosition(int index) { return getXPosition(index) + getXOffset() / 2; } - private int getStartXPosition(int index) { + private float getStartXPosition(int index) { return getXPosition(index) - getXOffset() / 2; } @@ -135,7 +183,7 @@ int height = getHeight(); g2.setColor(BACKGROUND_COLOR); - g2.fillRect(0, 0, width, height); + g2.fill(new Rectangle2D.Float(0, 0, width, height)); // Nothing to paint? if (getPaintingModel() == null || getPaintingModel().getPositions().size() == 0) { @@ -150,30 +198,30 @@ } - private int getBarStartY() { - return getHeight() - BAR_HEIGHT; + private float getBarStartY() { + return getHeight() / 2 - BAR_HEIGHT / 2; } private void paintBar(Graphics2D g) { List list = getPaintingModel().getPositions(); - int barStartY = getBarStartY(); + float barStartY = getBarStartY(); g.setColor(BAR_COLOR); - g.fillRect(getXPosition(0), barStartY + BAR_HEIGHT / 2 - BAR_THICKNESS / 2, getXPosition(list.size() - 1) - getXPosition(0), BAR_THICKNESS); + g.fill(new Rectangle2D.Float(getXPosition(0), barStartY + BAR_HEIGHT / 2 - BAR_THICKNESS / 2, getXPosition(list.size() - 1) - getXPosition(0), BAR_THICKNESS)); - int circleCenterY = barStartY + BAR_HEIGHT / 2; + float circleCenterY = barStartY + BAR_HEIGHT / 2; for (int i = 0; i < list.size(); i++) { - int curX = getXPosition(i); + float curX = getXPosition(i); g.setColor(getPaintingModel().getColors().get(i)); - g.fillOval(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE); + g.fill(new Ellipse2D.Float(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE)); g.setColor(Color.black); - g.drawOval(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE); + g.draw(new Ellipse2D.Float(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE)); String curS = list.get(i); if (curS != null && curS.length() > 0) { - int startX = getStartXPosition(i); - int endX = getEndXPosition(i); + float startX = getStartXPosition(i); + float endX = getEndXPosition(i); FontMetrics metrics = g.getFontMetrics(); Rectangle bounds = metrics.getStringBounds(curS, g).getBounds(); if (bounds.width < endX - startX && bounds.height < barStartY) { @@ -187,10 +235,10 @@ private void paintSelected(Graphics2D g, int start, int end) { - int startX = getStartXPosition(start); - int endX = getEndXPosition(end); - int barStartY = getBarStartY(); - int barSelectionEndingStartY = barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_ENDING_HEIGHT / 2; + float startX = getStartXPosition(start); + float endX = getEndXPosition(end); + float barStartY = getBarStartY(); + float barSelectionEndingStartY = barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_ENDING_HEIGHT / 2; paintSelectedEnding(g, startX, barSelectionEndingStartY); paintSelectedEnding(g, endX, barSelectionEndingStartY); @@ -200,18 +248,18 @@ } else if (isOverBar) { g.setColor(BAR_SELECTION_COLOR_ROLLOVER); } - g.fillRect(startX, barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_HEIGHT / 2, endX - startX, BAR_SELECTION_HEIGHT); + g.fill(new Rectangle2D.Float(startX, barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_HEIGHT / 2, endX - startX, BAR_SELECTION_HEIGHT)); } - private void paintSelectedEnding(Graphics g, int x, int y) { + private void paintSelectedEnding(Graphics2D g, float x, float y) { g.setColor(BAR_COLOR); - g.fillRect(x - BAR_THICKNESS / 2, y, BAR_THICKNESS, BAR_SELECTION_ENDING_HEIGHT); + g.fill(new Rectangle2D.Float(x - BAR_THICKNESS / 2, y, BAR_THICKNESS, BAR_SELECTION_ENDING_HEIGHT)); } private boolean isOverSecondPosition(Point p) { if (p.y >= getBarStartY()) { - int destX = getEndXPosition(getPaintingModel().getSecondPosition()); - int off = Math.abs(destX - p.x); + float destX = getEndXPosition(getPaintingModel().getSecondPosition()); + float off = Math.abs(destX - p.x); return off <= MOUSE_ENDING_OFFSET; } return false; @@ -219,8 +267,8 @@ private boolean isOverFirstPosition(Point p) { if (p.y >= getBarStartY()) { - int destX = getStartXPosition(getPaintingModel().getFirstPosition()); - int off = Math.abs(destX - p.x); + float destX = getStartXPosition(getPaintingModel().getFirstPosition()); + float off = Math.abs(destX - p.x); return off <= MOUSE_ENDING_OFFSET; } return false; @@ -235,9 +283,12 @@ @Override public void mouseDragged(MouseEvent e) { + // Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1); + // scrollRectToVisible(r); + if (state == State.DragBar) { - int firstX = this.getStartXPosition(model.getFirstPosition()); - int newFirstX = firstX + e.getPoint().x - startPoint.x; + float firstX = this.getStartXPosition(model.getFirstPosition()); + float newFirstX = firstX + e.getPoint().x - startPoint.x; int newIndex = getIndexFromPosition(newFirstX) + 1; if (newIndex + model.getSecondPosition() - model.getFirstPosition() >= model.getPositions().size()) { newIndex = model.getPositions().size() - (model.getSecondPosition() - model.getFirstPosition()) - 1; @@ -264,13 +315,13 @@ } } - private int getIndexFromPosition(int x) { + private int getIndexFromPosition(float x) { if (x < getXPosition(0)) { return -1; } for (int i = 0; i < getPaintingModel().getPositions().size() - 1; i++) { - int startX = getXPosition(i); - int endX = getXPosition(i + 1); + float startX = getXPosition(i); + float endX = getXPosition(i + 1); if (x >= startX && x <= endX) { return i; } diff -r 7977cb9fa21f -r 22e0c20a3498 src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Tue Aug 12 17:45:03 2014 +0200 +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java Tue Aug 12 15:12:37 2014 -0700 @@ -197,7 +197,8 @@ rangeSliderModel = new DiagramViewModel(diagram.getGraph().getGroup(), filterChain, sequence); rangeSlider = new RangeSlider(); rangeSlider.setModel(rangeSliderModel); - container.add(BorderLayout.CENTER, rangeSlider); + JScrollPane pane = new JScrollPane(rangeSlider, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + container.add(BorderLayout.CENTER, pane); scene = new DiagramScene(actions, rangeSliderModel); content = new InstanceContent();