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