1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.ui.browser.model; 4 5 import java.util.LinkedList; 6 import java.awt.*; 7 8 public class ImageTaskQueue implements Runnable { 9 10 private LinkedList<ImageTask> queue; 11 12 private Thread thread; 13 private boolean pause; 14 private boolean stop; 15 16 private LinkedList<ImageTaskQueueListener> listeners; 17 ImageTaskQueue()18 public ImageTaskQueue() { 19 thread = new Thread(this, "Image Task Queue"); 20 thread.setPriority(Thread.MIN_PRIORITY); 21 queue = new LinkedList<ImageTask>(); 22 listeners = new LinkedList<ImageTaskQueueListener>(); 23 } 24 addTask(ImageTask task)25 void addTask(ImageTask task) { 26 synchronized(queue) { 27 queue.add(task); 28 queue.notifyAll(); 29 } 30 } 31 removeTask(ImageTask task)32 void removeTask(ImageTask task) { 33 synchronized(queue) { 34 queue.remove(task); 35 } 36 } 37 removeAllTasks()38 void removeAllTasks() { 39 synchronized(queue) { 40 queue.clear(); 41 } 42 } 43 start()44 public void start() { 45 if (! thread.isAlive()) { 46 pause = false; 47 stop = false; 48 thread.start(); 49 } 50 } 51 stop()52 public void stop() { 53 pause = false; 54 stop = true; 55 synchronized(queue) { 56 queue.notifyAll(); 57 } 58 synchronized(thread) { 59 thread.notifyAll(); 60 } 61 } 62 pause()63 public void pause() { 64 synchronized(thread) { 65 pause = true; 66 } 67 } 68 resume()69 public void resume() { 70 synchronized(thread) { 71 if (pause) { 72 pause = false; 73 thread.notifyAll(); 74 } 75 } 76 } 77 raiseTask(ImageTask task)78 public void raiseTask(ImageTask task) { 79 synchronized(queue) { 80 if (queue.contains(task)) { 81 queue.remove(task); 82 queue.addFirst(task); 83 } 84 } 85 } 86 lowerTask(ImageTask task)87 public void lowerTask(ImageTask task) { 88 synchronized(queue) { 89 if (queue.contains(task)) { 90 queue.remove(task); 91 queue.addLast(task); 92 } 93 } 94 } 95 run()96 public void run() { 97 while (! stop) { 98 Runnable task; 99 synchronized(queue) { 100 while (queue.isEmpty() && (! stop)) { 101 waitForNotify(queue); 102 if (stop) { 103 return; 104 } 105 } 106 task = queue.removeFirst(); 107 logQueueSize(); 108 } 109 try { 110 task.run(); 111 } 112 catch (Throwable t) { 113 logTaskError(t); 114 } 115 synchronized(thread) { 116 while (pause && (! stop)) { 117 waitForNotify(thread); 118 } 119 } 120 } 121 } 122 addListener(ImageTaskQueueListener listener)123 void addListener(ImageTaskQueueListener listener) { 124 listeners.add(listener); 125 } 126 removeListener(ImageTaskQueueListener listener)127 void removeListener(ImageTaskQueueListener listener) { 128 listeners.remove(listener); 129 } 130 waitForNotify(Object monitor)131 private static void waitForNotify(Object monitor) { 132 synchronized(monitor) { 133 boolean interrupted; 134 do { 135 try { 136 interrupted = false; 137 monitor.wait(); 138 } 139 catch (InterruptedException e) { 140 interrupted = true; 141 } 142 } while (interrupted); 143 } 144 } 145 logQueueSize()146 private void logQueueSize() { 147 final int depth = queue.size(); 148 EventQueue.invokeLater( 149 new Runnable() { 150 public void run() { 151 for (ImageTaskQueueListener listener : listeners) { 152 listener.queueDepthChanged(depth); 153 } 154 } 155 } 156 ); 157 } 158 logTaskError(Throwable t)159 private void logTaskError(Throwable t) { 160 StringBuffer buffer = new StringBuffer(); 161 buffer.append("Abort ImageTask--"); 162 buffer.append(t.getClass().getName()); 163 if (t.getMessage() != null) { 164 buffer.append(": "); 165 buffer.append(t.getMessage()); 166 } 167 System.err.println(buffer); 168 t.printStackTrace(); 169 } 170 } 171