mirror of https://github.com/weisJ/darklaf.git
weisj
3 years ago
committed by
Jannis Weis
20 changed files with 685 additions and 683 deletions
@ -0,0 +1,375 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2006-2009, Alexander Potochkin |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions |
||||||
|
* are met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following |
||||||
|
* disclaimer in the documentation and/or other materials provided |
||||||
|
* with the distribution. |
||||||
|
* * Neither the name of the JXLayer project nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived |
||||||
|
* from this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package org.pbjar.jxlayer.plaf.ext; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.plaf.LayerUI; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.FocusEvent; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseWheelEvent; |
||||||
|
import java.awt.geom.AffineTransform; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.beans.PropertyChangeEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* The {@code AbstractLayerUI} provided default implementation for most |
||||||
|
* of the abstract methods in the {@link LayerUI} class. |
||||||
|
* It takes care of the management of {@code LayerItemListener}s and |
||||||
|
* defines the hook method to configure the {@code Graphics2D} instance |
||||||
|
* specified in the {@link #paint(Graphics,JComponent)} method. |
||||||
|
* It also provides convenient methods named |
||||||
|
* {@code process<eventType>Event} to process the given class of event. |
||||||
|
* <p/> |
||||||
|
* If state of the {@code AbstractLayerUI} is changed, call {@link #setDirty(boolean)} |
||||||
|
* with {@code true} as the parameter, it will repaint all {@code JLayer}s |
||||||
|
* connected with this {@code AbstractLayerUI} |
||||||
|
* |
||||||
|
* @see JLayer#setUI(LayerUI) |
||||||
|
*/ |
||||||
|
public abstract class AbstractLayerUI<V extends JComponent> |
||||||
|
extends LayerUI<V> { |
||||||
|
private static final Map<RenderingHints.Key, Object> emptyRenderingHintMap = |
||||||
|
Collections.unmodifiableMap(new HashMap<>(0)); |
||||||
|
|
||||||
|
private boolean dirty; |
||||||
|
private LayoutManager layoutManager; |
||||||
|
|
||||||
|
public void installUI(JComponent c) { |
||||||
|
super.installUI(c); |
||||||
|
((JLayer<?>) c).setLayerEventMask(getLayerEventMask()); |
||||||
|
} |
||||||
|
|
||||||
|
public void uninstallUI(JComponent c) { |
||||||
|
super.uninstallUI(c); |
||||||
|
((JLayer<?>) c).setLayerEventMask(0); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
*/ |
||||||
|
public void handlePropertyChangeEvent(PropertyChangeEvent evt, JLayer<? extends V> l) { |
||||||
|
if (!"dirty".equals(evt.getPropertyName()) |
||||||
|
|| evt.getNewValue() == Boolean.TRUE) { |
||||||
|
l.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the "dirty bit". |
||||||
|
* If {@code true}, then the {@code AbstractLayerUI} is considered dirty |
||||||
|
* and in need of being repainted. |
||||||
|
* |
||||||
|
* @return {@code true} if the {@code AbstractLayerUI} state has changed |
||||||
|
* and the {@link JLayer}s it is set to need to be repainted. |
||||||
|
*/ |
||||||
|
protected boolean isDirty() { |
||||||
|
return dirty; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the "dirty bit". |
||||||
|
* If {@code isDirty} is {@code true}, then the {@code AbstractLayerUI} |
||||||
|
* is considered dirty and it triggers the repainting |
||||||
|
* of the {@link JLayer}s this {@code AbstractLayerUI} it is set to. |
||||||
|
* |
||||||
|
* @param isDirty whether this {@code AbstractLayerUI} is dirty or not. |
||||||
|
*/ |
||||||
|
protected void setDirty(boolean isDirty) { |
||||||
|
boolean oldDirty = this.dirty; |
||||||
|
this.dirty = isDirty; |
||||||
|
firePropertyChange("dirty", oldDirty, isDirty); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
* <p/> |
||||||
|
* <b>Note:</b> It is rarely necessary to override this method, for |
||||||
|
* custom painting override {@link #paintLayer(Graphics2D,JLayer)} instead |
||||||
|
* <p/> |
||||||
|
* This method configures the passed {@code Graphics} with help of the |
||||||
|
* {@link #configureGraphics(Graphics2D,JLayer)} method, |
||||||
|
* then calls {@code paintLayer(Graphics2D,JLayer)} |
||||||
|
* and resets the "dirty bit" at the end. |
||||||
|
* |
||||||
|
* @see #configureGraphics(Graphics2D,JLayer) |
||||||
|
* @see #paintLayer(Graphics2D,JLayer) |
||||||
|
* @see #setDirty(boolean) |
||||||
|
*/ |
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
public void paint(Graphics g, JComponent c) { |
||||||
|
if (g instanceof Graphics2D) { |
||||||
|
Graphics2D g2 = (Graphics2D) g.create(); |
||||||
|
JLayer<V> l = (JLayer<V>) c; |
||||||
|
configureGraphics(g2, l); |
||||||
|
paintLayer(g2, l); |
||||||
|
g2.dispose(); |
||||||
|
setDirty(false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Subclasses should implement this method |
||||||
|
* and perform custom painting operations here. |
||||||
|
* <p/> |
||||||
|
* The default implementation paints the passed {@code JLayer} as is. |
||||||
|
* |
||||||
|
* @param g2 the {@code Graphics2D} context in which to paint |
||||||
|
* @param l the {@code JLayer} being painted |
||||||
|
*/ |
||||||
|
protected void paintLayer(Graphics2D g2, JLayer<? extends V> l) { |
||||||
|
l.paint(g2); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This method is called by the {@link #paint} method prior to |
||||||
|
* any drawing operations to configure the {@code Graphics2D} object. |
||||||
|
* The default implementation sets the {@link Composite}, the clip, |
||||||
|
* {@link AffineTransform} and rendering hints |
||||||
|
* obtained from the corresponding hook methods. |
||||||
|
* |
||||||
|
* @param g2 the {@code Graphics2D} object to configure |
||||||
|
* @param l the {@code JLayer} being painted |
||||||
|
* |
||||||
|
* @see #getComposite(JLayer) |
||||||
|
* @see #getClip(JLayer) |
||||||
|
* @see #getTransform(JLayer) |
||||||
|
* @see #getRenderingHints(JLayer) |
||||||
|
*/ |
||||||
|
protected void configureGraphics(Graphics2D g2, JLayer<? extends V> l) { |
||||||
|
Composite composite = getComposite(l); |
||||||
|
if (composite != null) { |
||||||
|
g2.setComposite(composite); |
||||||
|
} |
||||||
|
Shape clip = getClip(l); |
||||||
|
if (clip != null) { |
||||||
|
g2.clip(clip); |
||||||
|
} |
||||||
|
AffineTransform transform = getTransform(l); |
||||||
|
if (transform != null) { |
||||||
|
g2.transform(transform); |
||||||
|
} |
||||||
|
Map<RenderingHints.Key, Object> hints = getRenderingHints(l); |
||||||
|
if (hints != null) { |
||||||
|
for (RenderingHints.Key key : hints.keySet()) { |
||||||
|
Object value = hints.get(key); |
||||||
|
if (value != null) { |
||||||
|
g2.setRenderingHint(key, hints.get(key)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link Composite} to be used during painting of this {@code JLayer}, |
||||||
|
* the default implementation returns {@code null}. |
||||||
|
* |
||||||
|
* @param l the {@code JLayer} being painted |
||||||
|
* |
||||||
|
* @return the {@link Composite} to be used during painting for the {@code JLayer} |
||||||
|
*/ |
||||||
|
protected Composite getComposite(JLayer<? extends V> l) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link AffineTransform} to be used during painting of this {@code JLayer}, |
||||||
|
* the default implementation returns {@code null}. |
||||||
|
* |
||||||
|
* @param l the {@code JLayer} being painted |
||||||
|
* |
||||||
|
* @return the {@link AffineTransform} to be used during painting of the {@code JLayer} |
||||||
|
*/ |
||||||
|
protected AffineTransform getTransform(JLayer<? extends V> l) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the {@link Shape} to be used as the clip during painting of this {@code JLayer}, |
||||||
|
* the default implementation returns {@code null}. |
||||||
|
* |
||||||
|
* @param l the {@code JLayer} being painted |
||||||
|
* |
||||||
|
* @return the {@link Shape} to be used as the clip during painting of the {@code JLayer} |
||||||
|
*/ |
||||||
|
protected Shape getClip(JLayer<? extends V> l) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the map of rendering hints to be used during painting of this {@code JLayer}, |
||||||
|
* the default implementation returns the empty unmodifiable map. |
||||||
|
* |
||||||
|
* @param l the {@code JLayer} being painted |
||||||
|
* |
||||||
|
* @return the map of rendering hints to be used during painting of the {@code JLayer} |
||||||
|
*/ |
||||||
|
protected Map<RenderingHints.Key, Object> getRenderingHints(JLayer<? extends V> l) { |
||||||
|
return emptyRenderingHintMap; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLayoutManager(final LayoutManager layoutManager) { |
||||||
|
this.layoutManager = layoutManager; |
||||||
|
} |
||||||
|
|
||||||
|
protected LayoutManager getLayout() { |
||||||
|
return layoutManager; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doLayout(JLayer<? extends V> l) { |
||||||
|
LayoutManager layoutManager = getLayout(); |
||||||
|
if (layoutManager != null) { |
||||||
|
layoutManager.layoutContainer(l); |
||||||
|
} else { |
||||||
|
super.doLayout(l); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize(final JComponent c) { |
||||||
|
LayoutManager layoutManager = getLayout(); |
||||||
|
if (layoutManager != null) { |
||||||
|
return layoutManager.preferredLayoutSize(c); |
||||||
|
} else { |
||||||
|
return super.getPreferredSize(c); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getMinimumSize(final JComponent c) { |
||||||
|
LayoutManager layoutManager = getLayout(); |
||||||
|
if (layoutManager != null) { |
||||||
|
return layoutManager.minimumLayoutSize(c); |
||||||
|
} else { |
||||||
|
return super.getMinimumSize(c); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* By default only mouse, mouse motion, mouse wheel, keyboard and focus events are supported, |
||||||
|
* if you need to catch any other type of events, |
||||||
|
* override this method to return the different mask |
||||||
|
* |
||||||
|
* @see JLayer#setLayerEventMask(long) |
||||||
|
*/ |
||||||
|
public long getLayerEventMask() { |
||||||
|
return AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK |
||||||
|
| AWTEvent.MOUSE_WHEEL_EVENT_MASK |
||||||
|
| AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
* <p/> |
||||||
|
* This method calls the appropriate |
||||||
|
* {@code process<eventType>Event} |
||||||
|
* method for the given class of event. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void eventDispatched(AWTEvent e, JLayer<? extends V> l) { |
||||||
|
if (e instanceof FocusEvent) { |
||||||
|
processFocusEvent((FocusEvent) e, l); |
||||||
|
} else if (e instanceof MouseEvent) { |
||||||
|
switch (e.getID()) { |
||||||
|
case MouseEvent.MOUSE_PRESSED: |
||||||
|
case MouseEvent.MOUSE_RELEASED: |
||||||
|
case MouseEvent.MOUSE_CLICKED: |
||||||
|
case MouseEvent.MOUSE_ENTERED: |
||||||
|
case MouseEvent.MOUSE_EXITED: |
||||||
|
processMouseEvent((MouseEvent) e, l); |
||||||
|
break; |
||||||
|
case MouseEvent.MOUSE_MOVED: |
||||||
|
case MouseEvent.MOUSE_DRAGGED: |
||||||
|
processMouseMotionEvent((MouseEvent) e, l); |
||||||
|
break; |
||||||
|
case MouseEvent.MOUSE_WHEEL: |
||||||
|
processMouseWheelEvent((MouseWheelEvent) e, l); |
||||||
|
break; |
||||||
|
} |
||||||
|
} else if (e instanceof KeyEvent) { |
||||||
|
processKeyEvent((KeyEvent) e, l); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes {@code FocusEvent} occurring on the {@link JLayer} |
||||||
|
* or any of its subcomponents. |
||||||
|
* |
||||||
|
* @param e the {@code FocusEvent} to be processed |
||||||
|
* @param l the layer this LayerUI is set to |
||||||
|
*/ |
||||||
|
protected void processFocusEvent(FocusEvent e, JLayer<? extends V> l) { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes {@code MouseEvent} occurring on the {@link JLayer} |
||||||
|
* or any of its subcomponents. |
||||||
|
* |
||||||
|
* @param e the {@code MouseEvent} to be processed |
||||||
|
* @param l the layer this LayerUI is set to |
||||||
|
*/ |
||||||
|
protected void processMouseEvent(MouseEvent e, JLayer<? extends V> l) { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes mouse motion events occurring on the {@link JLayer} |
||||||
|
* or any of its subcomponents. |
||||||
|
* |
||||||
|
* @param e the {@code MouseEvent} to be processed |
||||||
|
* @param l the layer this LayerUI is set to |
||||||
|
*/ |
||||||
|
protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends V> l) { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes {@code MouseWheelEvent} occurring on the {@link JLayer} |
||||||
|
* or any of its subcomponents. |
||||||
|
* |
||||||
|
* @param e the {@code MouseWheelEvent} to be processed |
||||||
|
* @param l the layer this LayerUI is set to |
||||||
|
*/ |
||||||
|
protected void processMouseWheelEvent(MouseWheelEvent e, JLayer<? extends V> l) { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes {@code KeyEvent} occurring on the {@link JLayer} |
||||||
|
* or any of its subcomponents. |
||||||
|
* |
||||||
|
* @param e the {@code KeyEvent} to be processed |
||||||
|
* @param l the layer this LayerUI is set to |
||||||
|
*/ |
||||||
|
protected void processKeyEvent(KeyEvent e, JLayer<? extends V> l) { |
||||||
|
} |
||||||
|
} |
@ -1,73 +1,89 @@ |
|||||||
/* |
/* |
||||||
* Copyright (c) 2008-2009, Piet Blok |
* Copyright (c) 2008-2009, Piet Blok All rights reserved. |
||||||
* All rights reserved. |
|
||||||
* <p> |
* <p> |
||||||
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without modification, are permitted |
||||||
* modification, are permitted provided that the following conditions |
* provided that the following conditions are met: |
||||||
* are met: |
|
||||||
* <p> |
* <p> |
||||||
* Redistributions of source code must retain the above copyright |
* Redistributions of source code must retain the above copyright notice, this list of conditions |
||||||
* notice, this list of conditions and the following disclaimer. |
* and the following disclaimer. Redistributions in binary form must reproduce the above copyright |
||||||
* Redistributions in binary form must reproduce the above |
* notice, this list of conditions and the following disclaimer in the documentation and/or other |
||||||
* copyright notice, this list of conditions and the following |
* materials provided with the distribution. Neither the name of the copyright holder nor the names |
||||||
* disclaimer in the documentation and/or other materials provided |
* of the contributors may be used to endorse or promote products derived from this software without |
||||||
* with the distribution. |
* specific prior written permission. |
||||||
* Neither the name of the copyright holder nor the names of the |
|
||||||
* contributors may be used to endorse or promote products derived |
|
||||||
* from this software without specific prior written permission. |
|
||||||
* <p> |
* <p> |
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR |
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY |
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
*/ |
||||||
package org.pbjar.jxlayer.plaf.ext.transform; |
package org.pbjar.jxlayer.plaf.ext.transform; |
||||||
|
|
||||||
import javax.swing.*; |
import javax.swing.*; |
||||||
|
import javax.swing.plaf.LayerUI; |
||||||
|
|
||||||
import org.jdesktop.swingx.ForwardingRepaintManager; |
import org.jdesktop.swingx.ForwardingRepaintManager; |
||||||
|
import org.pbjar.jxlayer.plaf.ext.TransformUI; |
||||||
import org.pbjar.jxlayer.repaint.RepaintManagerProvider; |
import org.pbjar.jxlayer.repaint.RepaintManagerProvider; |
||||||
import org.pbjar.jxlayer.repaint.RepaintManagerUtils; |
import org.pbjar.jxlayer.repaint.RepaintManagerUtils; |
||||||
import org.pbjar.jxlayer.repaint.WrappedRepaintManager; |
import org.pbjar.jxlayer.repaint.WrappedRepaintManager; |
||||||
|
|
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.Rectangle; |
||||||
|
|
||||||
/** |
/** |
||||||
* A specialized {@link RepaintManager} that checks for every JComponent that is being set dirty, if it has a JXLayer |
* A specialized {@link RepaintManager} that checks for every JComponent that is being set dirty, if |
||||||
* ancestor, equipped with a TransformUI. In that case, the transformed region on the JXLayer is also marked dirty. |
* it has a JLayer ancestor, equipped with a TransformUI. In that case, the transformed region on |
||||||
|
* the JLayer is also marked dirty. |
||||||
* <p> |
* <p> |
||||||
* A fall back class if the {@link ForwardingRepaintManager} cannot be instantiated because the |
* A fall back class if the {@link ForwardingRepaintManager} cannot be instantiated because the |
||||||
* SwingX packages are not on the class path. |
* SwingX packages are not on the class path. |
||||||
* |
* |
||||||
* @see RepaintManagerProvider |
* @see RepaintManagerProvider |
||||||
* @see RepaintManagerUtils |
* @see RepaintManagerUtils |
||||||
* @see TransformRPMSwingX |
|
||||||
*/ |
*/ |
||||||
@TransformRPMAnnotation |
@TransformRPMAnnotation |
||||||
public class TransformRPMFallBack extends WrappedRepaintManager { |
public class TransformRPMFallBack extends WrappedRepaintManager { |
||||||
|
|
||||||
/** |
|
||||||
* Sole constructor. |
|
||||||
* |
|
||||||
* @param delegate the delegate {@link RepaintManager} |
|
||||||
*/ |
|
||||||
public TransformRPMFallBack(final RepaintManager delegate) { |
public TransformRPMFallBack(final RepaintManager delegate) { |
||||||
super(delegate); |
super(delegate); |
||||||
TransformRPMImpl.hackInitialization(delegate, this); |
|
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Delegates and then marks a JXLayer ancestor as dirty with the transformed rectangle. |
* Searches upwards in the component hierarchy for a {@link JLayer} ancestor with an enabled |
||||||
|
* {@link TransformUI}. |
||||||
|
* <p> |
||||||
|
* If found, the dirty rectangle is transformed to a rectangle targeted at that {@link JLayer} and |
||||||
|
* the argument manager's {@link RepaintManager#addDirtyRegion(JComponent, int, int, int, int)} is |
||||||
|
* invoked. |
||||||
|
* |
||||||
|
* @param aComponent a component |
||||||
|
* @param x the X of the dirty region |
||||||
|
* @param y the Y of the dirty region |
||||||
|
* @param w the width of the dirty region |
||||||
|
* @param h the height of the dirty region |
||||||
*/ |
*/ |
||||||
|
@SuppressWarnings("unchecked") |
||||||
@Override |
@Override |
||||||
public void addDirtyRegion(final JComponent c, final int x, final int y, final int w, final int h) { |
public void addDirtyRegion(final JComponent aComponent, final int x, final int y, final int w, final int h) { |
||||||
if (!TransformRPMImpl.addDirtyRegion(c, x, y, w, h, this)) { |
if (aComponent.isShowing()) { |
||||||
super.addDirtyRegion(c, x, y, w, h); |
JLayer<?> layer = TransformUtils.findTransformJLayer(aComponent); |
||||||
|
if (layer != null) { |
||||||
|
LayerUI<?> layerUI = layer.getUI(); |
||||||
|
TransformUI ui = (TransformUI) layerUI; |
||||||
|
Point point = aComponent.getLocationOnScreen(); |
||||||
|
SwingUtilities.convertPointFromScreen(point, layer); |
||||||
|
Rectangle transformPortRegion = ui.transform(new Rectangle(x + point.x, y + point.y, w, h), |
||||||
|
(JLayer<JComponent>) layer); |
||||||
|
addDirtyRegion(layer, |
||||||
|
transformPortRegion.x, transformPortRegion.y, |
||||||
|
transformPortRegion.width, transformPortRegion.height); |
||||||
|
return; |
||||||
|
} |
||||||
} |
} |
||||||
|
super.addDirtyRegion(aComponent, x, y, w, h); |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,186 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009, Piet Blok |
|
||||||
* All rights reserved. |
|
||||||
* <p> |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions |
|
||||||
* are met: |
|
||||||
* <p> |
|
||||||
* Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* Redistributions in binary form must reproduce the above |
|
||||||
* copyright notice, this list of conditions and the following |
|
||||||
* disclaimer in the documentation and/or other materials provided |
|
||||||
* with the distribution. |
|
||||||
* Neither the name of the copyright holder nor the names of the |
|
||||||
* contributors may be used to endorse or promote products derived |
|
||||||
* from this software without specific prior written permission. |
|
||||||
* <p> |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
package org.pbjar.jxlayer.plaf.ext.transform; |
|
||||||
|
|
||||||
import java.awt.*; |
|
||||||
import java.lang.reflect.Field; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
import java.util.logging.Level; |
|
||||||
import java.util.logging.Logger; |
|
||||||
|
|
||||||
import javax.swing.*; |
|
||||||
|
|
||||||
import com.github.weisj.darklaf.util.SystemInfo; |
|
||||||
import org.jdesktop.jxlayer.JXLayer; |
|
||||||
import org.jdesktop.jxlayer.plaf.LayerUI; |
|
||||||
import org.pbjar.jxlayer.plaf.ext.TransformUI; |
|
||||||
|
|
||||||
import com.github.weisj.darklaf.util.LogUtil; |
|
||||||
|
|
||||||
/** |
|
||||||
* To avoid duplicate code, this class implements the actual logic for {@link TransformRPMSwingX} and {@link |
|
||||||
* TransformRPMFallBack}. |
|
||||||
* |
|
||||||
* @author Piet Blok |
|
||||||
*/ |
|
||||||
public final class TransformRPMImpl { |
|
||||||
|
|
||||||
private static final Logger LOGGER = LogUtil.getDetachedLogger(TransformRPMImpl.class); |
|
||||||
/** |
|
||||||
* A flag, indicating whether or not a very dirty initialization on created {@link RepaintManager}s must be |
|
||||||
* performed. |
|
||||||
* |
|
||||||
* @see #hackInitialization(RepaintManager, RepaintManager) |
|
||||||
*/ |
|
||||||
public static final boolean hack = !SystemInfo.isJava9OrGreater; |
|
||||||
|
|
||||||
private TransformRPMImpl() {} |
|
||||||
|
|
||||||
/** |
|
||||||
* Searches upwards in the component hierarchy for a {@link JXLayer} ancestor with an enabled {@link TransformUI}. |
|
||||||
* <p> |
|
||||||
* If found, the dirty rectangle is transformed to a rectangle targeted at that {@link JXLayer} and the argument |
|
||||||
* manager's {@link RepaintManager#addDirtyRegion(JComponent, int, int, int, int)} is invoked. {@code true} is |
|
||||||
* returned. |
|
||||||
* </p> |
|
||||||
* <p> |
|
||||||
* Else, (@code false} is returned. |
|
||||||
* </p> |
|
||||||
* |
|
||||||
* @param aComponent a component |
|
||||||
* @param x the X of the dirty region |
|
||||||
* @param y the Y of the dirty region |
|
||||||
* @param w the width of the dirty region |
|
||||||
* @param h the height of the dirty region |
|
||||||
* @param manager the current {@link RepaintManager} |
|
||||||
* @return {@code true} if the call is delegated to the manager with a transformed rectangle, |
|
||||||
* {@code false} |
|
||||||
* otherwise |
|
||||||
*/ |
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public static boolean addDirtyRegion(final JComponent aComponent, final int x, final int y, |
|
||||||
final int w, final int h, final RepaintManager manager) { |
|
||||||
if (aComponent.isShowing()) { |
|
||||||
JXLayer<?> layer = findJXLayer(aComponent); |
|
||||||
if (layer != null) { |
|
||||||
LayerUI<?> layerUI = layer.getUI(); |
|
||||||
TransformUI ui = (TransformUI) layerUI; |
|
||||||
Point point = aComponent.getLocationOnScreen(); |
|
||||||
SwingUtilities.convertPointFromScreen(point, layer); |
|
||||||
Rectangle transformPortRegion = ui.transform(new Rectangle(x + point.x, y + point.y, w, h), |
|
||||||
(JXLayer<JComponent>) layer); |
|
||||||
manager.addDirtyRegion(layer, |
|
||||||
transformPortRegion.x, transformPortRegion.y, |
|
||||||
transformPortRegion.width, transformPortRegion.height); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* If {@link #hack} is {@code true}, the private fields {@code paintManager} and {@code bufferStrategyType} are |
|
||||||
* copied via reflection from the source manager into the destination manager. |
|
||||||
* |
|
||||||
* @param sourceManager the source manager |
|
||||||
* @param destinationManager the destination manager |
|
||||||
*/ |
|
||||||
public static void hackInitialization(final RepaintManager sourceManager, |
|
||||||
final RepaintManager destinationManager) { |
|
||||||
if (hack) { |
|
||||||
Class<RepaintManager> rpmClass = RepaintManager.class; |
|
||||||
try { |
|
||||||
|
|
||||||
Field fieldBufferStrategyType = rpmClass.getDeclaredField("bufferStrategyType"); |
|
||||||
Field fieldPaintManager = rpmClass.getDeclaredField("paintManager"); |
|
||||||
Method methodGetPaintManager = rpmClass.getDeclaredMethod("getPaintManager"); |
|
||||||
|
|
||||||
fieldBufferStrategyType.setAccessible(true); |
|
||||||
fieldPaintManager.setAccessible(true); |
|
||||||
methodGetPaintManager.setAccessible(true); |
|
||||||
|
|
||||||
Object paintManager = methodGetPaintManager.invoke(sourceManager); |
|
||||||
short bufferStrategyType = (Short) fieldBufferStrategyType.get(sourceManager); |
|
||||||
|
|
||||||
fieldBufferStrategyType.set(destinationManager, bufferStrategyType); |
|
||||||
fieldPaintManager.set(destinationManager, paintManager); |
|
||||||
|
|
||||||
fieldBufferStrategyType.setAccessible(false); |
|
||||||
fieldPaintManager.setAccessible(false); |
|
||||||
methodGetPaintManager.setAccessible(false); |
|
||||||
|
|
||||||
LOGGER.warning("Copied paintManager of type: " + paintManager.getClass().getName()); |
|
||||||
switch (bufferStrategyType) { |
|
||||||
case (0) : |
|
||||||
LOGGER.warning("Copied bufferStrategyType " |
|
||||||
+ bufferStrategyType |
|
||||||
+ ": BUFFER_STRATEGY_NOT_SPECIFIED"); |
|
||||||
break; |
|
||||||
case (1) : |
|
||||||
LOGGER.warning("Copied bufferStrategyType " |
|
||||||
+ bufferStrategyType |
|
||||||
+ ": BUFFER_STRATEGY_SPECIFIED_ON"); |
|
||||||
break; |
|
||||||
case (2) : |
|
||||||
LOGGER.warning("Copied bufferStrategyType " |
|
||||||
+ bufferStrategyType |
|
||||||
+ ": BUFFER_STRATEGY_SPECIFIED_OFF"); |
|
||||||
break; |
|
||||||
default : |
|
||||||
LOGGER.warning("Copied bufferStrategyType " |
|
||||||
+ bufferStrategyType + ": ???"); |
|
||||||
break; |
|
||||||
} |
|
||||||
} catch (Throwable t) { |
|
||||||
LOGGER.log(Level.SEVERE, t.getMessage(), t.getStackTrace()); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Find the first ancestor {@link JXLayer} with an enabled {@link TransformUI}. |
|
||||||
* |
|
||||||
* @param aComponent some component |
|
||||||
* @return a {@link JXLayer} instance or {@code null} |
|
||||||
*/ |
|
||||||
private static JXLayer<?> findJXLayer(final JComponent aComponent) { |
|
||||||
|
|
||||||
JXLayer<?> layer = (JXLayer<?>) SwingUtilities.getAncestorOfClass(JXLayer.class, aComponent); |
|
||||||
if (layer != null) { |
|
||||||
LayerUI<?> ui = ((JXLayer<?>) layer).getUI(); |
|
||||||
if (ui instanceof TransformUI) { |
|
||||||
return layer; |
|
||||||
} |
|
||||||
return findJXLayer(layer); |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
@ -1,73 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (c) 2009, Piet Blok |
|
||||||
* All rights reserved. |
|
||||||
* <p> |
|
||||||
* Redistribution and use in source and binary forms, with or without |
|
||||||
* modification, are permitted provided that the following conditions |
|
||||||
* are met: |
|
||||||
* <p> |
|
||||||
* Redistributions of source code must retain the above copyright |
|
||||||
* notice, this list of conditions and the following disclaimer. |
|
||||||
* Redistributions in binary form must reproduce the above |
|
||||||
* copyright notice, this list of conditions and the following |
|
||||||
* disclaimer in the documentation and/or other materials provided |
|
||||||
* with the distribution. |
|
||||||
* Neither the name of the copyright holder nor the names of the |
|
||||||
* contributors may be used to endorse or promote products derived |
|
||||||
* from this software without specific prior written permission. |
|
||||||
* <p> |
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||||
*/ |
|
||||||
package org.pbjar.jxlayer.plaf.ext.transform; |
|
||||||
|
|
||||||
import javax.swing.*; |
|
||||||
|
|
||||||
import org.jdesktop.swingx.ForwardingRepaintManager; |
|
||||||
import org.pbjar.jxlayer.repaint.RepaintManagerProvider; |
|
||||||
import org.pbjar.jxlayer.repaint.RepaintManagerUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* A specialized {@link RepaintManager} that checks for every JComponent that is being set dirty, if it has a JXLayer |
|
||||||
* ancestor, equipped with a TransformUI. In that case, the transformed region on the JXLayer is also marked dirty. |
|
||||||
* <p> |
|
||||||
* If this class cannot be instantiated because the SwingX packages are not on the class path, |
|
||||||
* use {@link TransformRPMFallBack} |
|
||||||
* |
|
||||||
* @author Piet Blok |
|
||||||
* @see TransformRPMFallBack |
|
||||||
* @see RepaintManagerProvider |
|
||||||
* @see RepaintManagerUtils |
|
||||||
*/ |
|
||||||
@TransformRPMAnnotation |
|
||||||
public class TransformRPMSwingX extends ForwardingRepaintManager { |
|
||||||
|
|
||||||
/** |
|
||||||
* Sole constructor. |
|
||||||
* |
|
||||||
* @param delegate the delegate {@link RepaintManager} |
|
||||||
*/ |
|
||||||
public TransformRPMSwingX(final RepaintManager delegate) { |
|
||||||
super(delegate); |
|
||||||
TransformRPMImpl.hackInitialization(delegate, this); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Delegates and then marks a JXLayer ancestor as dirty with the transformed rectangle. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void addDirtyRegion(final JComponent c, final int x, final int y, final int w, final int h) { |
|
||||||
if (!TransformRPMImpl.addDirtyRegion(c, x, y, w, h, this)) { |
|
||||||
super.addDirtyRegion(c, x, y, w, h); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue