mirror of https://github.com/weisJ/darklaf.git
weisj
4 years ago
9 changed files with 660 additions and 49 deletions
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2021 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||||
|
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or |
||||||
|
* substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||||
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf; |
||||||
|
|
||||||
|
import java.awt.Window; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import javax.swing.UIManager; |
||||||
|
import javax.swing.UnsupportedLookAndFeelException; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.theme.Theme; |
||||||
|
import com.github.weisj.darklaf.theme.event.ThemeChangeEvent; |
||||||
|
import com.github.weisj.darklaf.theme.event.ThemeChangeListener; |
||||||
|
import com.github.weisj.darklaf.theme.event.ThemeEventSupport; |
||||||
|
import com.github.weisj.darklaf.util.LogUtil; |
||||||
|
|
||||||
|
final class LafInstaller { |
||||||
|
|
||||||
|
private static final Logger LOGGER = LogUtil.getLogger(LafManager.class); |
||||||
|
private static final ThemeEventSupport<ThemeChangeEvent, ThemeChangeListener> eventSupport = |
||||||
|
new ThemeEventSupport<>(); |
||||||
|
|
||||||
|
void install(final Theme theme) { |
||||||
|
try { |
||||||
|
LOGGER.fine(() -> "Installing theme " + theme); |
||||||
|
LafTransition transition = LafTransition.showSnapshot(); |
||||||
|
UIManager.setLookAndFeel(new DarkLaf(false)); |
||||||
|
updateLaf(); |
||||||
|
SwingUtilities.invokeLater(transition::runTransition); |
||||||
|
notifyThemeInstalled(theme); |
||||||
|
} catch (final UnsupportedLookAndFeelException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void updateLaf() { |
||||||
|
for (final Window w : Window.getWindows()) { |
||||||
|
updateLafRecursively(w); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void updateLafRecursively(final Window window) { |
||||||
|
for (final Window childWindow : window.getOwnedWindows()) { |
||||||
|
updateLafRecursively(childWindow); |
||||||
|
} |
||||||
|
SwingUtilities.updateComponentTreeUI(window); |
||||||
|
} |
||||||
|
|
||||||
|
void notifyThemeInstalled(final Theme newTheme) { |
||||||
|
eventSupport.dispatchEvent(new ThemeChangeEvent(null, newTheme), ThemeChangeListener::themeInstalled); |
||||||
|
} |
||||||
|
|
||||||
|
void addThemeChangeListener(final ThemeChangeListener listener) { |
||||||
|
eventSupport.addListener(listener); |
||||||
|
} |
||||||
|
|
||||||
|
void removeThemeChangeListener(final ThemeChangeListener listener) { |
||||||
|
eventSupport.removeListener(listener); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
void notifyThemeChanged(final Theme oldTheme, final Theme newTheme) { |
||||||
|
if (oldTheme != newTheme) { |
||||||
|
eventSupport.dispatchEvent(new ThemeChangeEvent(oldTheme, newTheme), ThemeChangeListener::themeChanged); |
||||||
|
LOGGER.fine(() -> "Setting theme to " + newTheme); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,166 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2021 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||||
|
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or |
||||||
|
* substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||||
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.awt.AlphaComposite; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.Window; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.JLayeredPane; |
||||||
|
import javax.swing.RootPaneContainer; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.graphics.Animator; |
||||||
|
import com.github.weisj.darklaf.graphics.DefaultInterpolator; |
||||||
|
import com.github.weisj.darklaf.util.ImageUtil; |
||||||
|
import com.github.weisj.darklaf.util.PropertyUtil; |
||||||
|
import com.github.weisj.darklaf.util.graphics.ImagePainter; |
||||||
|
import com.github.weisj.darklaf.util.value.SharedNonNull; |
||||||
|
|
||||||
|
class LafTransition { |
||||||
|
|
||||||
|
private static final String ANIMATED_LAF_CHANGE = DarkLaf.SYSTEM_PROPERTY_PREFIX + "animatedLafChange"; |
||||||
|
|
||||||
|
private LafTransition() {} |
||||||
|
|
||||||
|
static LafTransition showSnapshot() { |
||||||
|
return PropertyUtil.getSystemFlag(ANIMATED_LAF_CHANGE) |
||||||
|
? new AnimatedLafTransition() |
||||||
|
: new LafTransition(); |
||||||
|
} |
||||||
|
|
||||||
|
void runTransition() { |
||||||
|
// Do nothing.
|
||||||
|
} |
||||||
|
|
||||||
|
static final class AnimatedLafTransition extends LafTransition { |
||||||
|
|
||||||
|
private final Animator animator; |
||||||
|
private final Map<JLayeredPane, Component> uiSnapshots; |
||||||
|
private final SharedNonNull<Float> sharedAlpha; |
||||||
|
|
||||||
|
private AnimatedLafTransition() { |
||||||
|
sharedAlpha = new SharedNonNull<>(1f); |
||||||
|
animator = new TransitionAnimator(); |
||||||
|
uiSnapshots = new LinkedHashMap<>(); |
||||||
|
Window[] windows = Window.getWindows(); |
||||||
|
for (Window window : windows) { |
||||||
|
if (window instanceof RootPaneContainer && window.isShowing()) { |
||||||
|
RootPaneContainer rootPaneContainer = (RootPaneContainer) window; |
||||||
|
Image img = ImageUtil.scaledImageFromComponent(rootPaneContainer.getRootPane()); |
||||||
|
JLayeredPane layeredPane = rootPaneContainer.getLayeredPane(); |
||||||
|
JComponent imageLayer = new ImageLayer(layeredPane, img, sharedAlpha); |
||||||
|
imageLayer.setSize(layeredPane.getSize()); |
||||||
|
layeredPane.add(imageLayer, JLayeredPane.DRAG_LAYER); |
||||||
|
uiSnapshots.put(layeredPane, imageLayer); |
||||||
|
} |
||||||
|
} |
||||||
|
doPaint(); |
||||||
|
} |
||||||
|
|
||||||
|
void runTransition() { |
||||||
|
animator.resume(); |
||||||
|
} |
||||||
|
|
||||||
|
private void disposeSnapshots() { |
||||||
|
for (Map.Entry<JLayeredPane, Component> entry : uiSnapshots.entrySet()) { |
||||||
|
entry.getKey().remove(entry.getValue()); |
||||||
|
entry.getKey().revalidate(); |
||||||
|
entry.getKey().repaint(); |
||||||
|
} |
||||||
|
uiSnapshots.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
private void doPaint() { |
||||||
|
for (Map.Entry<JLayeredPane, Component> entry : uiSnapshots.entrySet()) { |
||||||
|
if (entry.getKey().isShowing()) { |
||||||
|
entry.getValue().revalidate(); |
||||||
|
entry.getValue().repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class TransitionAnimator extends Animator { |
||||||
|
|
||||||
|
private static final int DURATION = 160; |
||||||
|
private static final int RESOLUTION = 10; |
||||||
|
|
||||||
|
public TransitionAnimator() { |
||||||
|
super(DURATION / RESOLUTION, DURATION, false, DefaultInterpolator.EASE_IN_SINE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void resume() { |
||||||
|
doPaint(); |
||||||
|
super.resume(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paintNow(final float fraction) { |
||||||
|
sharedAlpha.set(1f - fraction); |
||||||
|
doPaint(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintCycleEnd() { |
||||||
|
disposeSnapshots(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class ImageLayer extends JComponent { |
||||||
|
|
||||||
|
private final JLayeredPane layeredPane; |
||||||
|
private final SharedNonNull<Float> sharedAlpha; |
||||||
|
private final Image image; |
||||||
|
|
||||||
|
private ImageLayer(final JLayeredPane layeredPane, final Image image, final SharedNonNull<Float> sharedAlpha) { |
||||||
|
this.layeredPane = layeredPane; |
||||||
|
this.image = image; |
||||||
|
this.sharedAlpha = sharedAlpha; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateUI() {} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paint(final Graphics g) { |
||||||
|
Graphics gg = g.create(); |
||||||
|
((Graphics2D) gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, sharedAlpha.get())); |
||||||
|
ImagePainter.drawImage(gg, image, 0, 0, this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Rectangle getBounds() { |
||||||
|
return layeredPane.getBounds(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,168 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2021 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||||
|
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or |
||||||
|
* substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||||
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.util.graphics; |
||||||
|
|
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.geom.AffineTransform; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.awt.image.BufferedImageOp; |
||||||
|
import java.awt.image.ImageObserver; |
||||||
|
|
||||||
|
public final class ImagePainter { |
||||||
|
/** |
||||||
|
* A hidpi-aware wrapper over {@link Graphics#drawImage(Image, int, int, ImageObserver)}. |
||||||
|
* |
||||||
|
* @see #drawImage(Graphics, Image, Rectangle, Rectangle, ImageObserver) |
||||||
|
*/ |
||||||
|
public static void drawImage(final Graphics g, final Image image, final int x, final int y, |
||||||
|
final ImageObserver observer) { |
||||||
|
drawImage(g, image, new Rectangle(x, y, -1, -1), null, null, observer); |
||||||
|
} |
||||||
|
|
||||||
|
static void drawImage(final Graphics g, final Image image, final int x, final int y, final int width, |
||||||
|
final int height, final BufferedImageOp op, |
||||||
|
final ImageObserver observer) { |
||||||
|
Rectangle srcBounds = width >= 0 && height >= 0 ? new Rectangle(x, y, width, height) : null; |
||||||
|
drawImage(g, image, new Rectangle(x, y, width, height), srcBounds, op, observer); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* A hidpi-aware wrapper over {@link Graphics#drawImage(Image, int, int, int, int, ImageObserver)}. |
||||||
|
* |
||||||
|
* @see #drawImage(Graphics, Image, Rectangle, Rectangle, BufferedImageOp, ImageObserver) |
||||||
|
*/ |
||||||
|
public static void drawImage(final Graphics g, final Image image, final Rectangle dstBounds, |
||||||
|
final ImageObserver observer) { |
||||||
|
drawImage(g, image, dstBounds, null, null, observer); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @see #drawImage(Graphics, Image, Rectangle, Rectangle, BufferedImageOp, ImageObserver) |
||||||
|
*/ |
||||||
|
public static void drawImage(final Graphics g, |
||||||
|
final Image image, |
||||||
|
final Rectangle dstBounds, |
||||||
|
final Rectangle srcBounds, |
||||||
|
final ImageObserver observer) { |
||||||
|
drawImage(g, image, dstBounds, srcBounds, null, observer); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* A hidpi-aware wrapper over |
||||||
|
* {@link Graphics#drawImage(Image, int, int, int, int, int, int, int, int, ImageObserver)}. |
||||||
|
* <p> |
||||||
|
* The {@code dstBounds} and {@code srcBounds} are in the user space (just like the width/height of |
||||||
|
* the image). If {@code dstBounds} is null or if its width/height is set to (-1) the image bounds |
||||||
|
* or the image width/height is used. If {@code srcBounds} is null or if its width/height is set to |
||||||
|
* (-1) the image bounds or the image right/bottom area to the provided x/y is used. |
||||||
|
*/ |
||||||
|
public static void drawImage(Graphics g, |
||||||
|
Image image, |
||||||
|
final Rectangle dstBounds, |
||||||
|
final Rectangle srcBounds, |
||||||
|
final BufferedImageOp op, |
||||||
|
final ImageObserver observer) { |
||||||
|
int userWidth = image.getWidth(observer); |
||||||
|
int userHeight = image.getHeight(observer); |
||||||
|
|
||||||
|
int dx = 0; |
||||||
|
int dy = 0; |
||||||
|
int dw = -1; |
||||||
|
int dh = -1; |
||||||
|
if (dstBounds != null) { |
||||||
|
dx = dstBounds.x; |
||||||
|
dy = dstBounds.y; |
||||||
|
dw = dstBounds.width; |
||||||
|
dh = dstBounds.height; |
||||||
|
} |
||||||
|
boolean hasDstSize = dw >= 0 && dh >= 0; |
||||||
|
|
||||||
|
Graphics2D invG = null; |
||||||
|
double scaleX = 1; |
||||||
|
double scaleY = 1; |
||||||
|
if (image instanceof ScaledImage) { |
||||||
|
ScaledImage scaledImage = (ScaledImage) image; |
||||||
|
Image delegate = scaledImage.getDelegate(); |
||||||
|
if (delegate != null) image = delegate; |
||||||
|
scaleX = scaledImage.getScaleX(); |
||||||
|
scaleY = scaledImage.getScaleY(); |
||||||
|
|
||||||
|
userWidth /= scaleX; |
||||||
|
userHeight /= scaleY; |
||||||
|
|
||||||
|
AffineTransform tx = ((Graphics2D) g).getTransform(); |
||||||
|
if (scaleX == tx.getScaleX() && scaleY == tx.getScaleY()) { |
||||||
|
// The image has the same original scale as the graphics scale. However, the real image
|
||||||
|
// scale - userSize/realSize - can suffer from inaccuracy due to the image user size
|
||||||
|
// rounding to int (userSize = (int)realSize/originalImageScale). This may case quality
|
||||||
|
// loss if the image is drawn via Graphics.drawImage(image, <srcRect>, <dstRect>)
|
||||||
|
// due to scaling in Graphics. To avoid that, the image should be drawn directly via
|
||||||
|
// Graphics.drawImage(image, 0, 0) on the unscaled Graphics.
|
||||||
|
double gScaleX = tx.getScaleX(); |
||||||
|
double gScaleY = tx.getScaleY(); |
||||||
|
tx.scale(1 / gScaleX, 1 / gScaleY); |
||||||
|
tx.translate(dx * gScaleX, dy * gScaleY); |
||||||
|
dx = dy = 0; |
||||||
|
g = invG = (Graphics2D) g.create(); |
||||||
|
invG.setTransform(tx); |
||||||
|
} |
||||||
|
} |
||||||
|
try { |
||||||
|
if (op != null && image instanceof BufferedImage) { |
||||||
|
image = op.filter((BufferedImage) image, null); |
||||||
|
} |
||||||
|
if (invG != null && hasDstSize) { |
||||||
|
dw = (int) Math.round(dw * scaleX); |
||||||
|
dh = (int) Math.round(dh * scaleY); |
||||||
|
} |
||||||
|
if (srcBounds != null) { |
||||||
|
int sx = (int) Math.round(srcBounds.x * scaleX); |
||||||
|
int sy = (int) Math.round(srcBounds.y * scaleY); |
||||||
|
int sw = srcBounds.width >= 0 |
||||||
|
? (int) Math.round(srcBounds.width * scaleX) |
||||||
|
: (int) Math.round(userWidth * scaleX) - sx; |
||||||
|
int sh = srcBounds.height >= 0 |
||||||
|
? (int) Math.round(srcBounds.height * scaleY) |
||||||
|
: (int) Math.round(userHeight * scaleY) - sy; |
||||||
|
if (!hasDstSize) { |
||||||
|
dw = (int) Math.round(userWidth * scaleX); |
||||||
|
dh = (int) Math.round(userHeight * scaleY); |
||||||
|
} |
||||||
|
g.drawImage(image, |
||||||
|
dx, dy, dx + dw, dy + dh, |
||||||
|
sx, sy, sx + sw, sy + sh, |
||||||
|
observer); |
||||||
|
} else if (hasDstSize) { |
||||||
|
g.drawImage(image, dx, dy, dw, dh, observer); |
||||||
|
} else if (invG == null) { |
||||||
|
g.drawImage(image, dx, dy, userWidth, userHeight, observer); |
||||||
|
} else { |
||||||
|
g.drawImage(image, dx, dy, observer); |
||||||
|
} |
||||||
|
} finally { |
||||||
|
if (invG != null) invG.dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2021 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||||
|
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or |
||||||
|
* substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||||
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.util.graphics; |
||||||
|
|
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.awt.image.ImageObserver; |
||||||
|
import java.awt.image.ImageProducer; |
||||||
|
|
||||||
|
public class ScaledImage extends Image { |
||||||
|
|
||||||
|
private final BufferedImage delegate; |
||||||
|
private final double scaleX; |
||||||
|
private final double scaleY; |
||||||
|
|
||||||
|
public ScaledImage(final BufferedImage delegate, final double scaleX, final double scaleY) { |
||||||
|
this.delegate = delegate; |
||||||
|
this.scaleX = scaleX; |
||||||
|
this.scaleY = scaleY; |
||||||
|
} |
||||||
|
|
||||||
|
public BufferedImage getDelegate() { |
||||||
|
return delegate; |
||||||
|
} |
||||||
|
|
||||||
|
public double getScaleX() { |
||||||
|
return scaleX; |
||||||
|
} |
||||||
|
|
||||||
|
public double getScaleY() { |
||||||
|
return scaleY; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getWidth(final ImageObserver observer) { |
||||||
|
return delegate.getWidth(observer); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getHeight(final ImageObserver observer) { |
||||||
|
return delegate.getHeight(observer); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ImageProducer getSource() { |
||||||
|
return delegate.getSource(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Graphics getGraphics() { |
||||||
|
return delegate.getGraphics(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getProperty(final String name, final ImageObserver observer) { |
||||||
|
return delegate.getProperty(name, observer); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2021 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||||
|
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or |
||||||
|
* substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||||
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.util.value; |
||||||
|
|
||||||
|
public class Shared<T> { |
||||||
|
private T value; |
||||||
|
|
||||||
|
public Shared(final T initial) { |
||||||
|
set(initial); |
||||||
|
} |
||||||
|
|
||||||
|
public T get() { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void set(final T value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2021 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
||||||
|
* associated documentation files (the "Software"), to deal in the Software without restriction, |
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, |
||||||
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or |
||||||
|
* substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
||||||
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.util.value; |
||||||
|
|
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
public class SharedNonNull<T> extends Shared<T> { |
||||||
|
|
||||||
|
public SharedNonNull(final T initial) { |
||||||
|
super(initial); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void set(final T value) { |
||||||
|
super.set(Objects.requireNonNull(value)); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue