1 19 20 21 26 package org.netbeans.swing.scrollbars.impl; 27 28 import org.netbeans.swing.scrollbars.spi.Mark; 29 import org.netbeans.swing.scrollbars.spi.MarkingModel; 30 31 import javax.swing.*; 32 import javax.swing.event.ChangeListener ; 33 import javax.swing.plaf.metal.MetalScrollBarUI ; 34 import java.awt.*; 35 import java.awt.event.ComponentEvent ; 36 import java.awt.event.ComponentListener ; 37 import java.awt.event.MouseEvent ; 38 import java.beans.PropertyChangeEvent ; 39 import java.beans.PropertyChangeListener ; 40 import java.util.Enumeration ; 41 import java.util.HashMap ; 42 import java.util.Iterator ; 43 import java.util.Map ; 44 45 51 public class MetalMarkedScrollBarUI extends MetalScrollBarUI implements PropertyChangeListener , ChangeListener { 52 private static final int minsize = 4; 53 54 private int gutterSize=8; 55 private MarkingModel model; 56 57 61 public MetalMarkedScrollBarUI(MarkingModel model) { 62 this.model = model; 63 model.addChangeListener(this); 64 updateUI(); 65 } 66 67 public void updateUI () { 68 if ((scrollbar != null) && scrollbar.isVisible()) { 69 if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { 70 layoutVScrollbar (scrollbar); 71 } else { 72 layoutHScrollbar (scrollbar); 73 } 74 } 75 } 76 77 public Dimension getPreferredSize(JComponent c) { 78 Dimension result = super.getPreferredSize(c); 79 if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { 80 result.width += gutterSize - (gutterSize / 3); 81 } else { 82 result.height += gutterSize - (gutterSize / 3); 83 } 84 return result; 85 } 86 87 public void installUI(JComponent c) { 88 updateUI(); 89 super.installUI(c); 90 UIManager.addPropertyChangeListener(this); 91 c.addComponentListener ((ComponentListener ) trackListener); 92 } 93 94 public void uninstallUI(JComponent c) { 95 super.uninstallUI(c); 96 UIManager.removePropertyChangeListener(this); 97 c.removeComponentListener ((ComponentListener ) trackListener); 98 } 99 100 102 public final void propertyChange (PropertyChangeEvent pce) { 103 updateUI(); 104 } 105 106 protected void layoutVScrollbar(JScrollBar sb) { 107 super.layoutVScrollbar (sb); 108 trackRect.width -=gutterSize; 109 thumbRect.width -=gutterSize; 110 invalidateMarks(); 111 } 112 113 protected void layoutHScrollbar(JScrollBar sb) { 114 super.layoutVScrollbar (sb); 115 trackRect.height -=gutterSize; 116 thumbRect.height -=gutterSize; 117 invalidateMarks(); 118 } 119 120 public void paint(Graphics g, JComponent c) { 121 paintTrack(g, c, getTrackBounds()); 122 paintThumb(g, c, getThumbBounds()); 123 paintMarks(g); 124 if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { 125 g.setColor(UIManager.getColor("controlDkShadow")); g.drawLine(c.getWidth()-2, trackRect.y, c.getWidth()-2, trackRect.y+trackRect.height); 127 g.setColor(UIManager.getColor("controlHighlight")); g.drawLine(c.getWidth()-1, trackRect.y, c.getWidth()-1, trackRect.y+trackRect.height); 129 } else { 130 g.setColor(UIManager.getColor("controlDkShadow")); g.drawLine(trackRect.x, 2, trackRect.x+trackRect.width, 2); 132 g.setColor(UIManager.getColor("controlHighlight")); g.drawLine(trackRect.x, 1, trackRect.x+trackRect.width, 1); 134 } 135 } 136 137 private void paintMarks (Graphics g) { 138 Map map = getRectsToMarks(); 139 for (Iterator i = map.keySet().iterator(); i.hasNext();) { 140 Rectangle mrect = (Rectangle) i.next(); 141 Mark mark = (Mark) map.get(mrect); 142 paintMark (mark, g, mrect); 143 } 144 } 145 146 private boolean invalid = true; 147 private void invalidateMarks() { 148 invalid = true; 149 scrollbar.repaint(); 150 } 151 152 private Map getRectsToMarks() { 153 if (invalid) { 154 buildRects(); 155 } 156 return rectsToMarks; 157 } 158 159 private void buildRects() { 160 rectsToMarks.clear(); 161 if (model.size() == 0) { 162 return; 163 } 164 boolean vertical = scrollbar.getOrientation() == JScrollBar.VERTICAL; 165 int markRange = model.getMaxMarkLocation(); 166 167 Rectangle r = getMarksRect(); 168 for (Enumeration e = model.getMarks(); e.hasMoreElements();) { 169 Mark mark = (Mark) e.nextElement(); 170 Rectangle curr = new Rectangle(); 171 if (vertical) { 172 r.y = translate (mark.getStart(), markRange); 173 r.height = Math.max(minsize, translate (mark.getLength(), markRange)); 174 r.width = gutterSize; 175 curr.setBounds(r.x, r.y, r.width, r.height); 176 rectsToMarks.put (curr, mark); 177 } else { 178 r.x = translate (mark.getStart(), markRange); 179 r.width = Math.max(minsize, translate (mark.getLength(), markRange)); 180 r.height = gutterSize; 181 curr.setBounds(r.x, r.y, r.width, r.height); 182 rectsToMarks.put (curr, mark); 183 } 184 } 185 invalid = false; 186 } 187 188 private HashMap rectsToMarks = new HashMap (); 189 190 194 public Mark markAtPoint (Point p) { 195 Rectangle rect = getMarksRect(); 196 if (!(rect.contains(p))) return null; 197 java.util.Iterator i = rectsToMarks.keySet().iterator(); 198 while (i.hasNext()) { 199 Rectangle r = (Rectangle) i.next(); 200 if (r.contains(p)) return (Mark) rectsToMarks.get(r); 201 } 202 return null; 203 } 204 205 212 protected final int translate (int loc, int max) { 213 int range = getVisibleRange(); 214 double factor = range / max; 215 double pos = factor * loc; 216 return Math.round(Math.round(pos)); 217 } 218 219 224 protected final int getVisibleRange () { 225 Rectangle mrect = getMarksRect(); 226 return (scrollbar.getOrientation() == JScrollBar.VERTICAL) ? 227 mrect.height : mrect.width; 228 } 229 230 233 protected final Rectangle getMarksRect () { 234 Rectangle result; 235 if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { 236 result = new Rectangle (trackRect.x + trackRect.width + 1, trackRect.y, 237 trackRect.width +gutterSize, trackRect.height); 238 } else { 239 result = new Rectangle (trackRect.x, trackRect.y + trackRect.height + 1, 240 trackRect.width, trackRect.height +gutterSize); 241 } 242 return result; 243 } 244 245 protected TrackListener createTrackListener() { 246 return new MarkAndTrackListener (); 247 } 248 249 private int translateToScrollbarModel (int i) { 250 BoundedRangeModel mod = scrollbar.getModel(); 251 int min = mod.getMinimum(); 252 int max = mod.getMaximum(); 253 int mrange = max - min; 254 255 double factor = mrange / model.getMaxMarkLocation(); 256 double pos = (i * factor) + min; 257 return Math.round(Math.round(pos)); 258 } 259 260 private void goToMark (Mark m) { 261 Rectangle r = getMarksRect(); 262 int loc = translate (m.getStart(), r.height); 263 scrollbar.setValue(translateToScrollbarModel (loc)); 264 m.select(); 265 } 266 267 public void stateChanged(javax.swing.event.ChangeEvent e) { 268 invalidateMarks(); 269 } 270 271 protected class MarkAndTrackListener extends TrackListener implements ComponentListener { 272 public void mousePressed (MouseEvent e) 273 { 274 if (scrollbar.getValueIsAdjusting ()) { 275 super.mousePressed (e); 276 return; 277 } 278 if (SwingUtilities.isRightMouseButton(e) || 279 SwingUtilities.isMiddleMouseButton(e) || !scrollbar.isEnabled()) { 280 return; 281 } 282 283 Point p = e.getPoint(); 284 Rectangle r = getMarksRect(); 285 286 if (r.contains (p)) { 287 Mark m = markAtPoint (p); 288 if (m != null) { 289 goToMark (m); 290 } 291 } else { 292 super.mousePressed(e); 293 } 294 } 295 296 private boolean notInMarksRect (MouseEvent e) { 297 Point p = e.getPoint(); 298 Rectangle r = getMarksRect(); 299 return !(r.contains (p)); 300 } 301 302 public void mouseReleased (MouseEvent e) { 303 if (scrollbar.getValueIsAdjusting () || notInMarksRect (e)) { 304 super.mouseReleased (e); 305 } 306 } 307 308 public void mouseDragged (MouseEvent e) { 309 if (scrollbar.getValueIsAdjusting () || notInMarksRect (e)) { 310 super.mouseDragged (e); 311 } 312 } 313 String oldtext; 314 public void mouseMoved (MouseEvent e) { 315 if (scrollbar.getValueIsAdjusting () || notInMarksRect (e)) { 316 super.mouseMoved (e); 317 } else { 318 Point p = e.getPoint(); 319 Rectangle r = getMarksRect(); 320 321 if (r.contains (p)) { 322 Mark m = markAtPoint (p); 323 if (m != null) { 324 scrollbar.setToolTipText (m.getText()); 325 } else { 326 scrollbar.setToolTipText (null); 327 } 328 } 329 } 330 } 331 332 335 public void componentResized(ComponentEvent e) { 336 invalidateMarks(); 337 } 338 339 342 public void componentMoved(ComponentEvent e) { 343 344 } 345 346 349 public void componentShown(ComponentEvent e) { 350 invalidateMarks(); 351 } 352 353 356 public void componentHidden(ComponentEvent e) { 357 rectsToMarks.clear(); 358 invalid = true; 359 } 360 } 361 362 public void paintMarkMetal(Mark mark, Graphics g, Rectangle r) { 363 Color c = (Color) mark.get ("color"); if (c == null) { 365 c = UIManager.getColor("windowText"); } 367 g.setColor (c); 368 g.fillRect (r.x-1, r.y, r.width-1, r.height); 369 g.setColor (c.darker()); 370 g.drawRect (r.x-1, r.y, r.width-2, r.height); 371 } 372 373 374 375 public void paintMark(Mark mark, Graphics g, Rectangle r) { 376 if (getClass() == MetalMarkedScrollBarUI.class) { 377 paintMarkMetal (mark, g, r); 378 } else { 379 paintMarkWindows (mark, g, r); 380 } 381 } 382 383 private static final int overhang =5; 384 public void paintMarkWindows (Mark mark, Graphics graphics, Rectangle rect) { 385 Color c = (Color) mark.get ("color"); if (c == null) { 387 c = UIManager.getColor("windowText"); } 389 Paint p = new GradientPaint(rect.x+rect.width-1, rect.y+3, c, 390 rect.x-overhang, rect.y+3, UIManager.getColor("control")); 391 ((Graphics2D)graphics).setPaint(p); 392 393 graphics.fillRect (rect.x-overhang, rect.y, rect.width+4, rect.height); 394 395 graphics.setColor(c.darker()); 396 graphics.drawLine(rect.x+rect.width, rect.y, rect.x+rect.width, rect.y+rect.height-1); 397 graphics.drawLine(rect.x+rect.width-1, rect.y, rect.x+rect.width-1, rect.y+rect.height-1); 398 graphics.drawLine(rect.x+rect.width-2, rect.y, rect.x+rect.width-2, rect.y+rect.height-1); 399 graphics.drawLine(rect.x+rect.width-3, rect.y, rect.x+rect.width-3, rect.y+rect.height-1); 400 401 402 graphics.setColor(UIManager.getColor("controlLtHighlight")); 403 graphics.drawLine(rect.x-overhang, rect.y, 404 rect.x+rect.width+overhang, rect.y); 405 406 p = new GradientPaint(rect.x+rect.width-1, rect.y+3, c.darker(), 407 rect.x-overhang, rect.y+3, UIManager.getColor("controlShadow")); 408 ((Graphics2D)graphics).setPaint(p); 409 410 graphics.drawLine(rect.x-overhang, rect.y+rect.height, 411 rect.x+rect.width+overhang, rect.y+rect.height); 412 } 413 } 414 | Popular Tags |