libspin-java-1.5/0000755000175000017500000000000011240301753013224 5ustar gregoagregoalibspin-java-1.5/src/0000755000175000017500000000000010603251452014015 5ustar gregoagregoalibspin-java-1.5/src/assembly/0000755000175000017500000000000010603462334015637 5ustar gregoagregoalibspin-java-1.5/src/assembly/all.xml0000644000175000017500000000100310603466632017130 0ustar gregoagregoa all zip lib runtime . license.txt pom.xml src/ libspin-java-1.5/src/test/0000755000175000017500000000000010602562664015005 5ustar gregoagregoalibspin-java-1.5/src/test/java/0000755000175000017500000000000010602562664015726 5ustar gregoagregoalibspin-java-1.5/src/test/java/spin/0000755000175000017500000000000010602562662016675 5ustar gregoagregoalibspin-java-1.5/src/test/java/spin/JDKProxyFactoryTest.java0000644000175000017500000000303710602561074023401 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; import javax.swing.JFrame; import spin.proxy.JDKProxyFactory; /** * Test of JDK proxies. */ public class JDKProxyFactoryTest extends AbstractProxyFactoryTest { protected ProxyFactory getFactory() { return new JDKProxyFactory(); } /** * Test handling of non-accessible interfaces.
* Since Java 1.6 all {@link javax.swing.JComponent}s implement a package * protected interface * javax.swing.TransferHandler.HasGetTransferHandler. * * @see JDKProxyFactory#createProxy(Object, Evaluator) */ public void testNonAccessibleInterface() { getFactory().createProxy(new JFrame() { }, createEvaluator()); } }libspin-java-1.5/src/test/java/spin/AbstractProxyFactoryTest.java0000644000175000017500000000700710602561074024535 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; import junit.framework.TestCase; import spin.Evaluator; import spin.Invocation; import spin.ProxyFactory; /** * Abstract base class for tests of proxy factories. */ public abstract class AbstractProxyFactoryTest extends TestCase { protected abstract ProxyFactory getFactory(); /** * Test running through a proxy. */ public void testRun() { final RunnableBean runnable = new RunnableBean(); Evaluator evaluator = new Evaluator() { public void evaluate(Invocation invocation) throws Throwable { assertEquals(false, runnable.evaluated); assertEquals(false, runnable.run); runnable.evaluated = true; invocation.evaluate(); assertEquals(true, runnable.run); } }; Runnable proxy = (Runnable) getFactory().createProxy(runnable, evaluator); proxy.run(); } /** * Test reflexivity. * * @throws Exception */ public void testReflexive() throws Exception { Runnable runnable = new RunnableBean(); Runnable proxy = (Runnable) getFactory().createProxy(runnable, createEvaluator()); assertTrue("equals() is not reflexive", proxy.equals(proxy)); } /** * Test equality of two proxies of the same bean. * * @throws Exception */ public void testTwoProxiesOfSameBeanAreEqual() throws Exception { Runnable runnable = new RunnableBean(); Runnable proxy1 = (Runnable) getFactory().createProxy(runnable, createEvaluator()); Runnable proxy2 = (Runnable) getFactory().createProxy(runnable, createEvaluator()); assertTrue("two proxies of same bean are not equal", proxy1 .equals(proxy2)); } /** * Test non-equality of two proxies of different beans. * * @throws Exception */ public void testTwoProxiesOfDifferentBeansAreNotEqual() throws Exception { Runnable runnable1 = new RunnableBean(); Runnable runnable2 = new RunnableBean(); Runnable proxy1 = (Runnable) getFactory().createProxy(runnable1, createEvaluator()); Runnable proxy2 = (Runnable) getFactory().createProxy(runnable2, createEvaluator()); assertTrue("two proxies of different beans are equal", !proxy1 .equals(proxy2)); } /** * Runnable mock. */ public static class RunnableBean implements Runnable { /** * Was this runnable evaluated. */ public boolean evaluated = false; /** * Was this runnable run. */ public boolean run = false; public void run() { run = true; } } protected Evaluator createEvaluator() { return new Evaluator() { public void evaluate(Invocation invocation) throws Throwable { invocation.evaluate(); }; }; } }libspin-java-1.5/src/test/java/spin/CGLibProxyFactoryTest.java0000644000175000017500000000213710572560326023716 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; import spin.ProxyFactory; import spin.proxy.CGLibProxyFactory; /** * Test of CGLib proxies. */ public class CGLibProxyFactoryTest extends AbstractProxyFactoryTest { protected ProxyFactory getFactory() { return new CGLibProxyFactory(); } }libspin-java-1.5/src/test/java/spin/off/0000755000175000017500000000000010602562664017451 5ustar gregoagregoalibspin-java-1.5/src/test/java/spin/off/AWTReflectDispatcherTest.java0000644000175000017500000000261710523447304025124 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import javax.swing.SwingUtilities; import junit.framework.TestCase; public class AWTReflectDispatcherTest extends TestCase { public void test() throws Exception { AWTReflectDispatcherFactory factory = new AWTReflectDispatcherFactory(); final Dispatcher dispatcher = factory.createDispatcher(); SwingUtilities.invokeLater(new Runnable() { public void run() { try { dispatcher.start(); } catch (Throwable throwable) { fail(throwable.getMessage()); } } }); Thread.sleep(2000); dispatcher.stop(); } } libspin-java-1.5/src/test/java/spin/off/SpinOffTest.java0000644000175000017500000000463510523447300022517 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import javax.swing.SwingUtilities; import junit.framework.TestCase; import spin.Spin; public class SpinOffTest extends TestCase { private static final int DELAY = 3000; private class Timer { private long start; public Timer() { start = System.currentTimeMillis(); } public long elapsed() { return System.currentTimeMillis() - start; } } public static interface OneIntProperty { int getInt(); } public void testEDTNotBlockedDuringInvocation() throws Exception { class Flag { public boolean flag1, flag2; Throwable exception; } final Flag flag = new Flag(); OneIntProperty target = new OneIntProperty() { public int getInt() { try { Thread.sleep(DELAY); } catch (InterruptedException e) { } return 0; } }; final OneIntProperty proxy = (OneIntProperty) Spin.off(target); SwingUtilities.invokeLater(new Runnable() { public void run() { try { proxy.getInt(); } catch (Throwable t) { flag.exception = t; } finally { flag.flag1 = true; } } }); Timer timer = new Timer(); SwingUtilities.invokeAndWait(new Runnable() { public void run() { flag.flag2 = true; } }); assertTrue("Second runnable took too long: " + timer.elapsed(), timer .elapsed() < DELAY); assertTrue("Second runnable didn't run", flag.flag2); while (!flag.flag1) { if (timer.elapsed() > DELAY * 2) { fail("Original invocation timed out"); } Thread.sleep(10); } assertNull("Unexpected exception in original invocation " + flag.exception, flag.exception); } } libspin-java-1.5/src/site/0000755000175000017500000000000010602562662014770 5ustar gregoagregoalibspin-java-1.5/src/site/xdoc/0000755000175000017500000000000010603041062015710 5ustar gregoagregoalibspin-java-1.5/src/site/xdoc/problem.xml0000644000175000017500000004663110603457436020124 0ustar gregoagregoa Sven Meier Spin your Swing

In this section we take a look at a naive GUI implementation that shows how Swing freezes in case the application programmer doesn't take any special actions against it. We also describe the problem of calls into Swing components triggered by any other thread than the event dispatch thread (EDT).
Swing is not designed for multi threading, so let us first recall the single threading rule of every Swing GUI:

Access to a (visible) Swing component has to occur in the event dispatch thread.

The EDT is responsible to process all GUI related events, e.g. notifying listeners of user input, repainting dirty regions or updated areas. All these events are enqueued and treated sequentially - if one of them takes a long time to be processed, all further events will have to wait.

Throughout the next sections we'll put the code of a Swing GUI component and a non visual bean side by side. The bean encapsulates an extensive calculation that is used by multiple threads. Code run on the EDT is shown in green and code called by any other thread is shown in red.

As you can see in the following code, GUI.java calls the method getValue() on the bean when an action is performed. The EDT is routed from the GUI to the bean. While it is performing its calculations no further swing events can be processed - the GUI freezes.
One of these queued events is the repaint of the label triggered by label.setText("..."). When getValue() returns, the text of the label is changed again before the previous text was painted. So in fact "..." is never seen:

GUI.java

public void actionPerformed(ActionEvent e)
{
  label.setText("...");
  label.setText
(bean.getValue());
}


public void propertyChange(PropertyChangeEvent ev)
{
  label.setText((String)ev.getNewValue());
}
 

BeanImpl.java

public String getValue()
{
  String value;
 
// extensive calculation
 
return value;
}

public void setValue(String value)
{
  this.value = value;
  firePropertyChange
(value);
}

What happens if setValue() is invoked on the bean on another thread. The listeners are notified (the class GUI implements java.beans.PropertyChangeListener and is registered as a listener for changes of the bean), triggering a call to propertyChange() on the GUI. The text of the label is altered on the calling thread, violating the Swing threading rule.

The color distribution gives a hint where to search for problems of this implementation:
Green lines of code in BeanImpl.java result in a GUI freeze, red lines in GUI.java show a violation to the Swing threading rule.

One obvious solution to the problems seen in the previous section is to shift the invocation of getValue() from the EDT to a separate thread. When this method returns we must not propagate the result to a Swing component though. We have to return control to the EDT instead. This can be achieved via SwingUtilities.invokeLater() which will use our Runnable to correctly change the label's text on the EDT:

GUI.java

public void actionPerformed(ActionEvent e)
{
  label.setText("...");
 
new Thread(new Runnable()
  {
    public void run()
    {

      final String value = bean.getValue();
      SwingUtilities.invokeLater
(new Runnable()
      {

        public void run()
        {

          label.setText(value);         
        }
      });
    }
  }}).start();
}

public void propertyChange(final PropertyChangeEvent ev)
{
  SwingUtilities.invokeLater(new Runnable()
  {
    public void run()
    {

      label.setText((String)ev.getNewValue());
    }
  });
}

BeanImpl.java

public String getValue()
{

  String value;
 
// extensive calculation
 
return value;

}













public void setValue(String value)
{

  this.value = value;
  firePropertyChange
(value);

}




 

Now what happens if the bean informs the GUI about a value-change triggered by another thread? In propertyChange() we pass a runnable to the EDT via SwingUtiltites.invokeLater() that can safely alter the label.

Let's take a look at the colors once again: In BeanImpl.java there are only red lines - so we achieved a non freezing GUI. GUI.java has almost all lines in green. Since we restrict changes to Swing components to these green lines we are honouring the Swing threading rule too.
But the red lines in GUI.java make things difficult: The programmer of this class always has to know which thread is stepping through what part of the code - without any visual help of thread-coloring. Any mistake reintroduces the problems mentioned above.

SwingWorker is a utility class that aims to ease the efforts to write a non-freezing GUI. Although not included in the standard Java distribution it is maintained by the Swing team and downloadable at The Swing Connection.

As you can see in the following example a SwingWorker removes some of the visual clutter seen in the previous section. To use it you have to subclass it, placing extensive calculations into method construct(). In finished() you can alter the label because this method is called on the EDT. This is similar to our previous solution but this time the threading is handled by the superclass:

GUI.java

public void actionPerformed(ActionEvent e)
{

  label.setText("...");
 
new SwingWorker()
  {

    public Object construct()
    {

      return bean.getValue();
    }

   
public void finished()
    {

      label.setText((String)getValue());
    }
  }).start();
}

public void propertyChange(final PropertyChangeEvent ev)
{
  SwingUtilities.invokeLater(new Runnable()
  {
    public void run()
    {

      label.setText((String)ev.getNewValue());
    }
  });
}

BeanImpl.java

public String getValue()
{

  String value;
 
// extensive calculation
 
return value;

}











public void setValue(String value)
{

  this.value = value;
  firePropertyChange
(value);

}




 

The SwingWorker offers no support for our notification problem so we stick to our previous solution in propertyChange().

What about the colors?
The situation hasn't really improved. The indentation of code was minimized but we still have red lines in GUI.java. So the problem above isn't resolved yet, we're still seeking a better solution.

libspin-java-1.5/src/site/xdoc/acknowledgement.xml0000644000175000017500000001226410603460402021611 0ustar gregoagregoa Sven Meier Spin your Swing

The Spin project is influenced by the Foxtrot project. Foxtrot is the inventor of the Synchronous Model (Spin has adopted this technique) but uses an API that is similar to SwingWorker. It offers a subset of Spins features - it lacks transparent exception handling and offers no solution for asynchronous callbacks:

GUI.java

public void actionPerformed(ActionEvent e)
{
 
label.setText("...");
  String text =
(String)Worker.post(new Job()
  {
   
public Object run()
    {
     
return bean.getValue();
   
}
  })
;
  label.setText
(text);
}

The following code shows how Foxtrot can be 'simulated' with Spin (if you insist on restricting yourself to only one generic interface named Job or what-ever-you-like):

GUI.java

public void actionPerformed(ActionEvent e)
{
 
label.setText("...");
  String text =
((Job)Spin.off(new Job()
  {
   
public String run()
    {
     
return bean.getValue();
   
}
  }))
.run();
  label.setText
(text);
}

Starting with release 1.4 Spin isn't any longer restricted on using JDK virtual proxies. The creation of proxies is now encapsulated in the interface ProxyFactory.

Spin contains a CGLib specific implementation CGLibProxyFactory that offers the following benefits:

  • improved performance on interception of method invocations
  • no need to to use interfaces for your beans as required by JDK proxies

For this you just have to change the default factory of proxies:

Spin.setDefaultProxyFactory(new CGLibProxyFactory());
libspin-java-1.5/src/site/xdoc/solution.xml0000644000175000017500000003332610603457556020340 0ustar gregoagregoa Sven Meier Spin your Swing

Now let's take a look at the Spin solution. Here's the code:

GUI.java

public void actionPerformed(ActionEvent e)
{

  label.setText("...");
  label.setText
(bean.getValue());

}


public void propertyChange(PropertyChangeEvent ev)
{

  label.setText((String)ev.getNewValue());
}
 

BeanImpl.java

public String getValue()
{

  String value;
 
// extensive calculation
 
return value;

}

public void setValue(String value)
{

  this.value = value;
  firePropertyChange
(value);

}

Hey wait a minute! It's the same code as shown in the previous section Standard Swing. But the colors have changed - GUI.java is completely green and BeanImpl.java is completely red - how can this be?

Spin makes this solution possible - as you can see with no impact on the old code. An invisible layer between these two classes handles all threading issues transparently.
All we have to do is to spin-off the bean from the EDT. For this we wrap the bean in an instance of type Spin. The result can safely be casted to any interface the bean (or one of its superclasses) implements. The best place to do this is before a reference to this bean is passed to a GUI component (why bother the programmer of the GUI with this little detail):

bean = (Bean)Spin.off(bean);

