diff --git a/src/dorkbox/util/swing/ActiveRenderLoop.java b/src/dorkbox/util/swing/ActiveRenderLoop.java deleted file mode 100644 index 672a853..0000000 --- a/src/dorkbox/util/swing/ActiveRenderLoop.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Toolkit; -import java.util.List; - -import javax.swing.JComponent; - -import dorkbox.util.ActionHandlerLong; -import dorkbox.util.Property; - -/** - * Loop that controls the active rendering process - */ -public -class ActiveRenderLoop implements Runnable { - - @Property - /** - * How many frames per second we want the Swing ActiveRender thread to run at - * - * NOTE: The ActiveRenderLoop replaces the Swing EDT (only for specified JFrames) in order to enable smoother animations. It is also - * important to REMEMBER -- if you add a component to an actively managed JFrame, YOU MUST make sure to call - * {@link JComponent#setIgnoreRepaint(boolean)} otherwise this component will "fight" on the EDT for updates. You can completely - * disable the EDT by calling {@link NullRepaintManager#install()} - */ - public static int TARGET_FPS = 30; - - @SuppressWarnings("WhileLoopReplaceableByForEach") - @Override - public - void run() { - long lastTime = System.nanoTime(); - - // 30 FPS is usually just fine. This isn't a game where we need 60+ FPS. We permit this to be changed though, just in case it is. - final long OPTIMAL_TIME = 1000000000 / TARGET_FPS; - Graphics graphics = null; - - while (SwingActiveRender.hasActiveRenders) { - long now = System.nanoTime(); - long updateDeltaNanos = now - lastTime; - lastTime = now; - - // not synchronized, because we don't care. The worst case, is one frame of animation behind. - for (int i = 0; i < SwingActiveRender.activeRenderEvents.size(); i++) { - ActionHandlerLong actionHandlerLong = SwingActiveRender.activeRenderEvents.get(i); - - //noinspection unchecked - actionHandlerLong.handle(updateDeltaNanos); - } - - // this needs to be synchronized because we don't want to our canvas removed WHILE we are rendering it. - synchronized (SwingActiveRender.activeRenders) { - final List activeRenders = SwingActiveRender.activeRenders; - - for (Component component : activeRenders) { - if (!component.isDisplayable()) { - continue; - } - - // maybe the frame was closed, so we must be in a try/catch issue #11 - try { - graphics = component.getGraphics(); - component.paint(graphics); - } catch (Exception e) { - // the canvas can be closed as well. can get a "java.lang.IllegalStateException: Component must have a valid peer" if - // it's already be closed during the getDrawGraphics call. - e.printStackTrace(); - } finally { - if (graphics != null) { - graphics.dispose(); - } - } - } - } - - // Sync the display on some systems (on Linux, this fixes event queue problems) - Toolkit.getDefaultToolkit() - .sync(); - - try { - // Converted to int before the division, because IDIV is - // 1 order magnitude faster than LDIV (and int's work for us anyways) - // see: http://www.cs.nuim.ie/~jpower/Research/Papers/2008/lambert-qapl08.pdf - // Also, down-casting (long -> int) is not expensive w.r.t IDIV/LDIV - //noinspection NumericCastThatLosesPrecision - final int l = (int) (lastTime - System.nanoTime() + OPTIMAL_TIME); - final int millis = l / 1000000; - if (millis > 1) { - Thread.sleep(millis); - } - else { - // try to keep the CPU from getting slammed. We couldn't match our target FPS, so loop again - Thread.yield(); - } - } catch (InterruptedException ignored) { - } - } - } -} diff --git a/src/dorkbox/util/swing/DefaultMenuItemUI.java b/src/dorkbox/util/swing/DefaultMenuItemUI.java deleted file mode 100644 index 3ae8b43..0000000 --- a/src/dorkbox/util/swing/DefaultMenuItemUI.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; - -import javax.accessibility.Accessible; -import javax.swing.JComponent; -import javax.swing.UIManager; -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.MenuItemUI; - -public -class DefaultMenuItemUI extends MenuItemUI { - private final ComponentUI ui; - - public - DefaultMenuItemUI(final JComponent jComponent) { - this.ui = UIManager.getDefaults() - .getUI(jComponent); - } - - @Override - public - void installUI(final JComponent c) { - ui.installUI(c); - } - - @Override - public - void uninstallUI(final JComponent c) { - ui.uninstallUI(c); - } - - @Override - public - void paint(final Graphics g, final JComponent c) { - ui.paint(g, c); - } - - @Override - public - void update(final Graphics g, final JComponent c) { - ui.update(g, c); - } - - @Override - public - Dimension getPreferredSize(final JComponent c) { - return ui.getPreferredSize(c); - } - - @Override - public - Dimension getMinimumSize(final JComponent c) { - return ui.getMinimumSize(c); - } - - @Override - public - Dimension getMaximumSize(final JComponent c) { - return ui.getMaximumSize(c); - } - - @Override - public - boolean contains(final JComponent c, final int x, final int y) { - return ui.contains(c, x, y); - } - - @Override - public - int getBaseline(final JComponent c, final int width, final int height) { - return ui.getBaseline(c, width, height); - } - - @Override - public - Component.BaselineResizeBehavior getBaselineResizeBehavior(final JComponent c) { - return ui.getBaselineResizeBehavior(c); - } - - @Override - public - int getAccessibleChildrenCount(final JComponent c) { - return ui.getAccessibleChildrenCount(c); - } - - @Override - public - Accessible getAccessibleChild(final JComponent c, final int i) { - return ui.getAccessibleChild(c, i); - } -} diff --git a/src/dorkbox/util/swing/DefaultPopupMenuUI.java b/src/dorkbox/util/swing/DefaultPopupMenuUI.java deleted file mode 100644 index 68e0fbf..0000000 --- a/src/dorkbox/util/swing/DefaultPopupMenuUI.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; - -import javax.accessibility.Accessible; -import javax.swing.JComponent; -import javax.swing.UIManager; -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.PopupMenuUI; - -public -class DefaultPopupMenuUI extends PopupMenuUI { - private final ComponentUI ui; - - public - DefaultPopupMenuUI(final JComponent jComponent) { - this.ui = UIManager.getDefaults() - .getUI(jComponent); - } - - @Override - public - void installUI(final JComponent c) { - ui.installUI(c); - } - - @Override - public - void uninstallUI(final JComponent c) { - ui.uninstallUI(c); - } - - @Override - public - void paint(final Graphics g, final JComponent c) { - ui.paint(g, c); - } - - @Override - public - void update(final Graphics g, final JComponent c) { - ui.update(g, c); - } - - @Override - public - Dimension getPreferredSize(final JComponent c) { - return ui.getPreferredSize(c); - } - - @Override - public - Dimension getMinimumSize(final JComponent c) { - return ui.getMinimumSize(c); - } - - @Override - public - Dimension getMaximumSize(final JComponent c) { - return ui.getMaximumSize(c); - } - - @Override - public - boolean contains(final JComponent c, final int x, final int y) { - return ui.contains(c, x, y); - } - - @Override - public - int getBaseline(final JComponent c, final int width, final int height) { - return ui.getBaseline(c, width, height); - } - - @Override - public - Component.BaselineResizeBehavior getBaselineResizeBehavior(final JComponent c) { - return ui.getBaselineResizeBehavior(c); - } - - @Override - public - int getAccessibleChildrenCount(final JComponent c) { - return ui.getAccessibleChildrenCount(c); - } - - @Override - public - Accessible getAccessibleChild(final JComponent c, final int i) { - return ui.getAccessibleChild(c, i); - } -} diff --git a/src/dorkbox/util/swing/DefaultSeparatorUI.java b/src/dorkbox/util/swing/DefaultSeparatorUI.java deleted file mode 100644 index 6546abf..0000000 --- a/src/dorkbox/util/swing/DefaultSeparatorUI.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; - -import javax.accessibility.Accessible; -import javax.swing.JComponent; -import javax.swing.UIManager; -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.SeparatorUI; - -public -class DefaultSeparatorUI extends SeparatorUI { - private final ComponentUI ui; - - public - DefaultSeparatorUI(final JComponent jComponent) { - this.ui = UIManager.getDefaults() - .getUI(jComponent); - } - - @Override - public - void installUI(final JComponent c) { - ui.installUI(c); - } - - @Override - public - void uninstallUI(final JComponent c) { - ui.uninstallUI(c); - } - - @Override - public - void paint(final Graphics g, final JComponent c) { - ui.paint(g, c); - } - - @Override - public - void update(final Graphics g, final JComponent c) { - ui.update(g, c); - } - - @Override - public - Dimension getPreferredSize(final JComponent c) { - return ui.getPreferredSize(c); - } - - @Override - public - Dimension getMinimumSize(final JComponent c) { - return ui.getMinimumSize(c); - } - - @Override - public - Dimension getMaximumSize(final JComponent c) { - return ui.getMaximumSize(c); - } - - @Override - public - boolean contains(final JComponent c, final int x, final int y) { - return ui.contains(c, x, y); - } - - @Override - public - int getBaseline(final JComponent c, final int width, final int height) { - return ui.getBaseline(c, width, height); - } - - @Override - public - Component.BaselineResizeBehavior getBaselineResizeBehavior(final JComponent c) { - return ui.getBaselineResizeBehavior(c); - } - - @Override - public - int getAccessibleChildrenCount(final JComponent c) { - return ui.getAccessibleChildrenCount(c); - } - - @Override - public - Accessible getAccessibleChild(final JComponent c, final int i) { - return ui.getAccessibleChild(c, i); - } -} diff --git a/src/dorkbox/util/swing/NullRepaintManager.java b/src/dorkbox/util/swing/NullRepaintManager.java deleted file mode 100644 index c5cc6a8..0000000 --- a/src/dorkbox/util/swing/NullRepaintManager.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import javax.swing.JComponent; -import javax.swing.RepaintManager; -import javax.swing.SwingUtilities; - -/** - * The NullRepaintManager is a RepaintManager that doesn't do any repainting. Useful when all of the rendering is done manually by the - * application. - */ -public -class NullRepaintManager extends RepaintManager { - /** - * Installs the NullRepaintManager onto the EDT (WARNING: This disables painting/rendering by the EDT, for the entire JVM) - */ - public static - void install() { - SwingUtilities.invokeLater(new Runnable() { - @Override - public - void run() { - RepaintManager repaintManager = new NullRepaintManager(); - repaintManager.setDoubleBufferingEnabled(false); - RepaintManager.setCurrentManager(repaintManager); - } - }); - } - - public - void addInvalidComponent(JComponent c) { - // do nothing - } - - public - void addDirtyRegion(JComponent c, int x, int y, int w, int h) { - // do nothing - } - - public - void markCompletelyDirty(JComponent c) { - // do nothing - } - - public - void paintDirtyRegions() { - // do nothing - } -} diff --git a/src/dorkbox/util/swing/SwingActiveRender.java b/src/dorkbox/util/swing/SwingActiveRender.java deleted file mode 100644 index 5d0bf8f..0000000 --- a/src/dorkbox/util/swing/SwingActiveRender.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import java.awt.Component; -import java.awt.EventQueue; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.swing.SwingUtilities; - -import dorkbox.util.ActionHandlerLong; - -/** - * Contains all of the appropriate logic to setup and render via "Active" rendering (instead of "Passive" rendering). - * - * This permits us to render components OFF of the EDT - even though there are other frames/components that are ON the EDT. - *
- * Because we still want to react to mouse events, etc on the EDT, we do not completely remove the EDT -- we merely allow us - * to "synchronize" the EDT object to our thread. It's a little bit hacky, but it works beautifully, and permits MUCH nicer animations. - *
- */ -public final -class SwingActiveRender { - private static Thread activeRenderThread = null; - - static final List activeRenders = new ArrayList(); - static final List activeRenderEvents = new CopyOnWriteArrayList(); - - // volatile, so that access triggers thread synchrony, since 1.6. See the Java Language Spec, Chapter 17 - static volatile boolean hasActiveRenders = false; - - private static final Runnable renderLoop = new ActiveRenderLoop(); - - private - SwingActiveRender() { - } - - - /** - * Enables the component to to added to an "Active Render" thread, at a target "Frames-per-second". This is to support smooth, swing-based - * animations. - *

- * This works by removing this object from EDT updates and manually calls paint on the component, updating it on our own thread, but - * still remaining synchronized with the EDT. - * - * @param component the component to add to the ActiveRender thread. - */ - @SuppressWarnings("Duplicates") - public static - void addActiveRender(final Component component) { - // this should be on the EDT - if (!EventQueue.isDispatchThread()) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public - void run() { - addActiveRender(component); - } - }); - return; - } - - component.setIgnoreRepaint(true); - - synchronized (activeRenders) { - if (!hasActiveRenders) { - setupActiveRenderThread(); - } - - hasActiveRenders = true; - activeRenders.add(component); - } - } - - /** - * Removes a component from the ActiveRender queue. This should happen when the component is closed. - * - * @param component the component to remove - */ - public static - void removeActiveRender(final Component component) { - // this should be on the EDT - if (!EventQueue.isDispatchThread()) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public - void run() { - removeActiveRender(component); - } - }); - return; - } - - synchronized (activeRenders) { - activeRenders.remove(component); - - final boolean hadActiveRenders = !activeRenders.isEmpty(); - hasActiveRenders = hadActiveRenders; - - if (!hadActiveRenders) { - activeRenderThread = null; - } - } - - component.setIgnoreRepaint(false); - } - - /** - * Specifies an ActionHandler to be called when the ActiveRender thread starts to render at each tick. - * - * @param handler the handler to add - */ - public static - void addActiveRenderFrameStart(final ActionHandlerLong handler) { - synchronized (activeRenders) { - activeRenderEvents.add(handler); - } - } - - /** - * Potentially SLOW calculation, as it compares each entry in a queue for equality - * - * @param handler this is the handler to check - * - * @return true if this handler already exists in the active render, on-frame-start queue - */ - public static - boolean containsActiveRenderFrameStart(final ActionHandlerLong handler) { - synchronized (activeRenders) { - return activeRenderEvents.contains(handler); - } - } - - /** - * Removes the handler from the on-frame-start queue - * - * @param handler the handler to remove - */ - public static - void removeActiveRenderFrameStart(final ActionHandlerLong handler) { - synchronized (activeRenders) { - activeRenderEvents.remove(handler); - } - } - - /** - * Creates (if necessary) the active-render thread. When there are no active-render targets, this thread will exit - */ - private static - void setupActiveRenderThread() { - if (activeRenderThread != null) { - return; - } - - SynchronizedEventQueue.install(); - - activeRenderThread = new Thread(renderLoop, "AWT-ActiveRender"); - activeRenderThread.setDaemon(true); - activeRenderThread.start(); - } -} diff --git a/src/dorkbox/util/swing/SynchronizedEventQueue.java b/src/dorkbox/util/swing/SynchronizedEventQueue.java deleted file mode 100644 index 2467260..0000000 --- a/src/dorkbox/util/swing/SynchronizedEventQueue.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.swing; - -import java.awt.AWTEvent; -import java.awt.EventQueue; -import java.awt.Toolkit; - -public final -class SynchronizedEventQueue extends EventQueue { - public static final Object MUTEX = new Object(); - - private static final SynchronizedEventQueue instance = new SynchronizedEventQueue(); - private static volatile boolean alreadyInUse = false; - - public static synchronized - void install() { - if (!alreadyInUse) { - // set up the synchronized event queue - EventQueue eventQueue = Toolkit.getDefaultToolkit() - .getSystemEventQueue(); - eventQueue.push(instance); - alreadyInUse = true; - } - } - - /** - * Enforce singleton property. - */ - private - SynchronizedEventQueue() { - } - - protected - void dispatchEvent(AWTEvent aEvent) { - synchronized (MUTEX) { - try { - super.dispatchEvent(aEvent); - } catch (Exception e) { - e.printStackTrace(); - } - } - } -}