275 /** 276 * Returns font metrics for a font. 277 * 278 * @param f the font 279 * @return the metrics 280 */ 281 public FontMetrics getFontMetrics(Font f) { 282 // The Toolkit implementations cache, so we just forward 283 // to the default toolkit. 284 return Toolkit.getDefaultToolkit().getFontMetrics(f); 285 } 286 287 // --- AttributeContext methods -------------------- 288 289 /** 290 * Adds an attribute to the given set, and returns 291 * the new representative set. 292 * <p> 293 * This method is thread safe, although most Swing methods 294 * are not. Please see 295 * <A HREF="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 296 * in Swing</A> for more information. 297 * 298 * @param old the old attribute set 299 * @param name the non-null attribute name 300 * @param value the attribute value 301 * @return the updated attribute set 302 * @see MutableAttributeSet#addAttribute 303 */ 304 public synchronized AttributeSet addAttribute(AttributeSet old, Object name, Object value) { 305 if ((old.getAttributeCount() + 1) <= getCompressionThreshold()) { 306 // build a search key and find/create an immutable and unique 307 // set. 308 search.removeAttributes(search); 309 search.addAttributes(old); 310 search.addAttribute(name, value); 311 reclaim(old); 312 return getImmutableUniqueSet(); 313 } 314 MutableAttributeSet ma = getMutableAttributeSet(old); 315 ma.addAttribute(name, value); 316 return ma; 317 } 318 319 /** 320 * Adds a set of attributes to the element. 321 * <p> 322 * This method is thread safe, although most Swing methods 323 * are not. Please see 324 * <A HREF="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 325 * in Swing</A> for more information. 326 * 327 * @param old the old attribute set 328 * @param attr the attributes to add 329 * @return the updated attribute set 330 * @see MutableAttributeSet#addAttribute 331 */ 332 public synchronized AttributeSet addAttributes(AttributeSet old, AttributeSet attr) { 333 if ((old.getAttributeCount() + attr.getAttributeCount()) <= getCompressionThreshold()) { 334 // build a search key and find/create an immutable and unique 335 // set. 336 search.removeAttributes(search); 337 search.addAttributes(old); 338 search.addAttributes(attr); 339 reclaim(old); 340 return getImmutableUniqueSet(); 341 } 342 MutableAttributeSet ma = getMutableAttributeSet(old); 343 ma.addAttributes(attr); 344 return ma; 345 } 346 347 /** 348 * Removes an attribute from the set. 349 * <p> 350 * This method is thread safe, although most Swing methods 351 * are not. Please see 352 * <A HREF="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 353 * in Swing</A> for more information. 354 * 355 * @param old the old set of attributes 356 * @param name the non-null attribute name 357 * @return the updated attribute set 358 * @see MutableAttributeSet#removeAttribute 359 */ 360 public synchronized AttributeSet removeAttribute(AttributeSet old, Object name) { 361 if ((old.getAttributeCount() - 1) <= getCompressionThreshold()) { 362 // build a search key and find/create an immutable and unique 363 // set. 364 search.removeAttributes(search); 365 search.addAttributes(old); 366 search.removeAttribute(name); 367 reclaim(old); 368 return getImmutableUniqueSet(); 369 } 370 MutableAttributeSet ma = getMutableAttributeSet(old); 371 ma.removeAttribute(name); 372 return ma; 373 } 374 375 /** 376 * Removes a set of attributes for the element. 377 * <p> 378 * This method is thread safe, although most Swing methods 379 * are not. Please see 380 * <A HREF="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 381 * in Swing</A> for more information. 382 * 383 * @param old the old attribute set 384 * @param names the attribute names 385 * @return the updated attribute set 386 * @see MutableAttributeSet#removeAttributes 387 */ 388 public synchronized AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) { 389 if (old.getAttributeCount() <= getCompressionThreshold()) { 390 // build a search key and find/create an immutable and unique 391 // set. 392 search.removeAttributes(search); 393 search.addAttributes(old); 394 search.removeAttributes(names); 395 reclaim(old); 396 return getImmutableUniqueSet(); 397 } 398 MutableAttributeSet ma = getMutableAttributeSet(old); 399 ma.removeAttributes(names); 400 return ma; 401 } 402 403 /** 404 * Removes a set of attributes for the element. 405 * <p> 406 * This method is thread safe, although most Swing methods 407 * are not. Please see 408 * <A HREF="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 409 * in Swing</A> for more information. 410 * 411 * @param old the old attribute set 412 * @param attrs the attributes 413 * @return the updated attribute set 414 * @see MutableAttributeSet#removeAttributes 415 */ 416 public synchronized AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) { 417 if (old.getAttributeCount() <= getCompressionThreshold()) { 418 // build a search key and find/create an immutable and unique 419 // set. 420 search.removeAttributes(search); 421 search.addAttributes(old); 422 search.removeAttributes(attrs); 423 reclaim(old); 424 return getImmutableUniqueSet(); 425 } 426 MutableAttributeSet ma = getMutableAttributeSet(old); 427 ma.removeAttributes(attrs); 428 return ma; 429 } 430 431 /** 432 * Fetches an empty AttributeSet. 433 * 434 * @return the set 435 */ 436 public AttributeSet getEmptySet() { 437 return SimpleAttributeSet.EMPTY; 438 } 439 440 /** 441 * Returns a set no longer needed by the MutableAttributeSet implmentation. 442 * This is useful for operation under 1.1 where there are no weak 443 * references. This would typically be called by the finalize method 444 * of the MutableAttributeSet implementation. 445 * <p> 446 * This method is thread safe, although most Swing methods 447 * are not. Please see 448 * <A HREF="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 449 * in Swing</A> for more information. 450 * 451 * @param a the set to reclaim 452 */ 453 public void reclaim(AttributeSet a) { 454 if (SwingUtilities.isEventDispatchThread()) { 455 attributesPool.size(); // force WeakHashMap to expunge stale entries 456 } 457 // if current thread is not event dispatching thread 458 // do not bother with expunging stale entries. 459 } 460 461 // --- local methods ----------------------------------------------- 462 463 /** 464 * Returns the maximum number of key/value pairs to try and 465 * compress into unique/immutable sets. Any sets above this 466 * limit will use hashtables and be a MutableAttributeSet. 467 * 468 * @return the threshold | 275 /** 276 * Returns font metrics for a font. 277 * 278 * @param f the font 279 * @return the metrics 280 */ 281 public FontMetrics getFontMetrics(Font f) { 282 // The Toolkit implementations cache, so we just forward 283 // to the default toolkit. 284 return Toolkit.getDefaultToolkit().getFontMetrics(f); 285 } 286 287 // --- AttributeContext methods -------------------- 288 289 /** 290 * Adds an attribute to the given set, and returns 291 * the new representative set. 292 * <p> 293 * This method is thread safe, although most Swing methods 294 * are not. Please see 295 * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 296 * in Swing</A> for more information. 297 * 298 * @param old the old attribute set 299 * @param name the non-null attribute name 300 * @param value the attribute value 301 * @return the updated attribute set 302 * @see MutableAttributeSet#addAttribute 303 */ 304 public synchronized AttributeSet addAttribute(AttributeSet old, Object name, Object value) { 305 if ((old.getAttributeCount() + 1) <= getCompressionThreshold()) { 306 // build a search key and find/create an immutable and unique 307 // set. 308 search.removeAttributes(search); 309 search.addAttributes(old); 310 search.addAttribute(name, value); 311 reclaim(old); 312 return getImmutableUniqueSet(); 313 } 314 MutableAttributeSet ma = getMutableAttributeSet(old); 315 ma.addAttribute(name, value); 316 return ma; 317 } 318 319 /** 320 * Adds a set of attributes to the element. 321 * <p> 322 * This method is thread safe, although most Swing methods 323 * are not. Please see 324 * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 325 * in Swing</A> for more information. 326 * 327 * @param old the old attribute set 328 * @param attr the attributes to add 329 * @return the updated attribute set 330 * @see MutableAttributeSet#addAttribute 331 */ 332 public synchronized AttributeSet addAttributes(AttributeSet old, AttributeSet attr) { 333 if ((old.getAttributeCount() + attr.getAttributeCount()) <= getCompressionThreshold()) { 334 // build a search key and find/create an immutable and unique 335 // set. 336 search.removeAttributes(search); 337 search.addAttributes(old); 338 search.addAttributes(attr); 339 reclaim(old); 340 return getImmutableUniqueSet(); 341 } 342 MutableAttributeSet ma = getMutableAttributeSet(old); 343 ma.addAttributes(attr); 344 return ma; 345 } 346 347 /** 348 * Removes an attribute from the set. 349 * <p> 350 * This method is thread safe, although most Swing methods 351 * are not. Please see 352 * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 353 * in Swing</A> for more information. 354 * 355 * @param old the old set of attributes 356 * @param name the non-null attribute name 357 * @return the updated attribute set 358 * @see MutableAttributeSet#removeAttribute 359 */ 360 public synchronized AttributeSet removeAttribute(AttributeSet old, Object name) { 361 if ((old.getAttributeCount() - 1) <= getCompressionThreshold()) { 362 // build a search key and find/create an immutable and unique 363 // set. 364 search.removeAttributes(search); 365 search.addAttributes(old); 366 search.removeAttribute(name); 367 reclaim(old); 368 return getImmutableUniqueSet(); 369 } 370 MutableAttributeSet ma = getMutableAttributeSet(old); 371 ma.removeAttribute(name); 372 return ma; 373 } 374 375 /** 376 * Removes a set of attributes for the element. 377 * <p> 378 * This method is thread safe, although most Swing methods 379 * are not. Please see 380 * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 381 * in Swing</A> for more information. 382 * 383 * @param old the old attribute set 384 * @param names the attribute names 385 * @return the updated attribute set 386 * @see MutableAttributeSet#removeAttributes 387 */ 388 public synchronized AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names) { 389 if (old.getAttributeCount() <= getCompressionThreshold()) { 390 // build a search key and find/create an immutable and unique 391 // set. 392 search.removeAttributes(search); 393 search.addAttributes(old); 394 search.removeAttributes(names); 395 reclaim(old); 396 return getImmutableUniqueSet(); 397 } 398 MutableAttributeSet ma = getMutableAttributeSet(old); 399 ma.removeAttributes(names); 400 return ma; 401 } 402 403 /** 404 * Removes a set of attributes for the element. 405 * <p> 406 * This method is thread safe, although most Swing methods 407 * are not. Please see 408 * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 409 * in Swing</A> for more information. 410 * 411 * @param old the old attribute set 412 * @param attrs the attributes 413 * @return the updated attribute set 414 * @see MutableAttributeSet#removeAttributes 415 */ 416 public synchronized AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) { 417 if (old.getAttributeCount() <= getCompressionThreshold()) { 418 // build a search key and find/create an immutable and unique 419 // set. 420 search.removeAttributes(search); 421 search.addAttributes(old); 422 search.removeAttributes(attrs); 423 reclaim(old); 424 return getImmutableUniqueSet(); 425 } 426 MutableAttributeSet ma = getMutableAttributeSet(old); 427 ma.removeAttributes(attrs); 428 return ma; 429 } 430 431 /** 432 * Fetches an empty AttributeSet. 433 * 434 * @return the set 435 */ 436 public AttributeSet getEmptySet() { 437 return SimpleAttributeSet.EMPTY; 438 } 439 440 /** 441 * Returns a set no longer needed by the MutableAttributeSet implmentation. 442 * This is useful for operation under 1.1 where there are no weak 443 * references. This would typically be called by the finalize method 444 * of the MutableAttributeSet implementation. 445 * <p> 446 * This method is thread safe, although most Swing methods 447 * are not. Please see 448 * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency 449 * in Swing</A> for more information. 450 * 451 * @param a the set to reclaim 452 */ 453 public void reclaim(AttributeSet a) { 454 if (SwingUtilities.isEventDispatchThread()) { 455 attributesPool.size(); // force WeakHashMap to expunge stale entries 456 } 457 // if current thread is not event dispatching thread 458 // do not bother with expunging stale entries. 459 } 460 461 // --- local methods ----------------------------------------------- 462 463 /** 464 * Returns the maximum number of key/value pairs to try and 465 * compress into unique/immutable sets. Any sets above this 466 * limit will use hashtables and be a MutableAttributeSet. 467 * 468 * @return the threshold |