The only restriction here is that the Bean has to be broken into interface and implementation. The GUI components will only use the interface! The following picture shows how Spin connects the GUI and the bean. Calls on the EDT from the GUI to the bean are brokered to other threads invocating the beans functionality: Spin off

The need for an interface isn't really a restriction:

  • It is generally recommended to separate an application in different layers which communicate through well defined interfaces. The GUI of an application is certainly part of another layer than extensive calculations or I/O operations.
  • If you don't want to or are unable to use an interface you can utilize CGLib instead of JDK proxies.

For the notification of changes to the bean we use an inverse technique.
We must spin-over any invocation of a GUI callback-method on another thread to the EDT. This time we wrap the GUI in a Spin instance assuming that the bean allows for an PropertyChangeListener to be added as a callback (this could be any interface like foo.DataChangedListener):

bean.addPropertyChangeListener((PropertyChangeListener)Spin.over(gui);

Spin over

This is all you have to know to get Spin to work in your project. If you're interested in the internals of Spin go on to the next section.

Spin is built on top of virtual proxies and a technique borrowed from the java.awt.Dialog component. While a modal dialog has to wait for user input, the EDT is rerouted to the swing event processing to handle further events.

The following diagram shows how this is used in Spin. Each invocation of a bean's method is intercepted and handled by a SpinOffEvaluator:
getValue() is evaluated asynchronously on another thread (customizable with a Starter) while Swing events are dispatched through a Dispatcher. Once the call to the bean returns the dispatching of events is stopped and the EDT is free to return to the standard event processing: Spin off sequence

For asynchronous notifications from the bean to the GUI we reuse the technique introduced in the previous sections. But this time the call to invokeAndWait() is encapsulated by Spin with a SpinOverEvaluator: Spin over sequence

Please take a look at the full API for details on how to customize Spin.

Although Spin handles threading transparently there are caveats with spin-off that you should be aware of:

Security
For dispatching Spin needs access to AWT internals that are not available in applets or untrusted JavaWebStart applications due to security restrictions. This will hopefully change once AWT offers an official way to dispatch events.
Meanwhile Spin offers alternative solutions which are less performant but also work in a secured environment. Please take a look at DialogDispatcherFactory and InternalOptionPaneDispatcherFactory.
Reference backdoor
If your GUI hands over references to parts of its swing models (e.g. TreeModel, TableModel) in method calls to your bean, these could possibly be altered on another thread than the EDT thus VIOLATING THE SWING SINGLE THREADING RULE.
Bean threadsafety
If your GUI doesn't disable all further actions while an invocation on your bean is being processed, the event dispatching may cause a second concurrent call to the bean. In cases where this is desired the BEAN MUST BE THREADSAFE.
Asynchronous
Whenever your GUI calls a beans method through Spin, further actions should be allowed only if they are related to the current Spin invocation. This includes Cancel functionality and the retrieval of the current state of invocation or intermediate results (e.g. for updating a progress bar or incremental filling of a table).
You're running into problems if you're using Spin for real asynchronous executions. Let me give an example:
File tranfers of an Explorer-like application wich can be arbitrarily started and stopped while others are independently continuing are NOT A RECOMMENDED USAGE for Spin. Nevertheless Spin can be used to spin-over events from the transfers (e.g. completion notification) to the EDT.
Incomplete Event Handling
An event that triggers Spin will not be completely precessed until the return of the Spin invocation.
This might lead to minor visual annoyances, e.g. a JComboBox that does not close its popup or a JButton that stays depressed while Spin is running. But this behaviour could also result in other unexpected behaviours that you should be aware of.
Because of this Swing developers have expressed their concern about Spin and similar techniques, stating that 'Swing is not completely reentrant'.
While this may be true, the same objection could be brought forward against any modal dialog or modal internal frame. If you're using these in your application there is no reason to be afraid of Spin.

Spin is a small library that concentrates on offering a powerful solution to build non-freezing Swing applications. Spin enforces good application design by separating the GUI and non-visual components through interfaces. If it is used wisely in an application framework, the GUI programmers will never have to think about threads again.

Spin comes with several demonstration classes that show how to solve formerly challenging Swing programming problems with ease:

  • spin.demo.SpinOffGUI - shows how to execute extensive calculations without "freeze"
  • spin.demo.SpinOverGUI - demonstrates asynchronous event notification without pain
  • spin.demo.exception.ExceptionGUI - proves the transparent exception handling offered by Spin
  • spin.demo.pogress.PullGUI - shows how to handle visual progress while extensive calculations are executed
  • spin.demo.pogress.PushGUI - uses asynchronous event notification to update a progressbar
  • spin.demo.prompt.CallGUI - explains how to prompt the user between multiple extensive calculations
  • spin.demo.prompt.CallbackGUI - prompts the user for input which is triggered by callbacks from an extensive calculation
  • spin.demo.async.AsyncGUI - starts asynchronous calculations transparently through Spin
  • spin.demo.dispatcher.DispatcherGUI - test different dispatchers

We have successfully used Spin successfully in several projects to wrap all remote communication (RMI) between rich-clients and the application server.

libspin-java-1.5/src/site/xdoc/index.xml0000644000175000017500000000250410603460256017554 0ustar gregoagregoa Sven Meier Spin your Swing
Spin is a transparent threading solution for non-freezing Swing applications.

Swing is the standard component architecture for developing Java desktop applications. Its exhaustive collection of widgets is the foundation for easy development of rich graphical user interfaces (GUI).
Alas every non trivial GUI sooner or later encounters the problem of "freeze". This annoying behaviour is experienced by users every time the application performs extensive calculations or blocks for network or disk I/O.

We will explain the reason for this problem and explore different techniques to prevent Swing GUIs from "freezing". We will present our project named Spin which offers a - to our knowledge - revolutionary new approach. It offers a solution for transparent thread handling with minimal impact on your application code.

libspin-java-1.5/src/site/images.sxi0000644000175000017500000003720210603437744016771 0ustar gregoagregoaPK]X6Xmimetypeapplication/vnd.sun.xml.impressPK]X6Configurations2/statusbar/PK]X6'Configurations2/accelerator/current.xmlPKPK]X6Configurations2/floater/PK]X6Configurations2/popupmenu/PK]X6Configurations2/progressbar/PK]X6Configurations2/menubar/PK]X6Configurations2/toolbar/PK]X6Configurations2/images/Bitmaps/PK]X6 content.xmlɎ!Etv`ډEIP$AR'rKRU\T E͸ݭGmz,䯞8~-zNǟs_އw9 0H:H1M& $m$}1D/i#4(m˽1DFhQY|V0lYO6?.qys-<-pJjl\E O6(o ؓڍ8#88nLãMSkEÕ$`)ܧCəXJF:G;n*IٵIٕ c ͯpEω hYI!snL;;%Sh 'k" &.]' ,xAa5N>]h'l! twVAՄ[lS X r3H|2ZbS~inx%0^]$ zCE"஋+H+V7R hk;qxv“x؀,u҄nB=|C1sb2{/pW?z_6dǟX8P-s֜ J0i)$!&#]rCa=rkccwVqn7y<-jFwr9o0qUI:Hj#WtqUVbG>I$+{;KrCA^%ڞ}MW$_g)J}EzФş^O۰3g Wa7LW==Id;N>23hͷi^-|er{c7o|m@To|}Mo$ 9| 56|(zCLGLߦ<|b^!t0FE1rb%#'o$5l|>e~HC`h2`sp/9^.>WrŌo#f=rTQps+.ZV15kkA=.Q:YwWvzE53AbawkIN 073LPŋ>J-'VN*NH B0B@1 I?,A+A:*hGH,jB9`G}8{#VG[kL~pv#Fj{e],czt$HkIWI݆vY2 $qL![fT:D4H :T:| g>n_. Yj!O{s(5N} %HocK V- zj'YF@ڕlAf}nd ̵ƅ$/zPcojLJj3݆ίZp8[,t ˍZ ]$@/^- M*`,13od{LSD6,feg {9jr}^IC Ey |PҫȺzץ8(gLޥj# )ia㰭YAU?n-jA|"Zm:d-_i Xc(oǹ813loxm7.z*2aos rc XZiU'@umk KS`3/7MiLCe1cz٘>%rU42- $*)eI|% RvK8!k*0]&RbIڈ* K8^L#'L ިO W&%rk*:6lnC!:4-vowR)D0}Dg{-buU0V`FE.mR26tvnk15/0t'3@ {b"QE}ZzN^\љp\A]r YBBl:1.]ӉaiՁ%iɼw R-p#آMg5*KnbMfVߝBߘ&;`pcZrYPΨ(jyɶJ~_zME=ٴ4זSOT<%a&k,R7QP+g z/t Aoݯ0Sw !ݰ4zP>ص]XFoǨlBFɆ朚<3xNtØl.4 'R6}J]ԩ&>8=X?U[V"$+=怗p8K0Ð>Rf 2֠0=*=Ʈ!kRSg`05E3-@+uK5l׳|% ᘱpn"Fs?OCa<. oXN-dkLt;VMZ?||bT*F1𤘝6GI&dX$> d8ݛj!.&IgKD2 'ك|l|`tKdtmږey" ҽ\B9f0^R7PALP+ZH{cpIX,~dBC*C8m+ HhV+68sth%07e$ן3_Z3US:"* i4SiKlW-h:0۝=TzOLRWQ0 9 ?d`l6] bVL]Ϗ:K% ^^ŃXf@Z.&ݛfWU_lZG=$\ 7Al뼏v[P|y+&̀oy9G?r#9\yLgJa,c̖*{g / in5-Zb8)($]b:T'o"a]}}s#HF:7ҹ΍tnsb9!8`C.]k}lw_Qv- ȫ^Uh_mwX.*1.W^9(hy\AY2vHcֽK'O`A +H18 yd2BW}37ݻiM5Ǜ7mmqfܶmmqηm.mQPl|V2 sxSbLl7Ol:D،f$6#HlFb3Yb:~S#^N-~iq ɉ |Gpvu4Ph4C b#G9G8rđ#^8KMƝkP7_ۛ~][=<-捧}i{ڻZTN)@:Ȼ"nG//gҿ]9:IwmYI/տ+'iQ헨j9/^Od Sca5|ᬘůW-BHF~22tfJ #DlC;(2*@fYH|+!:"f/FZ`H?59 s@3ALV9; 4@0@hx\mrH9j皿Irj7/[kk؎@!$1PRj^VsPM#?YV$zIÍ+﷜kr ojxμ>1$k=Q+\5kbWA1fnN*|;S&t54#XitEc])]K^O١EXr>Ur@]\PK| 9PK]X6dOzzmeta.xml OpenOffice.org/2.0$Win32 OpenOffice.org_project/680m5$Build-9073Sven Meier2005-10-15T15:18:502007-03-31T13:02:58de-DE16PT7H18M58SPK]X6Thumbnails/thumbnail.png}eXABDdIMI @bH҈Ht)@!)tʔ!-!5`C>}=wsPz7oSPP҄==U?U4`S1ڼ ujV纓T0X:s%% @ϊM4ødwT?V\+Aaz~Qs $AcFG{SΣ㹀ѡa'?߫VBnaX{JǞ2ISѲe")nH\€TʀL Ȅ'Ⱥ)n0{X6) h/Ly&5P&f5KU&͘=%3nzQT!=bQ\c"kT6iS.IO$ X}B޽׭JA˅]Ԅ%5[b*98.k9{~)̪}L'&,N}xP6;crFhSk5?@K(*{'fٱp# B|OCB E5) GZ*L̅`strB9bS\uB/he'ih5v4O0zrDD m*ca,s!hn:8Y\G{u찪ÕZޓpM\5M\VHHWhzͲQv88X+ r#mX7;f;i5y. 6ZYLCH8SC:%. Q2e:kUr00~pz G82+:pi s@UXgOc3. 4[.<F8{<@JnPR@D'G8Y4a&t}gPR6rՏB&q&kyʎaHudŚq\ S|++BLFn|+6,ӨN]+E*eRbb0u(L:݇/h 3'\_|qzj/N"vE#\[;=}ߖOuK" BXh&~*GG#&瘆me0J/t9V+BDPPZJSZ^=̎vltRPrA֍,L&Dv§M-q㽎oOxQݬ4§W_﹚z)ADn O]f;t@H5f-QYAYYz,e#˦{2gN:HzW8$ =fQ7ȻyxȒx[Ay=79n}($QD(Z٤UTWy9D2#)|>>04q4^aKv&+?/WJϒb1B,rט5M3 w@MV#jMvm̌E7av"ѿ/֋=O[V~4leD`Cb5zx1tNP-8UjIz˝Ҳw\mxT:-cM0$2MĮbJtǼcƎkv7tEGjyPr;zzAԲоXHolƌ]3ա>Kff_;?;ؿe:+~IJ&3"R8^IBţtGv6@yo< H+VbJnn%O2(甏g%n퐾O4߬5_۱AVy/k Pi.5VL hG1%g]>\7gmJ3:^ 2],rJ350̲n5M_Xc0kwO~<5K8J#զ)Rkl+`Bf2H)ES?"ru"O/gԶ|Hc\f/UM#=v60(d2v+Q@F~a*eI)NyOO&\'3f|$Ĩݲ.? [.Sv^D=]" 25V<7 457bskIuw6#4bq0zGy 2\Îx$1X3g$PBF3*ָ닷9c uAKD8>`W*<'闢PMӷ驒]^^u):e(+ 0l .;{<`K1Yvn> #pxUISN`:XGPp  #e 륻^0ǘHhZ]Uc[@Cp@e#ME#&r}|Z`%6zk{>~&8W}M'GpzBiT7l(m5cD$Te\,qðߊ( $'h$k:g&x+8PIRzYI\,q7<`e,=*&Q9I܄Q J _`S-,v~9!0h8SfkHuv^%W.Z gb;3lV6v.WzMz修:T.QR}"ꆣ/Obcќ7} XB,^& e)6M{z掏K5$@tyz8p!QC잦N>\߅Y\lh5]3~]_2xhk#ɻ$E!Qޢ> D.Ii *]&qKbVj&bSVi؈Pq]q< x,gX$Cd[xg%6Rݑis^nޖ5/.`bwfW2_oi8ƈِgB&bv]П%BFH:t*/E, \y9MqC{d 6ɉ`rAOV[e#ܷd[dIha+_3-HŢ ťu㵉L䅜6C]^ߠvzoBϫN 1b^Bce0.rs׳ lWeM5'iŪw _y6Vrgv|d翸KYϟlO8`͙9 3E;Wp]}z@[DK#m-Bҝ5wU-Ac+? >h4@4Ի?(x[PK}-PK]X6META-INF/manifest.xmlo {bLd6=aGl_+ pYdnKAC?::UY% ] UlzJnt?[LWyp%*t4lr=yy&,XTf,ym`>J*Y(Nݜm@_AׇvPT )*ou}h8i-5:jqQ3n'Ȋˀpc8xV!ww$wv񬶾(.jQux DzZPK/3iPK]X6XmimetypePK]X6EConfigurations2/statusbar/PK]X6'}Configurations2/accelerator/current.xmlPK]X6Configurations2/floater/PK]X6 Configurations2/popupmenu/PK]X6BConfigurations2/progressbar/PK]X6|Configurations2/menubar/PK]X6Configurations2/toolbar/PK]X6Configurations2/images/Bitmaps/PK]X6{jϟ %content.xmlPK]X6| 9 styles.xmlPK]X6dOzzmeta.xmlPK]X6 ϡa"Thumbnails/thumbnail.pngPK]X6}- 1settings.xmlPK]X6/3i8META-INF/manifest.xmlPK~:libspin-java-1.5/src/site/resources/0000755000175000017500000000000010602562662017002 5ustar gregoagregoalibspin-java-1.5/src/site/resources/css/0000755000175000017500000000000010602562664017574 5ustar gregoagregoalibspin-java-1.5/src/site/resources/css/site.css0000644000175000017500000000436110603457144021253 0ustar gregoagregoatd.java, td.java-ln {vertical-align:top;} tt.java, tt.java-ln, pre.java, pre.java-ln {line-height:1em; margin-bottom:0em;} td.java-ln { text-align:right; } tt.java-ln, pre.java-ln { color:#888888 } /* Background */ span.java0 { font-size: 10pt; color:#ffffff; } /* Line numbers */ span.java1 { font-size: 10pt; color:#808080; } /* Multi-line comments */ span.java2 { font-size: 10pt; color:#3f7f5f; } /* Single-line comments */ span.java3 { font-size: 10pt; color:#3f7f5f; } /* Keywords */ span.java4 { font-size: 10pt; color:#7f0055; font-weight:bold; } /* Strings */ span.java5 { font-size: 10pt; color:#2a00ff; } /* Character constants */ span.java6 { font-size: 10pt; color:#990000; } /* Numeric constants */ span.java7 { font-size: 10pt; color:#990000; } /* Parenthesis */ span.java8 { font-size: 10pt; color:#000000; } /* Primitive Types */ span.java9 { font-size: 10pt; color:#7f0055; font-weight:bold; } /* Others */ span.java10 { font-size: 10pt; color:#000000; } /* Javadoc keywords */ span.java11 { font-size: 10pt; color:#7f9fbf; } /* Javadoc HTML tags */ span.java12 { font-size: 10pt; color:#7f7f9f; } /* Javadoc links */ span.java13 { font-size: 10pt; color:#3f3fbf; } /* Javadoc others */ span.java14 { font-size: 10pt; color:#3f5fbf; } /* Undefined */ span.java15 { font-size: 10pt; color:#ff6100; } /* Annotation */ span.java16 { font-size: 10pt; color:#646464; } div.java { border: 2px solid #3d95ff; line-height: 100%; } div.left { float: left; width: 48%; } div.right { float: right; width: 48%; } div.clear { clear: both; } h3.java { border: 0px; margin: 0px; background-color: #3d95ff; color: #ffffff; font-weight: normal; font-size: small; } code.java { display: block; overflow: hidden; border-left: 1em solid #ece9d8; line-height: 13px; white-space: nowrap; } span.onEDT { background-color:#c0FFa0; } span.offEDT { background-color:#FFb0c0; } *.centeredImage { text-align:center; margin-top:0px; margin-bottom:0px; padding:0px; display:block; } acronym { border-bottom: 1px dotted black; cursor: help; }libspin-java-1.5/src/site/resources/images/0000755000175000017500000000000010602562664020251 5ustar gregoagregoalibspin-java-1.5/src/site/resources/images/sequencespinover.gif0000644000175000017500000001204510603447704024336 0ustar gregoagregoaGIF89a 0  """"3#&&3 33)D/33D+DD6U;@@U5fFMUUDMf@wRZffRZwK^fww_fUjsmus`zk̍uݙ̀݋̣ݱ!Created with The GIMP! ?, @pH,Ȥrk:ШtJZѥv.x-xͶ/E~oڀs}zk/W*u}NƚХԽlۻظ߂tĤcGu Ȱ‡|6"̟ŋ$N2РG Jqc@grFKB.n觱egB>LrJD5m[%B߀&N=&ԑV\B]ilT¶*շ*~5+s5eS}[; # 5-D,"HR@ xZ?g0I#I0 *EO,/HǓXܻ{7'>Asq T9T m|A@jmVmIGV@.8fk  X`(P`x]$#F`\ucb*8D$/bY qcur$D` yE7 EL@|E~x (@ -aYYXut`јa[Y PTZ)`2T $`$) M2\qB|  s,n($: %Oi[qOa@*xzLPޒŪy@FZFfqeDЁQ+D(ě-0Ys9dDq 9 (2%_B: P8)$[{S3BԪ(@JP Wū*PLa" Y*egt- %`A >-.!OTļB0pX.}4Ք<Ƽkv(c28#[f\ə4˼ 3amn_.-]hJdw$vu}vLWl상gcH ,Иt P5B"ߊt&%FC[[ <;wncn֟,xq~z ft5q6I 2u;^/K D޼WPO /I]T<'1a2l{O]!T+aA6 K݅ `g&6bkSfXU$SrW"!EArV4`e"Y5jR*gD*UQ B5il*,ąP A~ o\/;5Tj$tQOI࢐l(4K C ,X!HBH+$lec/L lYAR"OhVFq͌{kd_jcO>RO@L9p2A:>=1eDxʣSG>)&4&׍j=D_^$kJ,DqGļe* 6c3l<KIH,00Nzt dPF@5Xʧ./*@IcNPT&@z5-JXǫZ2I}նX Rµ+)U+]־#si]zש5%|b)Qev`*PZV fujz h,eO2ъ8-jWֺlgKھV ns ޢko2\. @r:ЍtźnC[n׻KMz?N׽хo#@_(< u}}n_)>ǁ: 2߳$('NwoH L;-3^'azÞ<B0B>G }{b?)?osSYGx/3;??1~E_W!!g~f',y}ƗE'x~Zx.ȀVUEٵO#he߅8ǁ HQ,008f#P^,y6Y85W+)-I`%Qh0I"maÐ7IXtZٕ!LIH7•mJa l) nipـ%OYdoy%㔖PנV@zyًxXWxxe jIن8wjiȋhehjȋkXP9y؊h4٘[陮0IX)։RSɔX )Ǚgɞ8yɩfzɇI)Id ٙiҨz*_)6й0ٝ ꠌdٟ8h)9l8řĉIGYJtiwqAc`QpR: TځT %3q Vo bsʹxqYa9iC)Ig~ }yɣejA}&ğdБŦ&ɩڪ:vmj::yw{):=[3Y*IhGi>@%8Z'av!ez'ڂڂZjꊢ욬kH*ʚX*_ݺګگxZ*ku3Gyj [ K#˱)˯+ -۬豑:"KK$:󪨐AAK^ʗD k{8[CNzZڰX|!HJ[q˲n۵jV]tKvˈxkz;.[{9Vs뮍+l˴ʧf@{J{ȅ5{{}JJ^w5{Y»Kțk̛{[>?KǛͫܛ˼:X~ /h9yk9w: M;uK{`\w (Usy| pk,xQ!#||[ý`@\.9;ˆ: 21;HY?,A0$<ɹkGڸ|ƭ\Lo ǧ(;:Eỡۼ[K[ȊRrn'x *9|L\*BXɣu^ ʙ<ʼWʔɘ$<1òtl|ɪ l"˖,ʚ\dcI ˿|KYbs,|5;l˫<~Ŀͽϩ<,rEΟlFa¬͸ mf͛K Sgs ]iܻҋLk;Ҁ΋βt=i%Ӣܪܹ|{h|@Bͺ{/ll +N'7Ա<,J=<4U)dM|(z3PIY,Tfvxm\S em^ծ6r}؋tZ}Y,*KU]̖];m؎^ 8meׄנ ѭѩXژ 5 Ӭm*\۾҈ۃү0#iۛMڶamQ=mɝ=o}ݥӡUׯ؍GQ֝m}MMYަeitt zѽZN>$^&.A;libspin-java-1.5/src/site/resources/images/sequencespinoff.gif0000644000175000017500000001777010603447670024151 0ustar gregoagregoaGIF89aC0  """"3#&&3 33)D/33D+DD6U;@@U5fFMUUDMf@wRZffRZwK^fww_fUjsmus`zk̍uݙ̀݋̣ݱ!Created with The GIMP! ?,C@pH,Ȥrk:ШtJ.جZnx45n]{Z~-qvv/rQ*wzȆ͊qՕM/ؑk; H>U*\xΛ EF+ ITF'\w''BJ8rg>BQ.mF OS/J*'!6 8_ 8cK,Kѷ*]T16E5n_ uVCE冈y׊}xSmQ&udqG8\o~NĹ3sig]}5M2[H3/ Ri_ӽ{D,""8/@ |xv Q_D`B,P VB`ZEPABDBV/l X2$0BV.&ɋB( ^bv!^OBI4ڈc,: > @7.0XeUg-pppK  ~n @~h#zyp}T$w@^`(oY28G(D$@F`6BUEDdȪZCdh! C R;뮓hҊ,!+h *F|{# q.qAg-1-h:a%PBw"JR uGxt'8{ﵰx,ޔ*%\ )t`-JR psѴ 0 ${* 1R&pb&@a\B y$I'6B }MS`T(V$?$m/qڈM6yǸw3Y@*xz6L 'rvB0Ɏ2Q|(^-(§B ^i}HɃT3 +xW  8 S$OH?ɃF{Aͮ>eeq^]Kȇ{S[4' 8Au*uڢxn){pG@X=)%Z aSf?Vn&J `\4'- Vk uATukNF$Pg 8fQa| C%׹D(L!BG 1f2, ;vtk[t\7NN˅b~ @<_2jR18۷#:mE>8i;K%Lj/!T≞EX~Ē1 ?d NblФaI:a3VwN@T^徠ˉogT8g> +BSa,d.<-եBE=/OR.wҽ8;!k\RE;i_ky/xs}19qK0GF' Wo5Ip=g w/^=T/M4<>;ЏO[Ͼ{>'ů_~՟}?7~=Ͽ8XHx h G8~{~ "8$X&x(v@~/~1(7g䇃ߧǃ=Ȃ@B8DXFxH8>K}MXJPO8!X؇Y\؅^`xdX GyhX}mH}oVxQq(}w}yfHuj}PPh4ĈNO}8 H()Ȉv"X·v񉄰Xx~ȉ舻ȉPHxh8H8Hxh}0ˆ؍Hh荢ȍx1àm'Gg8؉ḏH(xȎIxhY﨑(9=8$)}X )*ɒ X6yH'>)i ɓ)x (|M Ȍȑ39U`lgXx8ٖn9}e@~jvy|EX 9Ie{J W(x9)Wn iY𘘙|ɖc))p9oAY6iɚ󨇟I9sY~Iyɛ։)y 9bZi)g8xGȞy_h29- H􉟹'? s9|zِ|jG٠IؕZY #zxʡ*J~َD 'ٓFy))?Z~6*8ښ"ڤ<)C 깢Vz-).Y:DZW:Bꨥ"$`JIG:q{ʥ! 縌ئY8bљIdj1:ڣ :s|J1`:ڨꉕW *q )sz׊hAYnxgj٦~̙*9 ~Hgz[\i:Re*!vi.j[ H:au^Ҹjɯܚ{ۘ+)ڰ'iXNq|*ȱ0B "; {-;Kک*ߪqc +9xD۱ IZJ+~HۘL˳5Hh9;I:iU˄`KWk%yN'OX(0Hٴ02)x[k, Y(ꚣ{3Ks{ЇmKh!;[p{I9ɸ9) )8Wr{۹;pjYf;h뼝Q7˷k*zR˼<+i2|꛽{۰{K%8_{ "); ̄[̶~8zs Z♾ LJ*;6{(,*ܶh܋);3)īT}8% B8CٗH< &='ؤا٪ yyZ{XJk˫K[jl}؟皠$|z {S 8A9ȭkƋ\g|0 ʁ3[ʯyvʪʫʬ ˯9y™~ ~Tv\K,]ȧ; ʣ؉ɖ|\亪I͉\l,\K̕gÑHz缾̴<[쬍솰F9: J0ܚYJݯcяId,Ҋ̶iqlH̅)]ͮL2ö{8==LͱғA*mN}, f ^x'{ՔHXO=_h=m\N4,NY@fݳ{{4hhkH-UyFۅ`miz|=)}׽cҜ 'ٚjU@pl?C (Iع ۚ=k MQ;uſJy 8nגڇT|;j-E9Aݚ;--Tͦ/ڒ ap ݠ )ܓ(R_iۘߓKэ\uVȸӂP~ $.̺̚ η!.֍R߿L{ܠ-N)]ߤ{}Ë0~J䥚>/=VVۄ-31ǥ:na  q.p>7IN!  snO@腎 «I|ۍDTnvn~nޠ} NTq~0PN.P-Kϣ1N뜞~ľˮn">> nnnNٞګEEN.~~llx={5E>ʞ흎b=c~>.,zCIO/.Fn%Qn林(n,\_~/S#N */nnzPW>`5-C=_|6,{eoz0KB .nHoq;_|* _a{=H_n D.UegG.\_s/XnK㛏Ri41ƶ/:L/OOM/,r*O?F/_?kTkm@UT.MS.D/7->m69Oi0JL01OQpщϏ2srM434s.2rҴ RՓֶe7XPXyQvUYx7zx-[Xmмy󼵺}N^;k_}ٛPS,0GGo Q$H,B DD',x\+ɠ3N8N9̓N>@4bP@ DDtQETH/}arLlϽ3717*K4,M]R/LU@//JTyy07R*sR;pmɓ`r|[OMW$qUӂ V%_6TќVM?n;sYu SV ?N]U6SHնQڍ]w `t8GkEMV|%80x{ ΐ56tWՍa`ug㤽q}͜#訥V7vh=>z˚4gTe)7C^n\1*vMp7,6g;™پ %bmۖ,: û!ЛsQ &y\wo{Uq'߽eݝcsoyYcVQx|E'wٛyYoқ{(ȩObc}zh7.+O~~'<7@Eqփ۴G5%u W@0_$d4"BP2)>L{]W:8LRm];=<DNEtaHH?&2B= b>4ۗNp1Ⲑ -yhDشIEKZV5^#Fı5NOjL }ZX{lc_zغ-&=]G`ݨ)9kSqӠ1eݬdȦ6> 薗<1 E \_rZ-fss]p/΁ NXq/{Xs;DvōMvI#[,wq܎)9׹]NSCeIq:;WLGѓnSWJYֹua؉;libspin-java-1.5/src/site/resources/images/spinoff.gif0000644000175000017500000001053310603447626022407 0ustar gregoagregoaGIF89asM   """""3#&))3&3 33)D/366D3D+DD6U;@DDU@U5fFMUUDRRfMf@wRZ__wffRZwK^fmmww_fUjszzmus`zk̍==uIIVVݙ̀ccݻpp}}݋̣ݱ! ,s֭کߖAA \~\,A*Hć]㭍=ZYOW$CʗZLK8=ټ΀=R9S(0<*eR]M>eŢիVaJH`Y*PgIDTUaj\U˷o_֮4xp(*^ R*DQ.췱4 B^^ͺ5Z bc>}ε֦($|←3PǛ N\zu̝̍WT}ϫ5wuW/EϿ?-7]uh`vtȜsbWZw:j>dr,'}|h 9ȗfRx!ga?`?#E9ahF)e&"X U/.,",u68fx n&YE)gvG$M N)G\Z: ^]~ޗ1Y5i)lZo>לI霧}j$e*lXfJ 8\0J*#~h^*,Ι y,:)VJ붵)<+}NHæ{c"٬y&mnі{-(r+zN (. c﯅TaF缢B,Ơ0ĄZ<,G 渃 [92/S쳍/_; xt4 luAe=(e)|JluStou8\ޭfa2nGD>]nk~W"Q J M./mo1:8xSNyp\097>LHVkr"Nݝ0bX7x3{|Bٗůx"Jv>!O2'sN`be)iMi%r(Ax$ pbo"2#A<.!]c hpIհl`!$>Boj5 pG?zйUiL9!e"S&ejTSR uUng@O! Vg?iLQH2Z8 S \P)<:] dU^,T*6 ٚsJ `4U|80=qPIƳcfZNӳ}'ո - 80<=.B:Pٽ J @a?=jzP\x"*Wkg"od`ErA2nq vP(k[py[~S(w)A;N~,I`+%UDgHɍd5VBPH``B#F쌃fR-O$V#xsV#"@@5@9kSBp`:$̆gci&/%G2(,SRkVlgvh=#But 0kiVw}#ms5Ӭ&(PTÀ7'AXwn&wyϜ$p.(sZq9#yηU(wE%@tK5yПw9;Í)1 m/՚k8,97xo u?W {Um+ /k0rؠ?68:׭c[y{~O򗿾}50'փY5J'|n/~GTkⷿP װÃw  BqG{{cTY6v~ ~heTe#l`yf7 X2g&}}6yp:Orr&vx?%(iw"V%2%8R_2g'{#8,0x6qE&h kPdK᳃Yh pQWUF(Yf"PMsA`6fP{qo}WR.x=7C0F0kVfG+MlBX;PvUx-]XrQ!I5}iz o6p}_OjBqKgQBڥ׸U8+Ai1l~⌵ 5j&5QC%7nb9b!ȌgbIPhECX<BPPep$i ~!(CՄfAi&ejq_eDP_H3u ioexE8v L[ypT~&=X`NPoeHE IԊTvf# VsպZQzئI2(CE ɜt:Ӊ\ "?/($!j.?jD ˬ>*ӉB Q:呯jh2Z$n ׹ll"&k cwNo-*p6(tĒ"gc" /* m$LkIw-/2˭Z\8[RLT*",%7#2;krJ(0OٜvX[]s?9}eyPO;"1r|7NOOل( S,}gkͅv㨷(Wxrf,$17׾睧ysXu⦗2x^y^} ^e4nCsw9$8 `ƺ&Cċ3`Ic{tr?*oԾK~(etwC7Aq Qjԯ7 ?mPQ+JBAȐ6!.b@$` _h`LP HHDp%OlGS39^ҒkG8E0N^#ɡQr> Op 0e>x Y A(g ωL(2ĵx<?! >(5;A~ i A:r1L 9ܙWNPQ3T$ T~Ef5ç `BAQnjgM+ O(`h{<pάf+Ur/J2FdWφ~;:LY#~4hҸ`3JicRsu:A1`\ B+ZdjI;ZU0ɎkĒL;X6,3o]j XQY|@ H F.YI/;*4J!\ɶ?YvbcwbY&K@o}vڰ`z_u(`s16uյ `% 60<<f)6(3^\`APӃ1V~,kC$ u 4@n `A dDf!e+`-tmjM5 PAC1 f&J.0eIz]RĴq ' M ? DYͮ!YD>i%Xߚ‰CLNHjfkhSkJ7|fXͳ=Ur \jhϽnyuh~oQv͒7 c? 5 3Ld0z_JC1g SǶn lN@+ngX5wfRE^x3h{i vj"Mp9]?G}kG! _M.`%:$^~a7d Gsxgs&~p~s]-@"-dw!qP 4~gކ%+?d]%p_:FŃ3gTJ=ΰX\F&}Vu_Mha⁃9ȀRd6%p1adF~F+Q0hwl6zϖP_#rz}3ITmS{gq)Ѓy\,$#6oAX}UyHy(Ez-(?ɉ6YMxv[u[AUEFaSdkGm钕Ld5i+`zV]`gP}jUy􏬱Za9H8.AIuwKa虆N94U.gY%9䚯EX my:͙洜^ :iVj)řݧ޹xZ4٘AfYJ!9WHGfn掊5]7,:R O JLypG~13)ŠH&#* ZU ΄y%" f_gt2ș'W*C'E-i"cT0e 'xtG@BjiAx9H8é⢣ڙN}rZ_ oBgj6ij%Vڞ=d)( 8vy!}JK IעɠBA2A:8dI0v?4FQ>*vC @KȒji}ÄeJJ) 54򣉔ZE FHzmU*j =J思3&m;<(6aH)4ȝ?|RKP.XMi)p fhq+J8*& o$@K!~[)4:`\n2Z;c7uE@b5':/ onCN}j9:p嚵x\ 4z8jHlkRb&s[H;Bt7| 28{w; ۥ%g긒 kVI2K k #{Gۺ+?;H|ߚKq-1+K?/A+";[;libspin-java-1.5/src/site/site.xml0000644000175000017500000000105110603041052016435 0ustar gregoagregoa SourceForge.net http://sourceforge.net/sflogo.php?group_id=3636&type=2 http://sourceforge.net ${reports} libspin-java-1.5/src/main/0000755000175000017500000000000010602562664014752 5ustar gregoagregoalibspin-java-1.5/src/main/java/0000755000175000017500000000000010602562664015673 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/0000755000175000017500000000000010602562664016644 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/Invocation.java0000644000175000017500000001075010602561052021611 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * A single invocation on a Spin proxy handled by {@link Evaluator}s. */ public class Invocation { /** * The object this invocation is evaluated on. */ private Object object; /** * The method to invoce. */ private Method method; /** * The arguments of the method to invoce. */ private Object[] args; /** * Was this invocation evaluated. */ private boolean evaluated; /** * An optional throwable catched in evaluation of this invocation. */ private Throwable throwable; /** * The result of this invocation. */ private Object result; /** * Create an invocation of the given method on the given object with the * given arguments. * * @param object * object to invoke method on * @param method * method to invoke * @param args * arguments for the method invocation */ public Invocation(Object object, Method method, Object[] args) { this.object = object; this.method = method; this.args = args; } /** * Set the object this invocation is evaluated on. * * @param object * object to evaluate on */ public void setObject(Object object) { this.object = object; } /** * Get the object this invocation is evaluated on. * * @return the object this invocation is evaluated on */ public Object getObject() { return object; } /** * Set the method to invoke. * * @param method * method to invoke */ public void setMethod(Method method) { this.method = method; } /** * Get the invoked method. * * @return the invoked method */ public Method getMethod() { return method; } /** * Set the arguments for the invoked method. * * @param args * the arguments for the invoked method */ public void setArguments(Object[] args) { this.args = args; } /** * Get the arguments for the invoked method. * * @return the arguments for the invoked method */ public Object[] getArguments() { return args; } /** * Get the result of evaluation * * @return the result */ public Object getResult() { return result; } /** * Set the result of evaluation * * @param result * the result */ public void setResult(Object result) { this.result = result; } /** * Get the throwable thrown on evaluation. * * @return the throwable */ public Throwable getThrowable() { return throwable; } /** * Set the throwable thrown on evaluation. * * @param throwable * the throwable */ public void setThrowable(Throwable throwable) { this.throwable = throwable; } /** * Evaluate the return value (or a possibly thrown Throwable) * by invoking to method with the arguments on the wrapped object. */ public void evaluate() { if (evaluated) { throw new IllegalStateException("already evaluated"); } try { result = method.invoke(object, args); } catch (InvocationTargetException ex) { this.throwable = ex.getTargetException(); } catch (Throwable throwable) { this.throwable = throwable; } evaluated = true; } /** * Test if this invocation is already evaluated. * * @return true if evaluation has finished */ public boolean isEvaluated() { return evaluated; } /** * Get the result or throwable of this invocation's evaluation. * * @return result result of evaluation * @throws Throwable * throwable of evaluation */ public Object resultOrThrow() throws Throwable { if (throwable != null) { throw throwable; } else { return result; } } }libspin-java-1.5/src/main/java/spin/Evaluator.java0000644000175000017500000000225610602561052021444 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; /** * An evaluator is used to evaluate invocations. * * @see spin.Invocation */ public abstract class Evaluator { /** * Evaluate the given invocation. * * @param invocation * invocation to evaluate * @throws Throwable */ public abstract void evaluate(Invocation invocation) throws Throwable; }libspin-java-1.5/src/main/java/spin/ProxyFactory.java0000644000175000017500000000570410602561052022154 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; import java.lang.reflect.Method; /** * A factory of proxies which intercept invocations, using Evaluators to * evaluate them. * * @see spin.Evaluator */ public abstract class ProxyFactory { /** * The equals method of class object. */ private static final Method equalsMethod; static { try { equalsMethod = Object.class.getMethod("equals", new Class[] { Object.class }); } catch (Exception ex) { throw new Error(ex); } } /** * Create a proxy for the given object that evaluates invocations with the * given evaluator. * * @param object * object to create proxy for * @param evaluator * evaluator to evaluate invocations with * @return new proxy */ public abstract Object createProxy(Object object, Evaluator evaluator); /** * Test if the given object is a proxy created by this factory. * * @param object * object to test * @return true if given object is a Spin proxy, * false otherwise */ public abstract boolean isProxy(Object object); /** * Test if the given proxies of this factory are intercepting the same * object. * * @param proxy1 * first proxy * @param proxy2 * second proxy * @return true if both proxies are intercepting the same object */ protected abstract boolean areProxyEqual(Object proxy1, Object proxy2); /** * Evaluate the given invocation with the given evaluator. * * @param evaluator * evaluator to evaluate with * @param proxy * proxy that intcepted the invocation * @param invocation * the invocation to evaluate * @return result of evaluation * @throws Throwable */ protected Object evaluteInvocation(Evaluator evaluator, Object proxy, Invocation invocation) throws Throwable { if (equalsMethod.equals(invocation.getMethod())) { return new Boolean(isProxy(invocation.getArguments()[0]) && areProxyEqual(proxy, invocation.getArguments()[0])); } else { evaluator.evaluate(invocation); return invocation.resultOrThrow(); } } }libspin-java-1.5/src/main/java/spin/Spin.java0000644000175000017500000001415610602561052020415 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin; import spin.off.SpinOffEvaluator; import spin.over.SpinOverEvaluator; import spin.proxy.JDKProxyFactory; /** *

