Синглтоны - это зло, что вы ожидаете? ;)
Возможно, наиболее полный подход заключается в загрузке основной части апплета в другой загрузчик классов (используйте java.net.URLClassLoader.newInstance). Затем используйте WeakHashMap, чтобы связать загрузчик классов с апплетом. Если бы вы могли разбить большую часть кода на общий загрузчик классов (как родительский элемент для каждого загрузчика классов для каждого апплета) и на обычную кодовую базу апплета, это было бы быстрее, но больше работало.
Другие хаки:
Если у вас есть доступ к любому компоненту, вы можете повторно использовать Component.getParent или SwingUtilities.getRoot.
Если вы находитесь в потоке экземпляра для каждого апплета, вы можете настроить ThreadLocal.
Из EDT вы можете прочитать текущее событие из очереди (java.awt.EventQueue.getCurrentEvent ()) и, возможно, найти компонент из этого. Либо отправьте EventQueue с переопределенным методом dispatchEvent.