1 /* 2 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.ui; 26 27 import java.awt.*; 28 import java.awt.font.*; 29 import java.awt.geom.*; 30 import java.util.*; 31 32 import sun.jvm.hotspot.debugger.*; 33 import sun.jvm.hotspot.utilities.*; 34 35 /** This can be extended, along with AnnotatedMemoryPanel, to be an 36 arbitrarily complex mechanism, supporting user interaction, 37 etc. */ 38 39 public class Annotation { 40 private Interval interval; 41 private java.util.List<String> strings; 42 private java.util.List<Integer> heights; 43 private Color baseColor; 44 private int width; 45 private int height; 46 private int x; 47 private int y; 48 49 /** The Annotation can handle the sense of lowAddress and 50 highAddress being swapped. */ Annotation(Address lowAddress, Address highAddress, String s)51 public Annotation(Address lowAddress, 52 Address highAddress, 53 String s) { 54 strings = new ArrayList<>(); 55 heights = new ArrayList<>(); 56 for (StringTokenizer tok = new StringTokenizer(s, "\n"); tok.hasMoreTokens(); ) { 57 strings.add(tok.nextToken()); 58 } 59 if (AddressOps.lessThan(highAddress, lowAddress)) { 60 Address temp = lowAddress; 61 lowAddress = highAddress; 62 highAddress = temp; 63 } 64 interval = new Interval(lowAddress, highAddress); 65 } 66 getInterval()67 public Interval getInterval() { 68 return interval; 69 } 70 getLowAddress()71 public Address getLowAddress() { 72 return (Address) getInterval().getLowEndpoint(); 73 } 74 getHighAddress()75 public Address getHighAddress() { 76 return (Address) getInterval().getHighEndpoint(); 77 } 78 79 /** Draw the annotation at its current (x, y) position with its 80 current color */ draw(Graphics g)81 public void draw(Graphics g) { 82 g.setColor(baseColor); 83 int tmpY = y; 84 for (int i = 0; i < strings.size(); i++) { 85 String s = (String) strings.get(i); 86 Integer h = (Integer) heights.get(i); 87 g.drawString(s, x, tmpY); 88 tmpY += h.intValue(); 89 } 90 } 91 92 /** Sets the base color of this annotation. The annotation may 93 render sub-portions in a different color if desired. */ setColor(Color c)94 public void setColor(Color c) { 95 this.baseColor = c; 96 } 97 98 /** Returns the base color of this annotation. */ getColor()99 public Color getColor() { 100 return baseColor; 101 } 102 103 /** Computes width and height for this Annotation. Retrieve the 104 computed information using getWidth() and getHeight(). Separated 105 because the width and height only need to be recomputed if the 106 font changes. */ computeWidthAndHeight(Graphics g)107 public void computeWidthAndHeight(Graphics g) { 108 width = 0; 109 height = 0; 110 heights.clear(); 111 for (Iterator iter = strings.iterator(); iter.hasNext(); ) { 112 String s = (String) iter.next(); 113 Rectangle2D bounds = GraphicsUtilities.getStringBounds(s, g); 114 width = Math.max(width, (int) bounds.getWidth()); 115 height += (int) bounds.getHeight(); 116 heights.add((int) bounds.getHeight()); 117 } 118 } 119 getWidth()120 public int getWidth() { 121 return width; 122 } 123 getHeight()124 public int getHeight() { 125 return height; 126 } 127 128 /** Set the x and y position of this annotation */ setXAndY(int x, int y)129 public void setXAndY(int x, int y) { 130 this.x = x; this.y = y; 131 } 132 setX(int x)133 public void setX(int x) { 134 this.x = x; 135 } 136 getX()137 public int getX() { 138 return x; 139 } 140 setY(int y)141 public void setY(int y) { 142 this.y = y; 143 } 144 getY()145 public int getY() { 146 return y; 147 } 148 getBounds()149 public Rectangle getBounds() { 150 return new Rectangle(x, y, width, height); 151 } toString()152 public String toString() { 153 String result = "Annotation: lowAddr: " + getLowAddress() + " highAddr: " + getHighAddress() + " strings: " + strings.size(); 154 for (int i = 0; i < strings.size(); i++) { 155 result += "\n" + (String) strings.get(i); 156 } 157 return result; 158 } 159 } 160