* Spin offers a transparent threading solution for developing * non-freezing Swing applications. *

*

* Let bean be a reference to a non-visual (possibly * multithreaded) bean implementing the interface Bean whose * methods have to be called by a Swing component. You can avoid any freezing by * using one line of code: * *

 * bean = (Bean) Spin.off(bean);
 * 
* * Now each method call on bean is executed on a separate thread, * while the EDT is continuing to dispatch events. All return values or * exceptions are handled by Spin and transparently returned to the * calling method. *

*

* For calls from other threads than the EDT to your Swing component you can use * the following (being XYListener any interface your component * implements): * *

 *     bean.addXYListener((XYListener)Spin.over(component); 
 * 
* * Now all required updates to your component (and/or its model) are * transparently excuted on the EDT. *

* * @see #off(Object) * @see #over(Object) * @see spin.ProxyFactory * @see spin.off.SpinOffEvaluator * @see spin.over.SpinOverEvaluator */ public class Spin { private static ProxyFactory defaultProxyFactory = new JDKProxyFactory(); private static Evaluator defaultOffEvaluator = new SpinOffEvaluator(); private static Evaluator defaultOverEvaluator = new SpinOverEvaluator(); private Object proxy; /** * Create a Spin wrapper for the given object. * * @param object * object to wrap * @param evaluator * evaluator of invocations on the given object */ public Spin(Object object, Evaluator evaluator) { this(object, defaultProxyFactory, evaluator); } /** * Create a Spin wrapper for the given object. * * @param object * object to wrap * @param proxyFactory * factory for a proxy * @param evaluator * evaluator of invocations on the given object */ public Spin(Object object, ProxyFactory proxyFactory, Evaluator evaluator) { if (object == null) { throw new IllegalArgumentException("object must not be null"); } if (proxyFactory == null) { throw new IllegalArgumentException("proxyFactory must not be null"); } if (evaluator == null) { throw new IllegalArgumentException("evaluator must not be null"); } proxy = proxyFactory.createProxy(object, evaluator); } /** * Get a proxy for the wrapped object.
* The returned object can safely be casted to any interface the wrapped * object implements. * * @return the new proxy */ public Object getProxy() { return proxy; } /** *

* Convenience method to spin-off the given object from Swing.

*

* The returned object can safely be casted to any interface the given * object implements. *

* * @param object * the object to spin-off * @return proxy for the given object * @see #setDefaultProxyFactory(ProxyFactory) * @see #setDefaultOffEvaluator(Evaluator) */ public static Object off(Object object) { return new Spin(object, defaultProxyFactory, defaultOffEvaluator) .getProxy(); } /** * Convenience method to spin-over the given object with Swing.
* The returned object can safely be casted to any interface the given * object implements. * * @param object * the object to spin-over * @return proxy for the given object * @see #setDefaultProxyFactory(ProxyFactory) * @see #setDefaultOverEvaluator(Evaluator) */ public static Object over(Object object) { return new Spin(object, defaultProxyFactory, defaultOverEvaluator) .getProxy(); } /** * Set the default factory of proxies. * * @param factory * proxy factore to use as default */ public static void setDefaultProxyFactory(ProxyFactory factory) { if (factory == null) { throw new IllegalArgumentException("factory must not be null"); } defaultProxyFactory = factory; } /** * Set the default evaluator for spin-off. * * @param evaluator * evaluator to use for spin-off */ public static void setDefaultOffEvaluator(Evaluator evaluator) { if (evaluator == null) { throw new IllegalArgumentException("evaluator must not be null"); } defaultOffEvaluator = evaluator; } /** * Set the default evaluator for spin-over. * * @param evaluator * evaluator for spin-over */ public static void setDefaultOverEvaluator(Evaluator evaluator) { if (evaluator == null) { throw new IllegalArgumentException("evaluator must not be null"); } defaultOverEvaluator = evaluator; } /** * Get the default proxy factory. * * @return the default factory of proxies */ public static ProxyFactory getDefaultProxyFactory() { return defaultProxyFactory; } /** * Get the default evaluator for spin-off. * * @return evaluator for spin-off */ public static Evaluator getDefaultOffEvaluator() { return defaultOffEvaluator; } /** * Get the default evaluator for spin-over. * * @return evaluator for spin-over */ public static Evaluator getDefaultOverEvaluator() { return defaultOverEvaluator; } }libspin-java-1.5/src/main/java/spin/proxy/0000755000175000017500000000000010602562664020025 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/proxy/CGLibProxyFactory.java0000644000175000017500000000625510602561052024200 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.proxy; import java.lang.reflect.Method; import spin.Evaluator; import spin.Invocation; import spin.ProxyFactory; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * A factory of proxies utilizing CGLib. */ public class CGLibProxyFactory extends ProxyFactory { public Object createProxy(Object object, Evaluator evaluator) { return Enhancer.create(object.getClass(), new SpinMethodInterceptor( object, evaluator)); } public boolean isProxy(Object object) { if (object == null) { return false; } if (!(object instanceof Factory)) { return false; } Factory factory = (Factory) object; return (factory.getCallback(0) instanceof SpinMethodInterceptor); } protected boolean areProxyEqual(Object proxy1, Object proxy2) { SpinMethodInterceptor methodInterceptor1 = (SpinMethodInterceptor) ((Factory) proxy1) .getCallback(0); SpinMethodInterceptor methodInterceptor2 = (SpinMethodInterceptor) ((Factory) proxy2) .getCallback(0); return methodInterceptor1.object == methodInterceptor2.object; } /** * Method interceptor for the Spin proxy. */ private class SpinMethodInterceptor implements MethodInterceptor { private Object object; private Evaluator evaluator; /** * Create a new handler of invocations. * * @param object * the object to invoke methods on * @param evaluator * the evaluator of methods */ public SpinMethodInterceptor(Object object, Evaluator evaluator) { this.object = object; this.evaluator = evaluator; } /** * Handle the invocation of a method on the Spin proxy. * * @param proxy * the proxy instance * @param method * the method to invoke * @param args * the arguments for the method * @param methodProxy * non-intercepted proxy for the method * @return the result of the invocation on the wrapped object * @throws Throwable * if the wrapped method throws a Throwable */ public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { return evaluteInvocation(evaluator, proxy, new Invocation( this.object, method, args)); } } }libspin-java-1.5/src/main/java/spin/proxy/JDKProxyFactory.java0000644000175000017500000001036210602561052023662 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.util.HashSet; import java.util.Set; import spin.Evaluator; import spin.Invocation; import spin.ProxyFactory; /** * A factory of proxies utilizing JDK virtual proxies. */ public class JDKProxyFactory extends ProxyFactory { /** * The created proxy will not implement non-public interfaces from different * class loaders since these yield an {@link IllegalAccessError} on * construction of a proxy. */ public Object createProxy(Object object, Evaluator evaluator) { Class clazz = object.getClass(); return Proxy.newProxyInstance(clazz.getClassLoader(), getAccessibleInterfaces(clazz), new SpinInvocationHandler( object, evaluator)); } /** * Utility method to retrieve all accessible interfaces of a class and its * superclasses. * * @param clazz * class to get interfaces for * @return implemented interfaces */ private static Class[] getAccessibleInterfaces(Class clazz) { ClassLoader loader = clazz.getClassLoader(); Set interfaces = new HashSet(); while (clazz != null) { Class[] candidates = clazz.getInterfaces(); for (int c = 0; c < candidates.length; c++) { Class candidate = candidates[c]; if (!Modifier.isPublic(candidate.getModifiers())) { if (candidate.getClassLoader() != loader) { // see note continue; } } interfaces.add(candidate); } clazz = clazz.getSuperclass(); } return (Class[]) interfaces.toArray(new Class[interfaces.size()]); } public boolean isProxy(Object object) { if (object == null) { return false; } if (!Proxy.isProxyClass(object.getClass())) { return false; } return (Proxy.getInvocationHandler(object) instanceof SpinInvocationHandler); } protected boolean areProxyEqual(Object proxy1, Object proxy2) { SpinInvocationHandler handler1 = (SpinInvocationHandler) Proxy .getInvocationHandler(proxy1); SpinInvocationHandler handler2 = (SpinInvocationHandler) Proxy .getInvocationHandler(proxy2); return handler1.object.equals(handler2.object); } /** * Invocation handler for the Spin proxy. */ private class SpinInvocationHandler implements InvocationHandler { private Object object; private Evaluator evaluator; /** * Create a new handler of invocations. * * @param object * the object to invoke methods on * @param evaluator * the evaluator of methods */ public SpinInvocationHandler(Object object, Evaluator evaluator) { this.object = object; this.evaluator = evaluator; } /** * Handle the invocation of a method on the Spin proxy. * * @param proxy * the proxy instance * @param method * the method to invoke * @param args * the arguments for the method * @return the result of the invocation on the wrapped object * @throws Throwable * if the wrapped method throws a Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return evaluteInvocation(evaluator, proxy, new Invocation( this.object, method, args)); } } }libspin-java-1.5/src/main/java/spin/off/0000755000175000017500000000000010602562664017416 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/off/SpinOffEvaluator.java0000644000175000017500000001031510602561052023476 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import javax.swing.SwingUtilities; import spin.Invocation; import spin.Evaluator; /** * An evaluator for spin-off, i.e. all invocations are evaluated on another * thread than the EDT while further events are dispatched. * * @see spin.off.Starter * @see spin.off.DispatcherFactory */ public class SpinOffEvaluator extends Evaluator { /** * Default factory of dispatchers. */ private static DispatcherFactory defaultDispatcherFactory = new AWTReflectDispatcherFactory(); /** * Default starter for asynchronous evaluation. */ private static Starter defaultStarter = new SimpleStarter(); /** * The factory of dispatchers. */ private DispatcherFactory dispatcherFactory; /** * The starter for asynchronous evaluation. */ private Starter starter; /** * Create an evaluator for spin-off using the default dispatcherFactory and * starter. * * @see #setDefaultStarter(Starter) * @see #setDefaultDispatcherFactory(DispatcherFactory) */ public SpinOffEvaluator() { this(defaultDispatcherFactory, defaultStarter); } /** * Create an evaluator for spin-off using the default starter. * * @param dispatcherFactory * factory of dispatchers * @see #setDefaultStarter(Starter) */ public SpinOffEvaluator(DispatcherFactory dispatcherFactory) { this(dispatcherFactory, defaultStarter); } /** * Create an evaluator for spin-off using the default dispatcherFactory. * * @param starter * starter * @see #setDefaultDispatcherFactory(DispatcherFactory) */ public SpinOffEvaluator(Starter starter) { this(defaultDispatcherFactory, starter); } /** * Create an evaluator for spin-off. * * @param dispatcherFactory * factory of dispatchers * @param starter * starter */ public SpinOffEvaluator(DispatcherFactory dispatcherFactory, Starter starter) { this.dispatcherFactory = dispatcherFactory; this.starter = starter; } /** * Spin the given invocation off the EDT. * * @param invocation * invocation to spin-off */ public final void evaluate(final Invocation invocation) throws Throwable { if (SwingUtilities.isEventDispatchThread()) { final Dispatcher dispatcher = dispatcherFactory.createDispatcher(); starter.start(new Runnable() { public void run() { invocation.evaluate(); dispatcher.stop(); } }); dispatcher.start(); if (!invocation.isEvaluated()) { throw new Error("dispatcher stopped prematurely"); } } else { invocation.evaluate(); } } /** * Get the default dispatcher factory. * * @return default factory of dispatchers */ public static DispatcherFactory getDefaultDispatcherFactory() { return defaultDispatcherFactory; } /** * Set the default dispatcher factory. * * @param dispatcherFactory * the factory of dispatchers to use as default */ public static void setDefaultDispatcherFactory( DispatcherFactory dispatcherFactory) { SpinOffEvaluator.defaultDispatcherFactory = dispatcherFactory; } /** * Get the default starter. * * @return default starter */ public static Starter getDefaultStarter() { return defaultStarter; } /** * Set the default starter. * * @param starter * the starter to use as default */ public static void setDefaultStarter(Starter starter) { SpinOffEvaluator.defaultStarter = starter; } }libspin-java-1.5/src/main/java/spin/off/InternalOptionPaneDispatcherFactory.java0000644000175000017500000000654110602561052027365 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import java.awt.Component; import java.awt.KeyboardFocusManager; import java.awt.Window; import javax.swing.JDesktopPane; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JRootPane; import javax.swing.RootPaneContainer; import javax.swing.SwingUtilities; /** * A factory of Dispatchers which uses modal internal * JOptionPanes to dispatch events. * * @see spin.off.SpinOffEvaluator#SpinOffEvaluator(DispatcherFactory) * @see spin.off.SpinOffEvaluator#setDefaultDispatcherFactory(DispatcherFactory) * @see AWTReflectDispatcherFactory */ public class InternalOptionPaneDispatcherFactory implements DispatcherFactory { /** * Create a dispatcher for events. * * @return dispatcher that does the actual dispatching */ public Dispatcher createDispatcher() { return new InternalOptionPaneDispatcher(); } /** * Dispatcher with a modal internal JOptionPane. */ private class InternalOptionPaneDispatcher implements Dispatcher, Runnable { /** * The lable to show in the JOptionPane. */ private JLabel label = new JLabel(); /** * Start the dispatching with a modal internal frame in the * JRootPane of the currently visible * RootPaneContainer. */ public void start() throws Throwable { Window window = KeyboardFocusManager .getCurrentKeyboardFocusManager().getActiveWindow(); while (window != null) { if (window.isVisible() && window instanceof RootPaneContainer) { break; } window = window.getOwner(); } if (window != null) { JRootPane rootPane = ((RootPaneContainer) window).getRootPane(); JDesktopPane desktop = new JDesktopPane(); rootPane.add(desktop); JOptionPane.showInternalConfirmDialog(desktop, label); rootPane.remove(desktop); } else { throw new Error("no visible RootPaneContainer"); } } /** * Stop dispatching. */ public void stop() { SwingUtilities.invokeLater(this); } /** * Called on the EDT to stop the dispatching. Hides the internal frame. */ public void run() { Component component = label; while (!(component instanceof JOptionPane)) { if (component == null) { throw new Error("no parental JOptionPane"); } component = component.getParent(); } JOptionPane optionPane = (JOptionPane) component; optionPane.setValue(null); } } }libspin-java-1.5/src/main/java/spin/off/DialogDispatcherFactory.java0000644000175000017500000000517010602561052025010 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import java.awt.Dialog; import javax.swing.SwingUtilities; /** * Abstract base class for factories that dispatch events with * java.awt.Dialogs. Shows how events can be dispatched with * standard AWT. * * @see spin.off.SpinOffEvaluator#SpinOffEvaluator(DispatcherFactory) * @see spin.off.SpinOffEvaluator#setDefaultDispatcherFactory(DispatcherFactory) * @see AWTReflectDispatcherFactory */ public abstract class DialogDispatcherFactory implements DispatcherFactory { /** * Create a dispatcher. * * @return dispatcher that does the actual dispatching */ public Dispatcher createDispatcher() { return new DialogDispatcher(); } /** * Factory method to implement by subclasses to aquire a dialog. * * @return dialog */ protected abstract Dialog aquireDialog(); /** * Factory method to implement by subclasses to release a dialog. * * @param dialog * the dialog to release */ protected abstract void releaseDialog(Dialog dialog); /** * Dispatcher with Dialog. */ protected class DialogDispatcher implements Dispatcher, Runnable { /** * The dialog used to do the actual dispatching. */ private Dialog dialog; /** * Start the dispatching. * * @throws Exception */ public void start() throws Throwable { dialog = aquireDialog(); dialog.setModal(true); dialog.setVisible(true); } /** * Stop dispatching. */ public void stop() { SwingUtilities.invokeLater(this); } /** * Called on the EDT to stop the dispatching. */ public void run() { dialog.setVisible(false); dialog.dispose(); releaseDialog(dialog); dialog = null; } } } libspin-java-1.5/src/main/java/spin/off/Dispatcher.java0000644000175000017500000000265510602561052022345 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; /** * An dispatcher of AWT events.
* Used by {@link SpinOffEvaluator}s to keep the UI reactive while waiting for * a spin-off to complete. */ public interface Dispatcher { /** * Start dispatching events.
* This method is always called on the EDT. It must not return until * {@link #stop()} is called. * * @throws Throwable * in case of any exceptions while dispatching */ public void start() throws Throwable; /** * Stop dispatching events.
* This method is not called on the EDT. */ public void stop(); }libspin-java-1.5/src/main/java/spin/off/SimpleStarter.java0000644000175000017500000000326610602561052023054 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; /** * Simple implementation of a Starter that creates a new thread * for each invocation of {@link #start(Runnable)}. */ public class SimpleStarter implements Starter { /** * The threadGroup used for all threads. */ private static final ThreadGroup threadGroup = new ThreadGroup("spin"); /** * For autonumbering anonymous threads. */ private static int threadNumber; /** * Get the next thread number. * * @return next thread number */ private static synchronized int nextThreadNumber() { return threadNumber++; } /** * Start a runnable asynchronously. * * @param runnable * runnable to start */ public void start(Runnable runnable) { new Thread(threadGroup, runnable, "Spin-" + nextThreadNumber()).start(); } } libspin-java-1.5/src/main/java/spin/off/DispatcherFactory.java0000644000175000017500000000230310602561052023663 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; /** * A factory of Dispatchers of AWT events. * * @see Dispatcher */ public interface DispatcherFactory { /** * Create a Dispatcher for AWT events.
* This method is always called on the EDT. * * @return dispatcher */ public Dispatcher createDispatcher(); } libspin-java-1.5/src/main/java/spin/off/Starter.java0000644000175000017500000000304210602561052021672 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; /** * A Starter starts Runnables asynchronously - * used by {@link SpinOffEvaluator}s to spin-off non UI computations from the * EDT.
* An implementation of this interface could be a sophisticated thread pool ore * simply use: * *
 * new Thread(runnable).start()
 * 
*/ public interface Starter { /** * Start a Runnable asynchronously.
* This method must return immediately without waiting for the * run() method of the Runnable to complete. * * @param runnable * runnable to start */ public void start(Runnable runnable); } libspin-java-1.5/src/main/java/spin/off/ListenerSpinOver.java0000644000175000017500000000670510602561052023532 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import java.lang.reflect.Method; import java.util.EventListener; import spin.Invocation; import spin.Spin; import spin.Evaluator; /** * An evaluator for spin-off that automatically spins-over all arguments of a * {@link spin.off.SpinOffEvaluator} if their corresponding parameter types are * subinterfaces of java.util.EventListener.
* Use an instance of this class on construction of a Spin object or * install it globally by calling the static method: * *
 * Spin.setDefaultOffEvaluator(new ListenerSpinOver());
 * 
* * @see #isListenerAdditionOrRemoval(java.lang.reflect.Method) * @see #isListener(java.lang.Class) */ public class ListenerSpinOver extends Evaluator { private Evaluator evaluator; /** * Constructor. */ public ListenerSpinOver() { this(Spin.getDefaultOffEvaluator()); } /** * Constructor. * * @param evaluator * the evaluator to wrap */ public ListenerSpinOver(Evaluator evaluator) { this.evaluator = evaluator; } public void evaluate(Invocation invocation) throws Throwable { Method method = invocation.getMethod(); if (isListenerAdditionOrRemoval(method)) { Class[] types = method.getParameterTypes(); Object[] args = invocation.getArguments(); for (int t = 0; t < types.length; t++) { if (isListener(types[t])) { args[t] = spinOver(args[t]); } } } evaluator.evaluate(invocation); } /** * Test if the given method is a listener addition or removal. For this the * methods name must obey the name pattern * (add|remove).*Listener. * * @param method * method to test * @return true if method obeys the name pattern of listener * addition or removal */ protected boolean isListenerAdditionOrRemoval(Method method) { String name = method.getName(); return name.endsWith("Listener") && (name.startsWith("add") || name.startsWith("remove")); } /** * Test if the given class is a listener subinterface. * * @param type * class to test * @return true if the class is an sub-interface of * java.util.EventListener */ protected boolean isListener(Class type) { return type.isInterface() && EventListener.class.isAssignableFrom(type); } /** * Spin-over the given object. * * @param object * object to spin-over * @return Spin proxy */ protected Object spinOver(Object object) { return Spin.over(object); } } libspin-java-1.5/src/main/java/spin/off/AWTReflectDispatcherFactory.java0000644000175000017500000001012410602561052025544 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.off; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.swing.SwingUtilities; /** * A factory of Dispatchers which uses reflection to AWT * internals to dispatch events - used as default by Spin for * spin-off.
* Once Swing offers an official way to start an event pump this class should be * replaced by a less intrusive solution. */ public class AWTReflectDispatcherFactory implements DispatcherFactory { /** * The AWT conditional class. */ private static Class conditionalClass; /** * The pumpMethod of the EDT. */ private static Method pumpMethod; /** * Create a dispatcher for events. * * @return dispatcher that does the actual dispatching */ public Dispatcher createDispatcher() { return new AWTReflectDispatcher(); } /** * Dispatcher with reflection of AWT. */ private class AWTReflectDispatcher implements Dispatcher, InvocationHandler { /** * Flag indicating that dispatching should stop. */ private boolean stopDispatching = false; /** * Start the dispatching. * * @throws Exception */ public void start() throws Throwable { try { Object conditional = Proxy.newProxyInstance(conditionalClass .getClassLoader(), new Class[] { conditionalClass }, this); pumpMethod.invoke(Thread.currentThread(), new Object[] { conditional }); synchronized (this) { // if the EDT refuses to pump events (e.g. because of a // sun.awt.AWTAutoShutdown) // we can do nothing else but wait for stop() to be called while (!stopDispatching) { wait(); } } } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } /** * Stop dispatching. */ public void stop() { synchronized (this) { stopDispatching = true; // notify possibly waiting start() notifyAll(); } // force the event queue to re-evaluate our conditional SwingUtilities.invokeLater(new Runnable() { public void run() { } }); } /** * Invoke evaluate() on the wrapped * Conditional instance - called by the * EventDispatchThread to test if pumping of events should be continued. * * @return true if events still should be continued * pumped, false otherwise */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (stopDispatching) { return Boolean.FALSE; } else { return Boolean.TRUE; } } } /** * Initialize AWT internals.
* Get references to class java.awt.Conditional and method * java.awt.EventDispatchThread.pumpEvents(). */ static { try { conditionalClass = Class.forName("java.awt.Conditional"); pumpMethod = Class.forName("java.awt.EventDispatchThread") .getDeclaredMethod("pumpEvents", new Class[] { conditionalClass }); pumpMethod.setAccessible(true); } catch (Exception ex) { throw new Error(ex.getMessage()); } } } libspin-java-1.5/src/main/java/spin/over/0000755000175000017500000000000010602562664017617 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/over/SpinOverEvaluator.java0000644000175000017500000000546510602561052024112 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.over; import javax.swing.SwingUtilities; import spin.Invocation; import spin.Evaluator; /** * An evaluator for spin-over, i.e. all invocations are evaluated on the EDT. */ public class SpinOverEvaluator extends Evaluator { private static boolean defaultWait = true; private boolean wait; /** * Create an evaluator for spin-over using the default wait setting. * * @see #setDefaultWait(boolean) */ public SpinOverEvaluator() { this(defaultWait); } /** * Create an evaluator for spin-over. * * @param wait * should the invocation wait for the evaluation to complete */ public SpinOverEvaluator(boolean wait) { this.wait = wait; } /** * Spin the given invocation on the EDT. * * @param invocation * invocation to spin-over */ public final void evaluate(final Invocation invocation) throws Throwable { if (SwingUtilities.isEventDispatchThread()) { invocation.evaluate(); } else { Runnable runnable = new Runnable() { public void run() { invocation.evaluate(); } }; if (wait) { SwingUtilities.invokeAndWait(runnable); } else { if (invocation.getMethod().getReturnType() != Void.TYPE) { onInvokeLaterNonVoidReturnType(invocation); } SwingUtilities.invokeLater(runnable); } } } /** * Hook method to handle a non-void return type of a invoked method. * * @param invocation * the invocation * @throws IllegalArgumentException */ protected void onInvokeLaterNonVoidReturnType(Invocation invocation) { throw new RuntimeException("invokeLater with non-void return type"); } /** * Should evaluations wait for the invocations. * * @return true if wait */ public static boolean getDefaultWait() { return defaultWait; } /** * Should evaluations wait for the invocations. * * @param wait * true if wait */ public static void setDefaultWait(boolean wait) { defaultWait = wait; } }libspin-java-1.5/src/main/java/spin/over/CheckingRepaintManager.java0000644000175000017500000000737010602561052025010 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.over; import java.awt.Component; import javax.swing.JComponent; import javax.swing.RepaintManager; import javax.swing.SwingUtilities; /** * A repaintManager that checks bad access - i.e. access from non EDT - to Swing * components. Install with: * *
 * RepaintManager.setCurrentManager(new CheckingRepaintManager());
 * 
* * Based on an idea by Scott Delap (http://www.clientjava.com). * * @see javax.swing.RepaintManager */ public class CheckingRepaintManager extends RepaintManager { /** * Overriden to check EDT rule. */ public synchronized void addInvalidComponent(JComponent component) { checkEDTRule(component); super.addInvalidComponent(component); } /** * Overriden to check EDT rule. */ public synchronized void addDirtyRegion(JComponent component, int x, int y, int w, int h) { checkEDTRule(component); super.addDirtyRegion(component, x, y, w, h); } /** * Check EDT rule on access to the given component. * * @param component * component to be repainted */ protected void checkEDTRule(Component component) { if (violatesEDTRule(component)) { EDTRuleViolation violation = new EDTRuleViolation(component); StackTraceElement[] stackTrace = violation.getStackTrace(); try { for (int e = stackTrace.length - 1; e >= 0; e--) { if (isLiableToEDTRule(stackTrace[e])) { StackTraceElement[] subStackTrace = new StackTraceElement[stackTrace.length - e]; System.arraycopy(stackTrace, e, subStackTrace, 0, subStackTrace.length); violation.setStackTrace(subStackTrace); } } } catch (Exception ex) { // keep stackTrace } indicate(violation); } } /** * Does acces to the given component violate the EDT rule. * * @param component * accessed component * @return true if EDT rule is violated */ protected boolean violatesEDTRule(Component component) { return !SwingUtilities.isEventDispatchThread() && component.isShowing(); } /** * Is the given stackTraceElement liable to the EDT rule. * * @param element * element * @return true if the className of the given element denotes * a subclass of java.awt.Component * @throws Exception * on any problem */ protected boolean isLiableToEDTRule(StackTraceElement element) throws Exception { return Component.class.isAssignableFrom(Class.forName(element .getClassName())); } /** * Indicate a violation of the EDT rule. This default implementation throws * the given exception, subclasses may want to log the exception instead. * * @param violation * violation of EDT rule */ protected void indicate(EDTRuleViolation violation) throws EDTRuleViolation { throw violation; } } libspin-java-1.5/src/main/java/spin/over/EDTRuleViolation.java0000644000175000017500000000267310602561052023611 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.over; import java.awt.Component; /** * Exception signaling a violation of the EDT rule. */ public class EDTRuleViolation extends RuntimeException { private Component component; /** * Create an exception. * * @param component * the component that triggered the violation. */ public EDTRuleViolation(Component component) { this.component = component; } /** * Get the component that triggered the violation. * * @return the violated component */ public Component getComponent() { return component; } } libspin-java-1.5/src/main/java/spin/demo/0000755000175000017500000000000010602562664017570 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/dispatcher/0000755000175000017500000000000010603466216021713 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/dispatcher/DispatcherGUI.java0000644000175000017500000001104510602561076025211 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.dispatcher; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.border.TitledBorder; import spin.Spin; import spin.demo.Bean; import spin.demo.BeanImpl; import spin.off.AWTReflectDispatcherFactory; import spin.off.Dispatcher; import spin.off.DispatcherFactory; import spin.off.InternalOptionPaneDispatcherFactory; import spin.off.SpinOffEvaluator; /** * A demonstration of a GUI using different dispatchers. */ public class DispatcherGUI extends JPanel { private JLabel label = new JLabel("???"); private JButton button = new JButton("Get"); private JPanel dispatcherFactoryPanel = new JPanel(); private ButtonGroup dispatcherFactoryGroup = new ButtonGroup(); private SwitchableDispatcherFactory dispatcherFactory = new SwitchableDispatcherFactory(); private Bean bean; /** * Constructor. * * @param aBean * the bean for this demonstration */ public DispatcherGUI(Bean aBean) { Spin spin = new Spin(aBean, new SpinOffEvaluator(dispatcherFactory)); bean = (Bean) spin.getProxy(); setLayout(new BorderLayout()); add(label, BorderLayout.CENTER); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); add(button, BorderLayout.SOUTH); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { label.setText("..."); button.setEnabled(false); String value = bean.getValue(); label.setText(value); button.setEnabled(true); } }); dispatcherFactoryPanel.setLayout(new GridLayout(0, 1)); dispatcherFactoryPanel .setBorder(new TitledBorder("Choose a dispatcher")); add(dispatcherFactoryPanel, BorderLayout.NORTH); // create a radioButton for each available dispatcher factory Iterator iterator = dispatcherFactory.names(); while (iterator.hasNext()) { final String name = (String) iterator.next(); JRadioButton button = new JRadioButton(name); button.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { dispatcherFactory.setCurrent(name); } }); dispatcherFactoryGroup.add(button); dispatcherFactoryPanel.add(button); button.setSelected(true); } } private class SwitchableDispatcherFactory implements DispatcherFactory { private Map factories = new HashMap(); { factories.put("AWT Reflection", new AWTReflectDispatcherFactory()); factories.put("Concealed Dialog", new ConcealedDialogDispatcherFactory()); factories.put("Revealed Dialog", new RevealedDialogDispatcherFactory()); factories.put("Internal OptionPane", new InternalOptionPaneDispatcherFactory()); } private String current; public Iterator names() { return factories.keySet().iterator(); } public void setCurrent(String name) { this.current = name; } public Dispatcher createDispatcher() { DispatcherFactory dispatcherFactory = (DispatcherFactory) factories .get(current); return dispatcherFactory.createDispatcher(); } } /** * Entrance to this demo. */ public static void main(String[] args) { Bean bean = new BeanImpl(); DispatcherGUI dispatcherGUI = new DispatcherGUI(bean); JFrame frame = new JFrame("Dispatchers"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(dispatcherGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/dispatcher/RevealedDialogDispatcherFactory.java0000644000175000017500000000640610602561100030755 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.dispatcher; import java.awt.Dialog; import java.awt.Frame; import java.awt.KeyboardFocusManager; import java.awt.Window; import javax.swing.JProgressBar; import spin.off.DialogDispatcherFactory; /** * Implementation of a dispatcher which uses dialogs to dispatch events.
* Due to the inability to change the owner of a dialog (after creation) this * class has to create a fresh dialog for each invocation on the bean. This * admittedly inperformant behaviour could be improved by pooling the dialogs on * a per-owner basis (e.g. utilizing a WeakHashMap).
* Subclasse might want to offer cancel functionality, display real progress or * show an animated image (e.g. the famous Netscape icon). * * @see #aquireDialog(Window) */ public class RevealedDialogDispatcherFactory extends DialogDispatcherFactory { /** * Aquire a dialog for the currently active window. */ protected Dialog aquireDialog() { Dialog dialog; Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager() .getActiveWindow(); if (window == null) { throw new Error("no active Window"); } else { dialog = aquireDialog(window); } initDialog(dialog); return dialog; } /** * Aquire a dialog for the given owning window.
* This default implementation always creates a new dialog. * * @param owner * owner to aquire dialog for * @return aquired dialog * @see #createDialog(Window) */ protected Dialog aquireDialog(Window owner) { return createDialog(owner); } /** * Create a dialog for the given owner. * * @param owner * owner of dialog to create * @return created dialog */ protected Dialog createDialog(Window owner) { Dialog dialog; if (owner instanceof Dialog) { dialog = new Dialog((Dialog) owner, "spin", true); } else if (owner instanceof Frame) { dialog = new Dialog((Frame) owner, "spin", true); } else { throw new Error("owner is no dialog or frame"); } dialog.setUndecorated(true); JProgressBar progressBar = new JProgressBar(); progressBar.setIndeterminate(true); dialog.add(progressBar); return dialog; } protected void initDialog(Dialog dialog) { dialog.pack(); dialog.setLocationRelativeTo(dialog.getOwner()); } protected void releaseDialog(Dialog dialog) { dialog.dispose(); } }libspin-java-1.5/src/main/java/spin/demo/dispatcher/ConcealedDialogDispatcherFactory.java0000644000175000017500000000663510602561052031115 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.dispatcher; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Frame; import java.awt.Toolkit; import java.util.ArrayList; import spin.off.DialogDispatcherFactory; /** * Implementation of a dispatcher which uses a pool of modal dialogs to dispatch * events. The dialogs are concealed, i.e. they are located outside of the * visible screen area.
* Note that the Dispatchers created by this class are not * usable for GUIs with Cancel functionality since they will * block user access to all windows of your application during dispatching.
* While this seems to be a major drawback this class nevertheless has its * eligibility: *
    *
  • It shows that Spin does no 'magic' nor any dirty tricks - * every shown Dialog does the same.
  • *
  • If your application really needs a Cancel functionality * you should consider to use a real asynchronous solution as showed in * spin.demo.async.AsyncGUI - please see also the caveat 'asynchronous'.
  • *
*/ public class ConcealedDialogDispatcherFactory extends DialogDispatcherFactory { /** * The shared owner of all created dialogs. */ private static Frame frame = new Frame(); /** * Pool of dialogs. */ private ArrayList dialogPool = new ArrayList(); /** * Aquire a pooled dialog. * * @return dialog */ protected Dialog aquireDialog() { synchronized (dialogPool) { Dialog dialog; if (dialogPool.size() == 0) { dialog = createDialog(); } else { dialog = (Dialog) dialogPool.remove(0); } initDialog(dialog); return dialog; } } /** * Release a pooled dialog. * * @param dialog * dialog to release */ protected void releaseDialog(Dialog dialog) { synchronized (dialogPool) { dialogPool.add(dialog); } } /** * Factory method to create a new dialog. Can be overriden to create a * custom dialog. * * @return created dialog. */ protected Dialog createDialog() { return new Dialog(frame, "spin", true); } /** * Initialize the given dialog.
* This default implementation positions the dialog outside of the visible * screen boundary. * * @param dialog * dialog to initialize */ protected void initDialog(Dialog dialog) { Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); dialog.setLocation(size.width, size.height); } } libspin-java-1.5/src/main/java/spin/demo/exception/0000755000175000017500000000000010602562664021566 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/exception/ExceptionGUI.java0000644000175000017500000000461610602561052024731 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.exception; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import spin.Spin; import spin.proxy.CGLibProxyFactory; /** * A demonstration of a GUI handling an exception. */ public class ExceptionGUI extends JPanel { private JButton button = new JButton("Exception"); private ExceptionBean exceptionBean; /** * Constructor. */ public ExceptionGUI(ExceptionBean aExceptionBean) { this.exceptionBean = aExceptionBean; setLayout(new BorderLayout()); add(button, BorderLayout.CENTER); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { button.setEnabled(false); try { exceptionBean.possiblyThrowException(); } catch (BeanException ex) { JOptionPane.showMessageDialog(ExceptionGUI.this, "Bean threw an exception", "Exception", JOptionPane.ERROR_MESSAGE); } button.setEnabled(true); } }); } /** * Entrance to this demo. */ public static void main(String[] args) { ExceptionBean bean = new ExceptionBean(); Spin spin = new Spin(bean, new CGLibProxyFactory(), Spin .getDefaultOffEvaluator()); ExceptionGUI exceptionGUI = new ExceptionGUI((ExceptionBean) spin .getProxy()); JFrame frame = new JFrame("Exception"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(exceptionGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/exception/ExceptionBean.java0000644000175000017500000000255410603465172025160 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.exception; import spin.demo.Assert; /** * Implementation of a exception throwing bean. */ public class ExceptionBean { /** * Possibly throw an exception. */ public void possiblyThrowException() throws BeanException { Assert.offEDT(); long time = (long) (Math.random() * 5000); try { synchronized (this) { wait(time); } } catch (InterruptedException ex) { // ignore } if (time > 2500) { throw new BeanException(); } } } libspin-java-1.5/src/main/java/spin/demo/exception/BeanException.java0000644000175000017500000000175707735653514025177 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.exception; /** * A checked exception for the bean. */ public class BeanException extends Exception { } libspin-java-1.5/src/main/java/spin/demo/async/0000755000175000017500000000000010602562664020705 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/async/AsyncBean.java0000644000175000017500000000223210602561052023400 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.async; /** * A common interface for an async bean. */ public interface AsyncBean { /** * Add a listener. * * @param listener * listener to add */ public void addListener(AsyncListener listener); /** * Start this bean in an asynchron thread. */ public void start(); } libspin-java-1.5/src/main/java/spin/demo/async/AsyncBeanImpl.java0000644000175000017500000000343410603465172024236 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.async; import java.util.ArrayList; import java.util.List; import spin.demo.Assert; /** * Implementation of an async bean. */ public class AsyncBeanImpl implements AsyncBean, Runnable { private List listeners = new ArrayList(); private int number = 0; /** * Add a listener. * * @param listener * listener to add */ public void addListener(AsyncListener listener) { Assert.offEDT(); listeners.add(listener); } /** * Start this bean in an asynchron thread. */ public void start() { Assert.offEDT(); new Thread(this).start(); } /** * @see Runnable */ public void run() { int number = this.number++; long duration = (long) (Math.random() * 5000); try { synchronized (this) { wait(duration); } } catch (InterruptedException ex) { // ignore } for (int l = 0; l < listeners.size(); l++) { ((AsyncListener) listeners.get(l)).finished(number, duration); } } } libspin-java-1.5/src/main/java/spin/demo/async/AsyncGUI.java0000644000175000017500000000527610603465146023202 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.async; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import spin.Spin; import spin.demo.Assert; import spin.off.ListenerSpinOver; /** * A demonstration of a GUI handling an async bean. Note that this class uses * {@link spin.off.ListenerSpinOver} to automatically spin-over a listener to * async events. */ public class AsyncGUI extends JPanel implements AsyncListener { private JButton button = new JButton("Start"); private JTextArea textArea = new JTextArea(); private AsyncBean asyncBean; /** * Constructor. */ public AsyncGUI(AsyncBean anAsyncBean) { this.asyncBean = anAsyncBean; // ListenerSpinOver will spin-over us automatically asyncBean.addListener(this); setLayout(new BorderLayout()); add(button, BorderLayout.NORTH); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { button.setEnabled(false); asyncBean.start(); button.setEnabled(true); } }); add(new JScrollPane(textArea), BorderLayout.CENTER); } /** * @see AsyncListener */ public void finished(int number, long duration) { Assert.onEDT(); textArea.append("Duration of " + number + " was " + duration + "\n"); } /** * Entrance to this demo. */ public static void main(String[] args) { // Automatically spin-over all listeners Spin.setDefaultOffEvaluator(new ListenerSpinOver()); AsyncBean asyncBean = new AsyncBeanImpl(); AsyncGUI asyncGUI = new AsyncGUI((AsyncBean) Spin.off(asyncBean)); JFrame frame = new JFrame("Async"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(asyncGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/async/AsyncListener.java0000644000175000017500000000226310602561052024324 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.async; import java.util.EventListener; /** * The interface for an listener to ansync bean. */ public interface AsyncListener extends EventListener { /** * Finished. * * @param number * the number * @param duration * the duration */ public void finished(int number, long duration); } libspin-java-1.5/src/main/java/spin/demo/complex/0000755000175000017500000000000010602562664021237 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/complex/FileService.java0000644000175000017500000000602210603465172024277 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; import java.io.File; import java.io.FileFilter; import spin.demo.Assert; /** * Implementation of a file service. */ public class FileService implements DirectoryService { private File root; private FileFilter filter; /** * Constructor. */ public FileService() { this(new File("./")); } /** * Constructor. * * @param root * root of this file service */ public FileService(String root) { this(new File(root)); } /** * Constructor. * * @param root * root of this file service */ public FileService(File root) { this(root, new AllFileFilter()); } /** * Constructor. * * @param root * root of this file service * @param filter * filter of this file service */ public FileService(File root, FileFilter filter) { this.root = root; this.filter = filter; } /** * Get the root directory. * * @return the root directory */ public Directory getRoot() { Assert.offEDT(); return new FileDirectory(root, true); } /** * Get the children of a directory. * * @param directory * directory to get children for * @return children */ public Directory[] getChildren(Directory directory) throws DirectoryServiceException { Assert.offEDT(); File file = ((FileDirectory) directory).file; File[] files = file.listFiles(filter); Directory[] directories = new Directory[files.length]; for (int f = 0; f < files.length; f++) { directories[f] = new FileDirectory(files[f], false); } return directories; } /** * Extension to directory. */ private class FileDirectory extends Directory { private File file; /** * Constructor * * @param file * file represented by this directory * @param root * is this directory the root */ public FileDirectory(File file, boolean root) { super(root ? file.getAbsolutePath() : file.getName(), !file .isDirectory()); this.file = file; } } /** * Filter that accepts all files. */ private static class AllFileFilter implements FileFilter { /** * @see FileFilter */ public boolean accept(File file) { return true; } } } libspin-java-1.5/src/main/java/spin/demo/complex/DirectoryServiceGUI.java0000644000175000017500000001301610602561052025723 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; import java.awt.BorderLayout; import java.awt.Cursor; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeNode; import spin.Spin; /** * A GUI that uses a directory service. */ public class DirectoryServiceGUI extends JPanel { private JTree tree = new JTree(); private JLabel label = new JLabel("", JLabel.RIGHT); private DirectoryService service; private DefaultTreeModel model; /** * Constructor. * * @param service * directory service to use */ public DirectoryServiceGUI(DirectoryService service) { this.service = service; setLayout(new BorderLayout()); add(label, BorderLayout.NORTH); DirectoryServiceNode root = new DirectoryServiceNode(null, service .getRoot()); model = new DefaultTreeModel(root); tree.addTreeWillExpandListener(new Listener()); tree.setModel(model); add(new JScrollPane(tree), BorderLayout.CENTER); } /** * A node in the tree. */ private class DirectoryServiceNode implements TreeNode { private Directory directory; private DirectoryServiceNode parent; private DirectoryServiceNode[] children = null; /** * Constructor. * * @param parent * parent node * @param directory * directory represented by this node */ public DirectoryServiceNode(DirectoryServiceNode parent, Directory directory) { this.parent = parent; this.directory = directory; } /** * String representation. */ public String toString() { return directory.getName(); } /** * Test if children are loaded. */ public boolean childrenLoaded() { return children != null; } /** * Load the children. * * @return true if children are loaded */ public void loadChildren() throws DirectoryServiceException { try { Directory[] directories = service.getChildren(directory); children = new DirectoryServiceNode[directories.length]; for (int d = 0; d < directories.length; d++) { children[d] = new DirectoryServiceNode(this, directories[d]); } } catch (DirectoryServiceException ex) { children = null; throw ex; } } /** * @see TreeNode */ public TreeNode getChildAt(int childIndex) { return children[childIndex]; } /** * @see TreeNode */ public int getChildCount() { if (children == null) { return 0; } return children.length; } /** * @see TreeNode */ public TreeNode getParent() { return parent; } /** * @see TreeNode */ public int getIndex(TreeNode node) { return Arrays.binarySearch(children, node); } /** * @see TreeNode */ public boolean getAllowsChildren() { return !isLeaf(); } /** * @see TreeNode */ public boolean isLeaf() { return directory.isLeaf(); } /** * @see TreeNode */ public Enumeration children() { return Collections.enumeration(Arrays.asList(children)); } } /** * The listener to tree expansion events. * * @see TreeWillExpandListener */ private class Listener implements TreeWillExpandListener { public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { DirectoryServiceNode node = (DirectoryServiceNode) event.getPath() .getLastPathComponent(); if (!node.childrenLoaded()) { try { tree.setCursor(Cursor .getPredefinedCursor(Cursor.WAIT_CURSOR)); tree.setEnabled(false); node.loadChildren(); model.nodeStructureChanged(node); } catch (DirectoryServiceException ex) { JOptionPane.showMessageDialog(DirectoryServiceGUI.this, ex .getMessage()); throw new ExpandVetoException(event); } finally { tree.setEnabled(true); tree.setCursor(Cursor.getDefaultCursor()); } } } public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { } } /** * Entrance to this complex demonstration. */ public static void main(String[] args) { DirectoryService service = new UnreliableService(new LatencyService( new FileService())); DirectoryServiceGUI serviceGUI = new DirectoryServiceGUI( (DirectoryService) Spin.off(service)); JFrame frame = new JFrame("Directory Service"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(serviceGUI); frame.pack(); frame.setVisible(true); } }libspin-java-1.5/src/main/java/spin/demo/complex/DirectoryServiceException.java0000644000175000017500000000211010602561052027226 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; /** * An exception of a directory service. */ public class DirectoryServiceException extends Exception { /** * Constructor. */ public DirectoryServiceException(String message) { super(message); } } libspin-java-1.5/src/main/java/spin/demo/complex/LatencyService.java0000644000175000017500000000327410602561052025016 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; /** * Service that adds a latency to another service. */ public class LatencyService implements DirectoryService { private DirectoryService service; /** * Constructor. */ public LatencyService(DirectoryService service) { this.service = service; } /** * Get the root directory. * * @return the root directory */ public Directory getRoot() { return service.getRoot(); } /** * Get the children of a directory. * * @param directory * directory to get children for * @return children */ public Directory[] getChildren(Directory directory) throws DirectoryServiceException { Directory[] children = service.getChildren(directory); try { // simulate latency Thread.sleep(200 * children.length); } catch (InterruptedException ex) { // ignore } return children; } } libspin-java-1.5/src/main/java/spin/demo/complex/Directory.java0000644000175000017500000000273210602561052024040 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; /** * A directory. */ public class Directory { private String name; private boolean isLeaf; /** * Constructor. * * @param name * name of this directory * @param isLeaf * is this directory a leaf */ public Directory(String name, boolean isLeaf) { this.name = name; this.isLeaf = isLeaf; } /** * Test if directory has children. * * @return true if this directory is a leaf */ public boolean isLeaf() { return isLeaf; } /** * Get the name. * * @return name of this directory */ public String getName() { return name; } } libspin-java-1.5/src/main/java/spin/demo/complex/DirectoryService.java0000644000175000017500000000244110602561052025356 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; /** * A common interface for a directory service. */ public interface DirectoryService { /** * Get the root directory. * * @return the root directory */ public Directory getRoot(); /** * Get the children of a directory. * * @param directory * directory to get children for * @return children */ public Directory[] getChildren(Directory directory) throws DirectoryServiceException; } libspin-java-1.5/src/main/java/spin/demo/complex/UnreliableService.java0000644000175000017500000000324510602561052025477 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.complex; /** * Service that adds a unreliability to another service. */ public class UnreliableService implements DirectoryService { private DirectoryService service; /** * Constructor. */ public UnreliableService(DirectoryService service) { this.service = service; } /** * Get the root directory. * * @return the root directory */ public Directory getRoot() { return service.getRoot(); } /** * Get the children of a directory. * * @param directory * directory to get children for * @return children */ public Directory[] getChildren(Directory directory) throws DirectoryServiceException { // simulate exception if (0.7d - Math.random() < 0) { throw new DirectoryServiceException("Service is unreliable"); } return service.getChildren(directory); } } libspin-java-1.5/src/main/java/spin/demo/progress/0000755000175000017500000000000010602562664021434 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/progress/PullGUI.java0000644000175000017500000000511510602561052023550 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.progress; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.Timer; import spin.Spin; /** * A demonstration of a GUI showing pulled progress. */ public class PullGUI extends JPanel implements ActionListener { private JProgressBar progressBar = new JProgressBar(); private JButton button = new JButton("Start"); private ProgressBean progressBean; /** * Constructor. */ public PullGUI(ProgressBean aProgressBean) { this.progressBean = aProgressBean; setLayout(new BorderLayout()); add(progressBar, BorderLayout.CENTER); add(button, BorderLayout.SOUTH); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { if ("Start".equals(button.getText())) { button.setText("Cancel"); progressBar.setValue(0); Timer timer = new Timer(1000, PullGUI.this); timer.start(); progressBean.start(); timer.stop(); button.setText("Start"); progressBar.setValue(100); } else { progressBean.cancel(); } } }); } /** * @see ActionListener */ public void actionPerformed(ActionEvent ev) { progressBar.setValue((int) (progressBean.getStatus() * 100)); } /** * Entrance to this demo. */ public static void main(String[] args) { ProgressBean progressBean = new ProgressBeanImpl(); PullGUI pullGUI = new PullGUI((ProgressBean) Spin.off(progressBean)); JFrame frame = new JFrame("Pulled progress"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(pullGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/progress/ProgressBean.java0000644000175000017500000000265110602561052024663 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.progress; import java.beans.PropertyChangeListener; /** * A common interface for a progress. */ public interface ProgressBean { /** * Start. */ public void start(); /** * Cancel the progress. */ public void cancel(); /** * Get the current status. * * @return status of progress */ public double getStatus(); /** * Add a listener top property changes. * * @param listener * listener to add */ public void addPropertyChangeListener(PropertyChangeListener listener); } libspin-java-1.5/src/main/java/spin/demo/progress/PushGUI.java0000644000175000017500000000610210603465146023560 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.progress; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import spin.Spin; import spin.demo.Assert; import spin.off.ListenerSpinOver; /** * A demonstration of GUI showing pushed progress. Note that this class uses * {@link spin.off.ListenerSpinOver} to automatically spin-over a listener to * property changes. */ public class PushGUI extends JPanel implements PropertyChangeListener { private JProgressBar progressBar = new JProgressBar(); private JButton button = new JButton("Start"); private ProgressBean progressBean; /** * Constructor. */ public PushGUI(ProgressBean aProgressBean) { this.progressBean = aProgressBean; // ListenerSpinOver will spin-over us automatically progressBean.addPropertyChangeListener(this); setLayout(new BorderLayout()); add(progressBar, BorderLayout.CENTER); add(button, BorderLayout.SOUTH); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { if ("Start".equals(button.getText())) { button.setText("Cancel"); progressBar.setValue(0); progressBean.start(); button.setText("Start"); progressBar.setValue(100); } else { progressBean.cancel(); } } }); } /** * @see java.beans.PropertyChangeListener */ public void propertyChange(PropertyChangeEvent evt) { Assert.onEDT(); if ("value".equals(evt.getPropertyName())) { double status = ((Double) evt.getNewValue()).doubleValue(); progressBar.setValue((int) (status * 100)); } } /** * Entrance to this demo. */ public static void main(String[] args) { // Automatically spin-over all listeners Spin.setDefaultOffEvaluator(new ListenerSpinOver()); ProgressBean progressBean = new ProgressBeanImpl(); PushGUI pushGUI = new PushGUI((ProgressBean) Spin.off(progressBean)); JFrame frame = new JFrame("Pushed progress"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(pushGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/progress/ProgressBeanImpl.java0000644000175000017500000000447710603465172025524 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.progress; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import spin.demo.Assert; /** * Implementation of a progress. */ public class ProgressBeanImpl implements ProgressBean { private PropertyChangeListener listener; private boolean cancelled; private double status; /** * Constructor. */ public ProgressBeanImpl() { } /** * Add a listener to property changes. * * @param listener * listener to add */ public void addPropertyChangeListener(PropertyChangeListener listener) { Assert.offEDT(); this.listener = listener; } /** * Start. */ public void start() { Assert.offEDT(); cancelled = false; status = 0.0d; for (int i = 0; i < 10; i++) { try { synchronized (this) { wait(1000); } Double oldValue = new Double(status); status += 0.1d; Double newValue = new Double(status); if (listener != null) { listener.propertyChange(new PropertyChangeEvent(this, "value", oldValue, newValue)); } } catch (InterruptedException ex) { // ignore } if (cancelled) { break; } } } /** * Cancel the progress. */ public void cancel() { Assert.offEDT(); cancelled = true; } /** * Get the current status. * * @return status of progress */ public double getStatus() { Assert.offEDT(); return status; } } libspin-java-1.5/src/main/java/spin/demo/SpinOffGUI.java0000644000175000017500000000452410602561052022337 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import spin.Spin; /** * A demonstration of a GUI using spin off. */ public class SpinOffGUI extends JApplet { private JLabel label = new JLabel("???"); private JButton button = new JButton("Get"); private Bean bean; /** * Constructor. * * @param aBean * the bean for this demonstration */ public SpinOffGUI(Bean aBean) { bean = aBean; getContentPane().setLayout(new BorderLayout()); getContentPane().add(label, BorderLayout.CENTER); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); getContentPane().add(button, BorderLayout.SOUTH); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { label.setText("..."); button.setEnabled(false); String value = bean.getValue(); label.setText(value); button.setEnabled(true); } }); } /** * Entrance to this demo. * * @param args * the arguments */ public static void main(String[] args) { Bean bean = new BeanImpl(); SpinOffGUI spinOffGUI = new SpinOffGUI((Bean) Spin.off(bean)); JFrame frame = new JFrame("Spin off"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(spinOffGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/SpinOverGUI.java0000644000175000017500000000425210603465146022546 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo; import java.awt.BorderLayout; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import spin.Spin; /** * A demonstration of a GUI using spin over. */ public class SpinOverGUI extends JPanel implements PropertyChangeListener { private JLabel label = new JLabel("???"); /** * Constructor. */ public SpinOverGUI() { setLayout(new BorderLayout()); add(label, BorderLayout.CENTER); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalAlignment(JLabel.CENTER); } /** * @see java.beans.PropertyChangeListener */ public void propertyChange(PropertyChangeEvent evt) { Assert.onEDT(); if ("value".equals(evt.getPropertyName())) { String text = (String) evt.getNewValue(); label.setText(text); } } /** * Entrance to this demo. * * @param args * the arguments */ public static void main(String[] args) { Bean bean = new BeanImpl(); SpinOverGUI spinOverGUI = new SpinOverGUI(); bean.addPropertyChangeListener((PropertyChangeListener) Spin .over(spinOverGUI)); JFrame frame = new JFrame("Spin over"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(spinOverGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/Bean.java0000644000175000017500000000261410602561052021271 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo; import java.beans.PropertyChangeListener; /** * A common interface for a bean. */ public interface Bean { /** * Get the value. * * @return the value */ public String getValue(); /** * Set the value. * * @param value * value to set */ public void setValue(String value); /** * Add a listener to property changes. * * @param listener * listener to add */ public void addPropertyChangeListener(PropertyChangeListener listener); } libspin-java-1.5/src/main/java/spin/demo/prompt/0000755000175000017500000000000010602562664021111 5ustar gregoagregoalibspin-java-1.5/src/main/java/spin/demo/prompt/CallbackGUI.java0000644000175000017500000000470510603465146024021 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.prompt; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import spin.Spin; import spin.demo.Assert; /** * A demonstration of GUI showing a callback prompt. */ public class CallbackGUI extends JPanel implements Prompt { private JButton button = new JButton("Start"); private PromptBean promptBean; /** * Constructor. */ public CallbackGUI(PromptBean aPromptBean) { this.promptBean = aPromptBean; setLayout(new BorderLayout()); add(button, BorderLayout.CENTER); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { button.setEnabled(false); promptBean.process((Prompt) Spin.over(CallbackGUI.this)); button.setEnabled(true); } }); } /** * Prompt. * * @param value * the value to prompt * @return true or false */ public boolean prompt(String value) { Assert.onEDT(); return JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog( CallbackGUI.this, value, "Prompt", JOptionPane.YES_NO_OPTION); } /** * Entrance to this demo. */ public static void main(String[] args) { PromptBean promptBean = new PromptBeanImpl(); CallbackGUI callbackGUI = new CallbackGUI((PromptBean) Spin .off(promptBean)); JFrame frame = new JFrame("Callback prompt"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(callbackGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/prompt/Prompt.java0000644000175000017500000000221310602561052023221 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.prompt; /** * A common interface for a prompt. */ public interface Prompt { /** * Prompt. * * @param value * the value to prompt * @return true or false */ public boolean prompt(String value); } libspin-java-1.5/src/main/java/spin/demo/prompt/CallGUI.java0000644000175000017500000000441210602561052023163 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.prompt; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import spin.Spin; /** * A demonstration of a GUI showing a call prompt. */ public class CallGUI extends JPanel { private JButton button = new JButton("Start"); private PromptBean promptBean; /** * Constructor. */ public CallGUI(PromptBean aPromptBean) { this.promptBean = aPromptBean; setLayout(new BorderLayout()); add(button, BorderLayout.CENTER); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { button.setEnabled(false); for (int i = promptBean.size() - 1; i >= 0; i--) { String value = promptBean.get(i); if (JOptionPane.YES_OPTION == JOptionPane .showConfirmDialog(CallGUI.this, value, "Prompt", JOptionPane.YES_NO_OPTION)) { promptBean.process(i); } } button.setEnabled(true); } }); } /** * Entrance to this demo. */ public static void main(String[] args) { PromptBean promptBean = new PromptBeanImpl(); CallGUI callGUI = new CallGUI((PromptBean) Spin.off(promptBean)); JFrame frame = new JFrame("Call prompt"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(callGUI); frame.pack(); frame.setVisible(true); } } libspin-java-1.5/src/main/java/spin/demo/prompt/PromptBean.java0000644000175000017500000000265110602561052024015 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.prompt; /** * A common interface for a prompt. */ public interface PromptBean { /** * Size. * * @return the size */ public int size(); /** * Get a value. * * @param index * index of value */ public String get(int index); /** * Process. * * @param index * index of value to process */ public void process(int index); /** * Process. * * @param prompt * the prompt to use for processing */ public void process(Prompt prompt); } libspin-java-1.5/src/main/java/spin/demo/prompt/PromptBeanImpl.java0000644000175000017500000000445610603465172024653 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo.prompt; import java.util.ArrayList; import java.util.List; import spin.demo.Assert; /** * Implementation of a prompt. */ public class PromptBeanImpl implements PromptBean { private List values = new ArrayList(); /** * Constructor. */ public PromptBeanImpl() { values.add("value1"); values.add("value2"); values.add("value3"); values.add("value4"); values.add("value5"); values.add("value6"); } /** * Size. * * @return the size */ public int size() { Assert.offEDT(); return values.size(); } /** * Get a value. * * @param index * index of value */ public String get(int index) { Assert.offEDT(); return (String) values.get(index); } /** * Process. * * @param index * index of value to process */ public void process(int index) { Assert.offEDT(); try { synchronized (this) { wait(2000); } } catch (InterruptedException ex) { // ignore } } /** * Process. * * @param prompt * the prompt to use */ public void process(Prompt prompt) { Assert.offEDT(); for (int i = values.size() - 1; i >= 0; i--) { String value = (String) values.get(i); if (prompt.prompt(value)) { try { synchronized (this) { wait(2000); } } catch (InterruptedException ex) { // ignore } } } } } libspin-java-1.5/src/main/java/spin/demo/Assert.java0000644000175000017500000000266210603465216021676 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo; import javax.swing.SwingUtilities; /** * Utility class to assert correct thread handling. */ public class Assert { /** * No instance. */ private Assert() { } /** * Must be executed on the EDT. */ public static void onEDT() { if (!SwingUtilities.isEventDispatchThread()) { throw new Error("assertion failed: on EDT"); } } /** * Must be executed off the EDT. */ public static void offEDT() { if (SwingUtilities.isEventDispatchThread()) { throw new Error("assertion failed: off EDT"); } } } libspin-java-1.5/src/main/java/spin/demo/BeanImpl.java0000644000175000017500000000451310603465172022122 0ustar gregoagregoa/** * Spin - transparent threading solution for non-freezing Swing applications. * Copyright (C) 2002 Sven Meier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package spin.demo; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Date; /** * Implementation of a bean. */ public class BeanImpl implements Bean { private PropertyChangeListener listener; private String value = new Date().toString(); /** * Constructor. */ public BeanImpl() { // alter continuously new Thread(new Runnable() { public void run() { try { while (true) { Thread.sleep(1000); setValue(new java.util.Date().toString()); } } catch (InterruptedException ex) { // ignore } } }).start(); } /** * Add a listener to property changes. * * @param listener * listener to add */ public void addPropertyChangeListener(PropertyChangeListener listener) { Assert.offEDT(); this.listener = listener; } /** * Get the value. * * @return the value */ public String getValue() { Assert.offEDT(); try { synchronized (this) { wait(5000); } } catch (InterruptedException ex) { // ignore } return value; } /** * Set the value. * * @param value * value to set */ public void setValue(String value) { String oldValue = this.value; this.value = value; String newValue = this.value; if (listener != null) { listener.propertyChange(new PropertyChangeEvent(this, "value", oldValue, newValue)); } } } libspin-java-1.5/license.txt0000644000175000017500000006447210121407220015415 0ustar gregoagregoa GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libspin-java-1.5/pom.xml0000644000175000017500000001040010603262742014542 0ustar gregoagregoa 4.0.0 spin spin jar 1.5 Spin http://spin.sourceforge.net Transparent threading solution for non-freezing Swing applications. GNU Lesser General Public License http://www.gnu.org/copyleft/lesser.html repo Sourceforge http://sourceforge.net/tracker?group_id=3636 svenmeier Sven Meier svenmeier@users.sourceforge.net Project Manager Architect Developer spin-developer spin-developer-request@lists.sourceforge.net?subject=subscribe mailto:spin-developer-request@lists.sourceforge.net?subject=unsubscribe spin-developer@lists.sourceforge.net http://sourceforge.net/mailarchive/forum.php?forum_name=spin-developer scm:pserver:anonymous@spin.cvs.sourceforge.net:/cvsroot/spin scm:extssh:spin.cvs.sourceforge.net:/cvsroot/spin http://spin.cvs.sourceforge.net/spin/ junit junit 3.8.1 test cglib cglib-nodep 2.1_3 true org.apache.maven.plugins maven-project-info-reports-plugin dependencies project-team mailing-list issue-tracking license scm maven-javadoc-plugin maven-surefire-plugin false src/main/java **/* **/*.java false src/test/java **/* **/*.java maven-compiler-plugin 1.4 1.4 maven-assembly-plugin src/assembly/all.xml