PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/bundles/plugins-trunk/CommonControls/common/swingworker/AccumulativeRunnable.java

#
Java | 142 lines | 29 code | 9 blank | 104 comment | 3 complexity | cc525361e0270e2335f6d1f44bce9dd5 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * $Id: AccumulativeRunnable.java,v 1.2 2006/09/28 20:20:28 idk Exp $
  3. *
  4. * Copyright 2005 Sun Microsystems, Inc. All rights
  5. * reserved. Use is subject to license terms.
  6. */
  7. //package org.jdesktop.swingworker;
  8. package common.swingworker;
  9. import java.util.*;
  10. import javax.swing.SwingUtilities;
  11. /**
  12. * An abstract class to be used in the cases where we need {@code Runnable}
  13. * to perform some actions on an appendable set of data.
  14. * The set of data might be appended after the {@code Runnable} is
  15. * sent for the execution. Usually such {@code Runnables} are sent to
  16. * the EDT.
  17. *
  18. * <p>
  19. * Usage example:
  20. *
  21. * <p>
  22. * Say we want to implement JLabel.setText(String text) which sends
  23. * {@code text} string to the JLabel.setTextImpl(String text) on the EDT.
  24. * In the event JLabel.setText is called rapidly many times off the EDT
  25. * we will get many updates on the EDT but only the last one is important.
  26. * (Every next updates overrides the previous one.)
  27. * We might want to implement this {@code setText} in a way that only
  28. * the last update is delivered.
  29. * <p>
  30. * Here is how one can do this using {@code AccumulativeRunnable}:
  31. * <pre>
  32. * AccumulativeRunnable<String> doSetTextImpl =
  33. * new AccumulativeRunnable<String>() {
  34. * @Override
  35. * protected void run(List&lt;String&gt; args) {
  36. * //set to the last string being passed
  37. * setTextImpl(args.get(args.size() - 1);
  38. * }
  39. * }
  40. * void setText(String text) {
  41. * //add text and send for the execution if needed.
  42. * doSetTextImpl.add(text);
  43. * }
  44. * </pre>
  45. *
  46. * <p>
  47. * Say we want want to implement addDirtyRegion(Rectangle rect)
  48. * which sends this region to the
  49. * handleDirtyRegions(List<Rect> regions) on the EDT.
  50. * addDirtyRegions better be accumulated before handling on the EDT.
  51. *
  52. * <p>
  53. * Here is how it can be implemented using AccumulativeRunnable:
  54. * <pre>
  55. * AccumulativeRunnable<Rectangle> doHandleDirtyRegions =
  56. * new AccumulativeRunnable<Rectangle>() {
  57. * @Override
  58. * protected void run(List&lt;Rectangle&gt; args) {
  59. * handleDirtyRegions(args);
  60. * }
  61. * };
  62. * void addDirtyRegion(Rectangle rect) {
  63. * doHandleDirtyRegions.add(rect);
  64. * }
  65. * </pre>
  66. *
  67. * @author Igor Kushnirskiy
  68. * @version $Revision: 1.2 $ $Date: 2006/09/28 20:20:28 $
  69. *
  70. * @param <T> the type this {@code Runnable} accumulates
  71. *
  72. */
  73. abstract class AccumulativeRunnable<T> implements Runnable {
  74. private List<T> arguments = null;
  75. /**
  76. * Equivalent to {@code Runnable.run} method with the
  77. * accumulated arguments to process.
  78. *
  79. * @param args accumulated arguments to process.
  80. */
  81. protected abstract void run(List<T> args);
  82. /**
  83. * {@inheritDoc}
  84. *
  85. * <p>
  86. * This implementation calls {@code run(List<T> args)} method
  87. * with the list of accumulated arguments.
  88. */
  89. public final void run() {
  90. run(flush());
  91. }
  92. /**
  93. * appends arguments and sends this {@code Runnable} for the
  94. * execution if needed.
  95. * <p>
  96. * This implementation uses {@see #submit} to send this
  97. * {@code Runnable} for execution.
  98. * @param args the arguments to accumulate
  99. */
  100. public final synchronized void add(T... args) {
  101. boolean isSubmitted = true;
  102. if (arguments == null) {
  103. isSubmitted = false;
  104. arguments = new ArrayList<T>();
  105. }
  106. Collections.addAll(arguments, args);
  107. if (!isSubmitted) {
  108. submit();
  109. }
  110. }
  111. /**
  112. * Sends this {@code Runnable} for the execution
  113. *
  114. * <p>
  115. * This method is to be executed only from {@code add} method.
  116. *
  117. * <p>
  118. * This implementation uses {@code SwingWorker.invokeLater}.
  119. */
  120. protected void submit() {
  121. SwingUtilities.invokeLater(this);
  122. }
  123. /**
  124. * Returns accumulated arguments and flashes the arguments storage.
  125. *
  126. * @return accumulated arguments
  127. */
  128. private final synchronized List<T> flush() {
  129. List<T> list = arguments;
  130. arguments = null;
  131. return list;
  132. }
  133. }