From: <hi...@us...> - 2011-05-31 16:18:14
|
Revision: 8197 http://genoviz.svn.sourceforge.net/genoviz/?rev=8197&view=rev Author: hiralv Date: 2011-05-31 16:18:07 +0000 (Tue, 31 May 2011) Log Message: ----------- Adding new classes to handle thread canceling. Added Paths: ----------- trunk/igb/src/com/affymetrix/igb/thread/ trunk/igb/src/com/affymetrix/igb/thread/CThreadEvent.java trunk/igb/src/com/affymetrix/igb/thread/CThreadListener.java trunk/igb/src/com/affymetrix/igb/thread/CThreadWorker.java trunk/igb/src/com/affymetrix/igb/thread/ThreadHandler.java Added: trunk/igb/src/com/affymetrix/igb/thread/CThreadEvent.java =================================================================== --- trunk/igb/src/com/affymetrix/igb/thread/CThreadEvent.java (rev 0) +++ trunk/igb/src/com/affymetrix/igb/thread/CThreadEvent.java 2011-05-31 16:18:07 UTC (rev 8197) @@ -0,0 +1,27 @@ + +package com.affymetrix.igb.thread; + +import java.util.EventObject; + +/** + * + * @author hiralv + */ +public class CThreadEvent extends EventObject{ + public static int STARTED = 0; + public static int ENDED = 1; + + private final int state; + + public CThreadEvent(CThreadWorker worker, int state){ + super(worker); + if(state != STARTED && state != ENDED){ + throw new IllegalArgumentException("Invalid Statusbar Message"); + } + this.state = state; + } + + public int getState(){ + return state; + } +} Added: trunk/igb/src/com/affymetrix/igb/thread/CThreadListener.java =================================================================== --- trunk/igb/src/com/affymetrix/igb/thread/CThreadListener.java (rev 0) +++ trunk/igb/src/com/affymetrix/igb/thread/CThreadListener.java 2011-05-31 16:18:07 UTC (rev 8197) @@ -0,0 +1,11 @@ +package com.affymetrix.igb.thread; + +import java.util.EventListener; + +/** + * + * @author hiralv + */ +public interface CThreadListener extends EventListener{ + public void heardThreadEvent(CThreadEvent cte); +} Added: trunk/igb/src/com/affymetrix/igb/thread/CThreadWorker.java =================================================================== --- trunk/igb/src/com/affymetrix/igb/thread/CThreadWorker.java (rev 0) +++ trunk/igb/src/com/affymetrix/igb/thread/CThreadWorker.java 2011-05-31 16:18:07 UTC (rev 8197) @@ -0,0 +1,58 @@ +package com.affymetrix.igb.thread; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import javax.swing.SwingWorker; + +/** + * + * @author hiralv + */ +public abstract class CThreadWorker extends SwingWorker{ + + private Set<CThreadListener> listeners= new CopyOnWriteArraySet<CThreadListener>(); + + final private String message; + + public CThreadWorker(String msg){ + if(msg == null || msg.length() == 0){ + throw new IllegalArgumentException("Invalid Statusbar Message"); + } + message = msg; + } + + public String getMessage(){ + return message; + } + + @Override + public final void done() { + if(!isCancelled()){ + finished(); + } + fireThreadEvent(this, CThreadEvent.ENDED); + } + + @Override + protected final Object doInBackground() throws Exception { + fireThreadEvent(this, CThreadEvent.STARTED); + return runInBackground(); + } + + protected abstract Object runInBackground(); + + protected abstract void finished(); + + public void addThreadListener(CThreadListener listener){ + listeners.add(listener); + } + + private void fireThreadEvent(CThreadWorker worker, int state){ + CThreadEvent event = new CThreadEvent(worker, state); + for(CThreadListener listener : listeners){ + listener.heardThreadEvent(event); + } + } + +} Added: trunk/igb/src/com/affymetrix/igb/thread/ThreadHandler.java =================================================================== --- trunk/igb/src/com/affymetrix/igb/thread/ThreadHandler.java (rev 0) +++ trunk/igb/src/com/affymetrix/igb/thread/ThreadHandler.java 2011-05-31 16:18:07 UTC (rev 8197) @@ -0,0 +1,137 @@ + +package com.affymetrix.igb.thread; + +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.AbstractButton; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JFrame; + +import com.affymetrix.igb.Application; +import com.affymetrix.igb.util.IGBUtils; +import com.affymetrix.igb.util.ThreadUtils; + + +/** + * + * @author hiralv + */ +public class ThreadHandler implements ActionListener, CThreadListener{ + private static final ImageIcon closeIcon = IGBUtils.getIcon("x_icon.gif"); + + private static ThreadHandler singleton; + private final Set<CThreadListener> listeners; + private final Set<CThreadWorker> workers; + private final JPopupMenu runningTasks; + private final Set<AbstractButton> popupHandler; + + public static ThreadHandler getThreadHandler(){ + if(singleton == null){ + singleton = new ThreadHandler(); + } + return singleton; + } + + private ThreadHandler(){ + runningTasks = new JPopupMenu(); + runningTasks.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); + listeners= new CopyOnWriteArraySet<CThreadListener>(); + workers = new LinkedHashSet<CThreadWorker>(); + popupHandler = new LinkedHashSet<AbstractButton>(1); + } + + public void execute(Object obj, CThreadWorker worker){ + if(obj == null || worker == null){ + throw new IllegalArgumentException("None of parameters can be null"); + } + worker.addThreadListener(this); + ThreadUtils.getPrimaryExecutor(obj).execute(worker); + } + + public void actionPerformed(ActionEvent ae) { + int size = setCancelPopup(); + if(size == 0 ) + return; + + JFrame frame = Application.getSingleton().getFrame(); + final int x = (int) frame.getAlignmentX(); + final int y = (int) frame.getAlignmentY() + frame.getHeight() - ((size+1) * 29); + runningTasks.show(frame,x,y); + } + + public int setCancelPopup() { + int size = workers.size(); + if(size == 0){ + return 0; + } + + final JPanel outerBox = new JPanel(); + outerBox.setLayout(new GridLayout(size,1)); + outerBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + + for (final CThreadWorker worker : workers) { + final Box box = Box.createHorizontalBox(); + //String string = worker.getMessage().substring(0, Math.min(40, worker.getMessage().length())); + final JLabel taskName = new JLabel(worker.getMessage()); + + final JButton cancelTask = new JButton(closeIcon); + cancelTask.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 0)); + cancelTask.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent ae) { + box.setVisible(false); + if(worker != null && !worker.isCancelled() && !worker.isDone()){ + worker.cancel(true); + } + } + }); + + box.setBorder(BorderFactory.createEtchedBorder()); + box.add(cancelTask); + box.add(Box.createRigidArea(new Dimension(5,25))); + box.add(taskName); + box.add(Box.createRigidArea(new Dimension(5,25))); + outerBox.add(box); + + } + runningTasks.removeAll(); + runningTasks.add(outerBox); + return size; + } + + public void heardThreadEvent(CThreadEvent cte) { + boolean enabled = workers.size() > 0; + CThreadWorker w = (CThreadWorker) cte.getSource(); + if (cte.getState() == CThreadEvent.STARTED) { + workers.add(w); + Application.getSingleton().addNotLockedUpMsg(w.getMessage()); + } else { + workers.remove(w); + Application.getSingleton().removeNotLockedUpMsg(w.getMessage()); + } + + boolean nowEnabled = workers.size() > 0; + if(enabled != nowEnabled){ + for(AbstractButton button : popupHandler){ + button.setEnabled(nowEnabled); + } + } + } + + public void addPopupHandler(AbstractButton button) { + button.addActionListener(this); + button.setEnabled(false); + popupHandler.add(button); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |