ActiveRenderLoop (for Swing) now accepts Window (instead of just JFrame)
This commit is contained in:
parent
a1d3b672b0
commit
88312df832
|
@ -17,10 +17,10 @@ package dorkbox.util.swing;
|
||||||
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Window;
|
||||||
import java.awt.image.BufferStrategy;
|
import java.awt.image.BufferStrategy;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JFrame;
|
|
||||||
|
|
||||||
import dorkbox.util.ActionHandlerLong;
|
import dorkbox.util.ActionHandlerLong;
|
||||||
import dorkbox.util.Property;
|
import dorkbox.util.Property;
|
||||||
|
@ -68,15 +68,15 @@ class ActiveRenderLoop implements Runnable {
|
||||||
// this needs to be synchronized because we don't want to our frame removed WHILE we are rendering it.
|
// this needs to be synchronized because we don't want to our frame removed WHILE we are rendering it.
|
||||||
synchronized (SwingActiveRender.activeRenders) {
|
synchronized (SwingActiveRender.activeRenders) {
|
||||||
for (int i = 0; i < SwingActiveRender.activeRenders.size(); i++) {
|
for (int i = 0; i < SwingActiveRender.activeRenders.size(); i++) {
|
||||||
JFrame jFrame = SwingActiveRender.activeRenders.get(i);
|
Window window = SwingActiveRender.activeRenders.get(i);
|
||||||
|
|
||||||
final BufferStrategy buffer = jFrame.getBufferStrategy();
|
final BufferStrategy buffer = window.getBufferStrategy();
|
||||||
|
|
||||||
// maybe the frame was closed
|
// maybe the frame was closed
|
||||||
if (buffer != null) {
|
if (buffer != null) {
|
||||||
try {
|
try {
|
||||||
graphics = buffer.getDrawGraphics();
|
graphics = buffer.getDrawGraphics();
|
||||||
jFrame.paint(graphics);
|
window.paint(graphics);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -17,6 +17,7 @@ package dorkbox.util.swing;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Window;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -25,24 +26,23 @@ import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JFrame;
|
|
||||||
|
|
||||||
import dorkbox.util.ActionHandlerLong;
|
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
|
* Contains all of the appropriate logic to setup and render via "Active" rendering (instead of "Passive" rendering). This permits us to
|
||||||
* render JFrames (and their contents), OFF of the EDT - even though there are other frames/components that are ON the EDT. <br> Because we
|
* render Windows (and their contents), OFF of the EDT - even though there are other frames/components that are ON the EDT. <br> 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
|
* 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. <br>
|
* object to our thread. It's a little bit hacky, but it works beautifully, and permits MUCH nicer animations. <br>
|
||||||
* <p/>
|
* <p/>
|
||||||
* <b>It is also important to REMEMBER -- if you add a component to an actively managed JFrame, YOU MUST make sure to call {@link
|
* <b>It is also important to REMEMBER -- if you add a component to an actively managed Window, YOU MUST make sure to call {@link
|
||||||
* JComponent#setIgnoreRepaint(boolean)} otherwise this component will "fight" on the EDT for updates. </b>
|
* JComponent#setIgnoreRepaint(boolean)} otherwise this component will "fight" on the EDT for updates. </b>
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
class SwingActiveRender {
|
class SwingActiveRender {
|
||||||
private static Thread activeRenderThread = null;
|
private static Thread activeRenderThread = null;
|
||||||
|
|
||||||
static final List<JFrame> activeRenders = new ArrayList<JFrame>();
|
static final List<Window> activeRenders = new ArrayList<Window>();
|
||||||
static final List<ActionHandlerLong> activeRenderEvents = new CopyOnWriteArrayList<ActionHandlerLong>();
|
static final List<ActionHandlerLong> activeRenderEvents = new CopyOnWriteArrayList<ActionHandlerLong>();
|
||||||
|
|
||||||
// volatile, so that access triggers thread synchrony, since 1.6. See the Java Language Spec, Chapter 17
|
// volatile, so that access triggers thread synchrony, since 1.6. See the Java Language Spec, Chapter 17
|
||||||
|
@ -56,25 +56,25 @@ class SwingActiveRender {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the jFrame to to added to an "Active Render" thread, at a target "Frames-per-second". This is to support smooth, swing-based
|
* Enables the window to to added to an "Active Render" thread, at a target "Frames-per-second". This is to support smooth, swing-based
|
||||||
* animations. <br> This works by removing this object from EDT updates, and instead manually calls paint(g) on the jFrame, updating it
|
* animations. <br> This works by removing this object from EDT updates, and instead manually calls paint(g) on the window, updating it
|
||||||
* on our own thread.
|
* on our own thread.
|
||||||
*
|
*
|
||||||
* @param jFrame the jFrame to add to the ActiveRender thread.
|
* @param window the window to add to the ActiveRender thread.
|
||||||
*/
|
*/
|
||||||
public static
|
public static
|
||||||
void addActiveRender(final JFrame jFrame) {
|
void addActiveRender(final Window window) {
|
||||||
// this should be on the EDT
|
// this should be on the EDT
|
||||||
if (!EventQueue.isDispatchThread()) {
|
if (!EventQueue.isDispatchThread()) {
|
||||||
throw new RuntimeException("adding a swing JFrame to be actively rendered must be done on the EDT.");
|
throw new RuntimeException("adding a swing Window to be actively rendered must be done on the EDT.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup double-buffering, so we can properly use Active-Rendering, so the animations will be smooth
|
// setup double-buffering, so we can properly use Active-Rendering, so the animations will be smooth
|
||||||
jFrame.createBufferStrategy(2);
|
window.createBufferStrategy(2);
|
||||||
|
|
||||||
// have to specify ALL children in jFrame to ignore EDT paint requests
|
// have to specify ALL children in Window to ignore EDT paint requests
|
||||||
Deque<Component> components = new ArrayDeque<Component>(8);
|
Deque<Component> components = new ArrayDeque<Component>(8);
|
||||||
components.add(jFrame);
|
components.add(window);
|
||||||
|
|
||||||
Component[] c;
|
Component[] c;
|
||||||
Component pop;
|
Component pop;
|
||||||
|
@ -93,7 +93,7 @@ class SwingActiveRender {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasActiveRenders = true;
|
hasActiveRenders = true;
|
||||||
activeRenders.add(jFrame);
|
activeRenders.add(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,14 +137,14 @@ class SwingActiveRender {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a jFrame from the ActiveRender queue. This should happen when the jFrame is closed.
|
* Removes a window from the ActiveRender queue. This should happen when the window is closed.
|
||||||
*
|
*
|
||||||
* @param jFrame the jFrame to remove
|
* @param window the window to remove
|
||||||
*/
|
*/
|
||||||
public static
|
public static
|
||||||
void removeActiveRender(final JFrame jFrame) {
|
void removeActiveRender(final Window window) {
|
||||||
synchronized (activeRenders) {
|
synchronized (activeRenders) {
|
||||||
activeRenders.remove(jFrame);
|
activeRenders.remove(window);
|
||||||
|
|
||||||
final boolean hadActiveRenders = !activeRenders.isEmpty();
|
final boolean hadActiveRenders = !activeRenders.isEmpty();
|
||||||
hasActiveRenders = hadActiveRenders;
|
hasActiveRenders = hadActiveRenders;
|
||||||
|
@ -154,9 +154,9 @@ class SwingActiveRender {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// have to specify ALL children in jFrame to obey EDT paint requests
|
// have to specify ALL children in window to obey EDT paint requests
|
||||||
Deque<Component> components = new ArrayDeque<Component>(8);
|
Deque<Component> components = new ArrayDeque<Component>(8);
|
||||||
components.add(jFrame);
|
components.add(window);
|
||||||
|
|
||||||
Component[] c;
|
Component[] c;
|
||||||
Component pop;
|
Component pop;
|
||||||
|
|
Loading…
Reference in New Issue