diff --git a/.idea/misc.xml b/.idea/misc.xml index accd629..d24ea8e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 67b7b31..aa86c60 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,9 +5,20 @@ + - - + + + + + + + + + + + + + + + + - - + + + + - + + + + + + + - + + + + @@ -121,6 +180,16 @@ + + + + + + + + + + diff --git a/jar library/swing-glasspane-popup-1.1.0.jar b/jar library/swing-glasspane-popup-1.1.0.jar deleted file mode 100644 index dcd406b..0000000 Binary files a/jar library/swing-glasspane-popup-1.1.0.jar and /dev/null differ diff --git a/jar library/swing-glasspane-popup-1.2.0.jar b/jar library/swing-glasspane-popup-1.2.0.jar new file mode 100644 index 0000000..749ee43 Binary files /dev/null and b/jar library/swing-glasspane-popup-1.2.0.jar differ diff --git a/pom.xml b/pom.xml index 5f2982c..de806dd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ raven.popup swing-glasspane-popup - 1.1.0 + 1.2.0 11 diff --git a/src/main/java/raven/alerts/AlertsOption.java b/src/main/java/raven/alerts/AlertsOption.java new file mode 100644 index 0000000..7cd193b --- /dev/null +++ b/src/main/java/raven/alerts/AlertsOption.java @@ -0,0 +1,108 @@ +package raven.alerts; + +import com.formdev.flatlaf.extras.FlatSVGIcon; +import raven.swing.AnimateIcon; +import raven.swing.animator.EasingInterpolator; +import raven.swing.animator.KeyFrames; + +import javax.swing.*; +import java.awt.*; + +public class AlertsOption { + + protected Icon icon; + protected Color baseColor; + + protected boolean loopAnimation; + + protected EffectOption effectOption; + + public AlertsOption(Icon icon, Color baseColor) { + this.icon = icon; + this.baseColor = baseColor; + } + + public AlertsOption setEffectOption(EffectOption effectOption) { + this.effectOption = effectOption; + return this; + } + + public AlertsOption setLoopAnimation(boolean loopAnimation) { + this.loopAnimation = loopAnimation; + return this; + } + + public static class EffectOption { + + protected float effectAlpha = 1f; + protected boolean effectFadeOut = false; + protected Icon[] randomEffect; + + public EffectOption setEffectAlpha(float effectAlpha) { + this.effectAlpha = effectAlpha; + return this; + } + + public EffectOption setEffectFadeOut(boolean effectFadeOut) { + this.effectFadeOut = effectFadeOut; + return this; + } + + public EffectOption setRandomEffect(Icon[] randomEffect) { + this.randomEffect = randomEffect; + return this; + } + } + + + protected static AlertsOption getAlertsOption(MessageAlerts.MessageType messageType) { + if (messageType == MessageAlerts.MessageType.SUCCESS) { + Icon effects[] = new Icon[]{ + new FlatSVGIcon("raven/alerts/effect/check.svg"), + new FlatSVGIcon("raven/alerts/effect/star.svg"), + new FlatSVGIcon("raven/alerts/effect/firework.svg"), + new FlatSVGIcon("raven/alerts/effect/balloon.svg") + }; + return getDefaultOption("raven/alerts/icon/success.svg", Color.decode("#10b981"), effects); + } else if (messageType == MessageAlerts.MessageType.WARNING) { + Icon effects[] = new Icon[]{ + new FlatSVGIcon("raven/alerts/effect/disclaimer.svg"), + new FlatSVGIcon("raven/alerts/effect/warning.svg"), + new FlatSVGIcon("raven/alerts/effect/query.svg"), + new FlatSVGIcon("raven/alerts/effect/mark.svg") + }; + return getDefaultOption("raven/alerts/icon/warning.svg", Color.decode("#f59e0b"), effects); + } else if (messageType == MessageAlerts.MessageType.ERROR) { + Icon effects[] = new Icon[]{ + new FlatSVGIcon("raven/alerts/effect/error.svg"), + new FlatSVGIcon("raven/alerts/effect/sad.svg"), + new FlatSVGIcon("raven/alerts/effect/shield.svg"), + new FlatSVGIcon("raven/alerts/effect/nothing.svg") + }; + return getDefaultOption("raven/alerts/icon/error.svg", Color.decode("#ef4444"), effects); + } else { + return getDefaultOption("raven/alerts/icon/information.svg", null); + } + } + + private static AlertsOption getDefaultOption(String icon, Color color, Icon[] effects) { + AnimateIcon.AnimateOption option = new AnimateIcon.AnimateOption() + .setInterpolator(EasingInterpolator.EASE_OUT_BOUNCE) + .setScaleInterpolator(new KeyFrames(1f, 1.5f, 1f)) + .setRotateInterpolator(new KeyFrames(0f, (float) Math.toRadians(-30f), 0f)); + return new AlertsOption(new AnimateIcon(icon, 4f, option), color) + .setEffectOption(new EffectOption() + .setEffectAlpha(0.9f) + .setEffectFadeOut(true) + .setRandomEffect(effects)) + .setLoopAnimation(true); + } + + public static AlertsOption getDefaultOption(String icon, Color color) { + AnimateIcon.AnimateOption option = new AnimateIcon.AnimateOption() + .setScaleInterpolator(new KeyFrames(1f, 1.2f, 1f)) + .setRotateInterpolator(new KeyFrames(0f, (float) Math.toRadians(-30), (float) Math.toRadians(30), 0f)); + return new AlertsOption(new AnimateIcon(icon, 4f, option), color) + .setLoopAnimation(true); + } +} diff --git a/src/main/java/raven/alerts/MessageAlerts.java b/src/main/java/raven/alerts/MessageAlerts.java new file mode 100644 index 0000000..bd3b888 --- /dev/null +++ b/src/main/java/raven/alerts/MessageAlerts.java @@ -0,0 +1,101 @@ +package raven.alerts; + +import com.formdev.flatlaf.FlatClientProperties; +import net.miginfocom.swing.MigLayout; +import raven.popup.GlassPanePopup; +import raven.popup.component.PopupCallbackAction; + +import javax.swing.*; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import java.awt.*; + +public class MessageAlerts { + + private static MessageAlerts instance; + + public static final int DEFAULT_OPTION = -1; + public static final int YES_NO_OPTION = 0; + public static final int YES_NO_CANCEL_OPTION = 1; + public static final int OK_CANCEL_OPTION = 2; + + // Return values + public static final int YES_OPTION = 0; + public static final int NO_OPTION = 1; + public static final int CANCEL_OPTION = 2; + public static final int OK_OPTION = 0; + public static final int CLOSED_OPTION = -1; + + public static MessageAlerts getInstance() { + if (instance == null) { + instance = new MessageAlerts(); + } + return instance; + } + + private MessageAlerts() { + } + + public void showMessage(String title, String message) { + showMessage(title, message, MessageType.DEFAULT); + } + + public void showMessage(String title, String message, MessageType messageType) { + showMessage(title, message, messageType, DEFAULT_OPTION, null); + } + + public void showMessage(String title, String message, MessageType messageType, int option, PopupCallbackAction callback) { + AlertsOption alertsOption = AlertsOption.getAlertsOption(messageType); + GlassPanePopup.showPopup(new SimpleAlerts(createSimpleMessage(alertsOption, title, message), alertsOption, option, callback)); + } + + private Component createSimpleMessage(AlertsOption option, String title, String message) { + JPanel panel = new JPanel(new MigLayout("wrap,insets 0,center", "center")); + panel.setOpaque(false); + JLabel labelTitle = new JLabel(title); + JTextPane textPane = new JTextPane(); + textPane.setOpaque(false); + StyledDocument doc = textPane.getStyledDocument(); + SimpleAttributeSet center = new SimpleAttributeSet(); + StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); + doc.setParagraphAttributes(0, doc.getLength(), center, false); + textPane.setEditable(false); + textPane.setText(message); + textPane.putClientProperty(FlatClientProperties.STYLE, "" + + "border:5,25,5,25;" + + "[light]foreground:lighten(@foreground,30%);" + + "[dark]foreground:darken(@foreground,30%)"); + labelTitle.putClientProperty(FlatClientProperties.STYLE, "" + + "font:bold +5"); + if (option.baseColor != null) { + labelTitle.setForeground(option.baseColor); + } + panel.add(labelTitle); + JScrollPane scrollPane = new JScrollPane(textPane); + if (option.effectOption != null) { + scrollPane.setOpaque(false); + scrollPane.getViewport().setOpaque(false); + } + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + applyScrollStyle(scrollPane.getVerticalScrollBar()); + applyScrollStyle(scrollPane.getHorizontalScrollBar()); + panel.add(scrollPane); + SwingUtilities.invokeLater(() -> scrollPane.getVerticalScrollBar().setValue(0)); + return panel; + } + + private void applyScrollStyle(JScrollBar scrollBar) { + scrollBar.setUnitIncrement(10); + scrollBar.putClientProperty(FlatClientProperties.STYLE, "" + + "width:10;" + + "trackArc:999;" + + "thumbInsets:0,3,0,3;" + + "trackInsets:0,3,0,3;"); + } + + public enum MessageType { + SUCCESS, ERROR, WARNING, DEFAULT + } +} diff --git a/src/main/java/raven/alerts/SimpleAlerts.java b/src/main/java/raven/alerts/SimpleAlerts.java new file mode 100644 index 0000000..858d162 --- /dev/null +++ b/src/main/java/raven/alerts/SimpleAlerts.java @@ -0,0 +1,292 @@ +package raven.alerts; + +import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.extras.FlatSVGIcon; +import com.formdev.flatlaf.ui.FlatUIUtils; +import com.formdev.flatlaf.util.Animator; +import com.formdev.flatlaf.util.CubicBezierEasing; +import com.formdev.flatlaf.util.Graphics2DProxy; +import net.miginfocom.swing.MigLayout; +import raven.popup.GlassPanePopup; +import raven.popup.component.GlassPaneChild; +import raven.popup.component.PopupCallbackAction; +import raven.popup.component.PopupController; +import raven.swing.AnimateIcon; + +import javax.swing.*; +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.util.Random; + +public class SimpleAlerts extends GlassPaneChild { + + private PanelEffect panelEffect; + private final Component component; + private final int option; + + public SimpleAlerts(Component component, AlertsOption alertsOption, int option, PopupCallbackAction callbackAction) { + this.component = component; + this.option = option; + this.callbackAction = callbackAction; + init(alertsOption); + } + + private void init(AlertsOption alertsOption) { + setLayout(new MigLayout("wrap,fillx,insets 15 0 15 0", "[fill,400]")); + panelEffect = new PanelEffect(component, alertsOption); + add(panelEffect); + } + + @Override + public void popupShow() { + panelEffect.startAnimation(); + } + + @Override + public int getRoundBorder() { + return 20; + } + + protected class PanelEffect extends JPanel { + + private AlertsOption alertsOption; + private Effect effects[]; + private float animate; + private Animator animator; + private JLabel labelIcon; + private Component component; + private AnimateIcon animateIcon; + private MigLayout layout; + private Component closeButton; + + protected void start() { + if (animator == null) { + animator = new Animator(2000, new Animator.TimingTarget() { + @Override + public void timingEvent(float v) { + animate = v; + if (animateIcon != null) { + animateIcon.setAnimate(v); + } + repaint(); + } + + @Override + public void end() { + if (alertsOption.loopAnimation && isShowing()) { + SwingUtilities.invokeLater(() -> { + startAnimation(); + }); + } + } + }); + animator.setInterpolator(CubicBezierEasing.EASE); + } + if (animator.isRunning()) { + animator.stop(); + } + animator.start(); + } + + private void startAnimation() { + createEffect(); + start(); + } + + private void createEffect() { + if (alertsOption.effectOption != null) { + effects = new Effect[30]; + for (int i = 0; i < effects.length; i++) { + effects[i] = new Effect(alertsOption.effectOption.randomEffect); + } + } + } + + public PanelEffect(Component component, AlertsOption alertsOption) { + this.component = component; + this.alertsOption = alertsOption; + layout = new MigLayout("fillx,wrap,insets 0", "[fill,center]", "0[]3[]20[]5"); + setLayout(layout); + if (alertsOption.icon instanceof AnimateIcon) { + animateIcon = (AnimateIcon) alertsOption.icon; + } + labelIcon = new JLabel(alertsOption.icon); + labelIcon.putClientProperty(FlatClientProperties.STYLE, "" + + "border:25,5,10,5"); + boolean ltr = getComponentOrientation().isLeftToRight(); + closeButton = createCloseButton(); + add(closeButton, "pos " + (ltr ? "100%-pref-25" : "25") + " 2"); + add(labelIcon); + add(component); + add(createActionButton(option, alertsOption.baseColor)); + + } + + @Override + public void applyComponentOrientation(ComponentOrientation o) { + super.applyComponentOrientation(o); + boolean ltr = getComponentOrientation().isLeftToRight(); + layout.setComponentConstraints(closeButton, "pos " + (ltr ? "100%-pref-25" : "25") + " 2"); + } + + protected Component createCloseButton() { + JButton cmdClose = new JButton(new FlatSVGIcon("raven/popup/icon/close.svg", 0.8f)); + cmdClose.putClientProperty(FlatClientProperties.STYLE, "" + + "arc:999;" + + "borderWidth:0;" + + "focusWidth:0;" + + "innerFocusWidth:0;" + + "background:null"); + applyCloseButtonEvent(cmdClose, PopupCallbackAction.CLOSE); + return cmdClose; + } + + protected void applyCloseButtonEvent(JButton button, int opt) { + button.addActionListener(e -> { + if (callbackAction == null) { + GlassPanePopup.closePopup(SimpleAlerts.this); + return; + } + PopupController action = createController(); + callbackAction.action(action, opt); + if (!action.getConsume()) { + GlassPanePopup.closePopup(SimpleAlerts.this); + } + }); + } + + @Override + protected void paintChildren(Graphics g) { + if (alertsOption.effectOption != null && effects != null && effects.length > 0) { + Graphics2D g2 = (Graphics2D) g.create(); + FlatUIUtils.setRenderingHints(g2); + int width = getWidth(); + int height = getHeight(); + int x = labelIcon.getX() + labelIcon.getWidth() / 2; + int y = labelIcon.getY() + labelIcon.getHeight() / 2; + float size = Math.min(width, height) / 2; + + float l = size * animate; + + g2.translate(x, y); + + for (int i = 0; i < effects.length; i++) { + Effect effect = effects[i]; + double sp = effect.speed * 0.05f; + double xx = Math.cos(Math.toRadians(effect.direction)) * l * sp; + double yy = Math.sin(Math.toRadians(effect.direction)) * l * sp; + AffineTransform oldTran = g2.getTransform(); + Icon icon = alertsOption.effectOption.randomEffect[effect.effectIndex]; + int iw = icon.getIconWidth() / 2; + int ih = icon.getIconHeight() / 2; + xx -= iw; + yy -= ih; + g2.translate(xx, yy); + g2.rotate(Math.toRadians(animate * 360), iw, ih); + if (alertsOption.effectOption.effectAlpha < 1f) { + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alertsOption.effectOption.effectAlpha)); + } + if (alertsOption.effectOption.effectFadeOut) { + float remove = 0.7f; + if (animate >= remove) { + float f = ((animate - remove) / (1f - remove)) * alertsOption.effectOption.effectAlpha; + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alertsOption.effectOption.effectAlpha - f)); + } + } + icon.paintIcon(null, new GraphicsColorFilter(g2, effect.color), 0, 0); + g2.setTransform(oldTran); + } + g2.dispose(); + } + super.paintChildren(g); + } + + + private JPanel createActionButton(int option, Color color) { + JPanel panel = new JPanel(new MigLayout("insets 3,center,gapx 15", "[90,fill]")); + switch (option) { + case MessageAlerts.OK_CANCEL_OPTION: + panel.add(createButton("Cancel", null, MessageAlerts.CANCEL_OPTION)); + case MessageAlerts.DEFAULT_OPTION: + panel.add(createButton("OK", color, MessageAlerts.OK_OPTION), 0); + break; + case MessageAlerts.YES_NO_CANCEL_OPTION: + panel.add(createButton("Cancel", null, MessageAlerts.CANCEL_OPTION)); + case MessageAlerts.YES_NO_OPTION: + panel.add(createButton("No", null, MessageAlerts.NO_OPTION), 0); + panel.add(createButton("Yes", color, MessageAlerts.YES_OPTION), 0); + } + return panel; + } + + private JButton createButton(String text, Color color, int option) { + JButton cmd = new JButton(text); + applyCloseButtonEvent(cmd, option); + cmd.putClientProperty(FlatClientProperties.STYLE, "" + + "borderWidth:0;" + + "focusWidth:0;" + + "innerFocusWidth:0;" + + "arc:10;" + + "font:+1;" + + "margin:5,5,5,5;" + + "foreground:" + (color == null ? "null" : "#F0F0F0") + ";" + + "arc:999"); + if (color != null) { + cmd.setBackground(color); + } + return cmd; + } + } + + protected class Effect { + + protected int effectIndex; + protected Color color; + protected float direction; + protected float speed; + + public Effect(Icon[] randomEffect) { + Random random = new Random(); + color = effectColors[random.nextInt(effectColors.length)]; + if (randomEffect != null && randomEffect.length > 0) { + effectIndex = random.nextInt(randomEffect.length); + } + direction = random.nextInt(360); + speed = random.nextInt(25) + 5; + } + } + + protected static final Color effectColors[] = { + Color.decode("#f43f5e"), Color.decode("#6366f1"), + Color.decode("#ec4899"), Color.decode("#3b82f6"), + Color.decode("#d946ef"), Color.decode("#0ea5e9"), + Color.decode("#a855f7"), Color.decode("#06b6d4"), + Color.decode("#8b5cf6"), Color.decode("#14b8a6"), + Color.decode("#10b981"), Color.decode("#22c55e"), + Color.decode("#84cc16"), Color.decode("#eab308"), + Color.decode("#f59e0b"), Color.decode("#f97316"), + Color.decode("#ef4444"), Color.decode("#78716c"), + Color.decode("#737373"), Color.decode("#71717a"), + Color.decode("#6b7280"), Color.decode("#64748b") + }; + + private static class GraphicsColorFilter extends Graphics2DProxy { + + protected Color color; + + public GraphicsColorFilter(Graphics2D delegate, Color color) { + super(delegate); + this.color = color; + } + + @Override + public Graphics create() { + return new GraphicsColorFilter((Graphics2D) super.create(), this.color); + } + + @Override + public void setPaint(Paint paint) { + super.setPaint(color); + } + } +} diff --git a/src/main/java/raven/drawer/Drawer.java b/src/main/java/raven/drawer/Drawer.java index 8c4b4c0..2a8feb9 100644 --- a/src/main/java/raven/drawer/Drawer.java +++ b/src/main/java/raven/drawer/Drawer.java @@ -22,11 +22,11 @@ public static Drawer newInstance() { } private Drawer() { - option = new DrawerOption(); } public void setDrawerBuilder(DrawerBuilder drawerBuilder) { drawerPanel = new DrawerPanel(drawerBuilder); + option = new DrawerOption(drawerBuilder.getDrawerWidth()); drawerBuilder.build(drawerPanel); } @@ -34,13 +34,19 @@ public void showDrawer() { if (drawerPanel == null) { throw new NullPointerException("Drawer builder has not initialize"); } - GlassPanePopup.showPopup(drawerPanel, option, "drawer"); + if (!isShowing()) { + GlassPanePopup.showPopup(drawerPanel, option, "drawer"); + } } public void closeDrawer() { GlassPanePopup.closePopup("drawer"); } + public boolean isShowing() { + return GlassPanePopup.isShowing(drawerPanel); + } + public DrawerPanel getDrawerPanel() { return drawerPanel; } diff --git a/src/main/java/raven/drawer/DrawerOption.java b/src/main/java/raven/drawer/DrawerOption.java index ef03a99..e463af2 100644 --- a/src/main/java/raven/drawer/DrawerOption.java +++ b/src/main/java/raven/drawer/DrawerOption.java @@ -6,7 +6,15 @@ public class DrawerOption extends DefaultOption { - private final int width = 275; + private final int width; + + public DrawerOption() { + this(275); + } + + public DrawerOption(int width) { + this.width = width; + } @Override public String getLayout(Component parent, float animate) { diff --git a/src/main/java/raven/drawer/component/DrawerBuilder.java b/src/main/java/raven/drawer/component/DrawerBuilder.java index b4244ca..c0367fc 100644 --- a/src/main/java/raven/drawer/component/DrawerBuilder.java +++ b/src/main/java/raven/drawer/component/DrawerBuilder.java @@ -13,4 +13,6 @@ public interface DrawerBuilder { public Component getMenu(); public Component getFooter(); + + public int getDrawerWidth(); } diff --git a/src/main/java/raven/drawer/component/DrawerPanel.java b/src/main/java/raven/drawer/component/DrawerPanel.java index ca1b04a..0dbf9e4 100644 --- a/src/main/java/raven/drawer/component/DrawerPanel.java +++ b/src/main/java/raven/drawer/component/DrawerPanel.java @@ -39,21 +39,16 @@ private void init() { protected JScrollPane createScroll(Component component) { JScrollPane scroll = new JScrollPane(component); + scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scroll.putClientProperty(FlatClientProperties.STYLE, "" + "background:null"); scroll.getVerticalScrollBar().setUnitIncrement(10); scroll.getHorizontalScrollBar().setUnitIncrement(10); scroll.getVerticalScrollBar().putClientProperty(FlatClientProperties.STYLE, "" + - "width:6;" + + "width:9;" + "trackArc:999;" + - "thumbInsets:0,0,0,3;" + - "trackInsets:0,0,0,3;" + - "background:null"); - scroll.getHorizontalScrollBar().putClientProperty(FlatClientProperties.STYLE, "" + - "width:6;" + - "trackArc:999;" + - "thumbInsets:0,0,0,3;" + - "trackInsets:0,0,0,3;" + + "thumbInsets:0,3,0,3;" + + "trackInsets:0,3,0,3;" + "background:null"); scroll.setBorder(BorderFactory.createEmptyBorder()); return scroll; diff --git a/src/main/java/raven/drawer/component/SimpleDrawerBuilder.java b/src/main/java/raven/drawer/component/SimpleDrawerBuilder.java index 5aeda55..046ec1f 100644 --- a/src/main/java/raven/drawer/component/SimpleDrawerBuilder.java +++ b/src/main/java/raven/drawer/component/SimpleDrawerBuilder.java @@ -45,6 +45,11 @@ public Component getFooter() { return footer; } + @Override + public int getDrawerWidth() { + return 275; + } + public void build(DrawerPanel drawerPanel) { } diff --git a/src/main/java/raven/drawer/component/menu/MenuLayout.java b/src/main/java/raven/drawer/component/menu/MenuLayout.java index b79439e..c7ee284 100644 --- a/src/main/java/raven/drawer/component/menu/MenuLayout.java +++ b/src/main/java/raven/drawer/component/menu/MenuLayout.java @@ -1,5 +1,8 @@ package raven.drawer.component.menu; +import com.formdev.flatlaf.util.UIScale; +import raven.drawer.DrawerOption; + import java.awt.*; public class MenuLayout implements LayoutManager { @@ -16,13 +19,15 @@ public void removeLayoutComponent(Component comp) { public Dimension preferredLayoutSize(Container parent) { synchronized (parent.getTreeLock()) { Insets insets = parent.getInsets(); - int width = insets.left + insets.right; + // use parent width to avoid the issues right-to-left scroll pane + int width = parent.getParent().getWidth(); int height = insets.top + insets.bottom; int count = parent.getComponentCount(); for (int i = 0; i < count; i++) { Component com = parent.getComponent(i); if (com.isVisible()) { height += com.getPreferredSize().height; + width = Math.max(width, com.getPreferredSize().width); } } return new Dimension(width, height); diff --git a/src/main/java/raven/drawer/component/menu/SimpleMenu.java b/src/main/java/raven/drawer/component/menu/SimpleMenu.java index cd7cea9..3939599 100644 --- a/src/main/java/raven/drawer/component/menu/SimpleMenu.java +++ b/src/main/java/raven/drawer/component/menu/SimpleMenu.java @@ -232,11 +232,7 @@ protected JButton createSubMenuItem(String name, int index, int gap) { JButton button = new JButton(name); button.setHorizontalAlignment(JButton.LEADING); button.putClientProperty(FlatClientProperties.STYLE, "" + - "arc:0;" + - "margin:7," + (gap + 25) + ",7,20;" + - "borderWidth:0;" + - "focusWidth:0;" + - "innerFocusWidth:0;" + + "border:7," + (gap + 25) + ",7,20;" + "background:null"); return button; } @@ -245,6 +241,7 @@ protected JButton createSubMenuItem(String name, int index, int gap) { protected void paintChildren(Graphics g) { super.paintChildren(g); if (getComponentCount() > 0) { + boolean ltr = getComponentOrientation().isLeftToRight(); int menuHeight = getComponent(0).getHeight(); int width = getWidth(); int height = getHeight(); @@ -255,21 +252,21 @@ protected void paintChildren(Graphics g) { int round = UIScale.scale(8); int gap = UIScale.scale(20 + (iconWidth / 2)); Path2D.Double p = new Path2D.Double(); - int x = gap; + int x = ltr ? gap : width - gap; p.moveTo(x, menuHeight); p.lineTo(x, last - round); int count = getComponentCount(); for (int i = 1; i < count; i++) { Component com = getComponent(i); int y = com.getY() + (com.getHeight() / 2); - p.append(createCurve(round, x, y, true), false); + p.append(createCurve(round, x, y, ltr), false); } Color color = FlatLaf.isLafDark() ? ColorFunctions.darken(getForeground(), 0.6f) : ColorFunctions.lighten(getForeground(), 0.6f); g2.setColor(color); g2.setStroke(new BasicStroke(UIScale.scale(1f))); g2.draw(p); // Create arrow - paintArrow(g2, width, menuHeight, menuLayout.getAnimate()); + paintArrow(g2, width, menuHeight, menuLayout.getAnimate(), ltr); g2.dispose(); } } @@ -286,11 +283,11 @@ private Shape createCurve(int round, int x, int y, boolean ltr) { return p2; } - private void paintArrow(Graphics2D g2, int width, int height, float animate) { + private void paintArrow(Graphics2D g2, int width, int height, float animate, boolean ltr) { int arrowWidth = UIScale.scale(10); int arrowHeight = UIScale.scale(4); int gap = UIScale.scale(15); - int x = width - arrowWidth - gap; + int x = ltr ? (width - arrowWidth - gap) : gap; int y = (height - arrowHeight) / 2; Path2D p = new Path2D.Double(); p.moveTo(0, animate * arrowHeight); diff --git a/src/main/java/raven/popup/DefaultOption.java b/src/main/java/raven/popup/DefaultOption.java index a7bfcfb..353b350 100644 --- a/src/main/java/raven/popup/DefaultOption.java +++ b/src/main/java/raven/popup/DefaultOption.java @@ -1,5 +1,7 @@ package raven.popup; +import com.formdev.flatlaf.FlatLaf; + import java.awt.*; public class DefaultOption implements Option { @@ -35,7 +37,7 @@ public boolean blockBackground() { @Override public Color background() { - return new Color(20, 20, 20); + return FlatLaf.isLafDark()?new Color(50, 50, 50):new Color(20, 20, 20); } @Override diff --git a/src/main/java/raven/popup/GlassPanePopup.java b/src/main/java/raven/popup/GlassPanePopup.java index 2c8fda9..cdfe7ff 100644 --- a/src/main/java/raven/popup/GlassPanePopup.java +++ b/src/main/java/raven/popup/GlassPanePopup.java @@ -27,6 +27,8 @@ private void init() { protected void addAndShowPopup(GlassPaneChild component, Option option, String name) { GlassPopup popup = new GlassPopup(this, component, option); + instance.layerPane.applyComponentOrientation(instance.contentPane.getComponentOrientation()); + popup.applyComponentOrientation(instance.contentPane.getComponentOrientation()); if (name != null) { popup.setName(name); } @@ -166,6 +168,31 @@ public static void closePopupAll() { } } + public static boolean isShowing(String name) { + boolean act = false; + for (Component com : instance.layerPane.getComponents()) { + if (com.getName() != null && com.getName().equals(name)) { + act = true; + break; + } + } + return act; + } + + public static boolean isShowing(Component component) { + boolean act = false; + for (Component com : instance.layerPane.getComponents()) { + if (com instanceof GlassPopup) { + GlassPopup popup = (GlassPopup) com; + if (popup.getComponent() == component) { + act = true; + break; + } + } + } + return act; + } + public static int getPopupCount() { return instance.layerPane.getComponentCount(); } diff --git a/src/main/java/raven/popup/GlassPopup.java b/src/main/java/raven/popup/GlassPopup.java index f219b65..0dbf2dc 100644 --- a/src/main/java/raven/popup/GlassPopup.java +++ b/src/main/java/raven/popup/GlassPopup.java @@ -98,7 +98,9 @@ public void begin() { @Override public void end() { componentLayer.hideSnapshot(); - if (!show) { + if (show) { + componentLayer.getComponent().popupShow(); + } else { parent.removePopup(GlassPopup.this); } if (option.useSnapshot()) { diff --git a/src/main/java/raven/popup/component/ComponentLayer.java b/src/main/java/raven/popup/component/ComponentLayer.java index 17fa87b..f8a3827 100644 --- a/src/main/java/raven/popup/component/ComponentLayer.java +++ b/src/main/java/raven/popup/component/ComponentLayer.java @@ -78,6 +78,7 @@ public void begin() { public void end() { showSnapshot = false; component = nextComponent; + component.popupShow(); nextComponent = null; animate = 0; component.setVisible(true); diff --git a/src/main/java/raven/popup/component/GlassPaneChild.java b/src/main/java/raven/popup/component/GlassPaneChild.java index 6ea8cf3..406e4c9 100644 --- a/src/main/java/raven/popup/component/GlassPaneChild.java +++ b/src/main/java/raven/popup/component/GlassPaneChild.java @@ -21,6 +21,9 @@ public void onPop() { } + public void popupShow() { + } + protected PopupController createController() { return new PopupController() { diff --git a/src/main/java/raven/popup/component/PopupController.java b/src/main/java/raven/popup/component/PopupController.java index dcb8265..098d36f 100644 --- a/src/main/java/raven/popup/component/PopupController.java +++ b/src/main/java/raven/popup/component/PopupController.java @@ -4,7 +4,7 @@ public abstract class PopupController { private boolean consume; - protected boolean getConsume() { + public boolean getConsume() { return consume; } diff --git a/src/main/java/raven/popup/component/SimplePopupBorder.java b/src/main/java/raven/popup/component/SimplePopupBorder.java index 4c7efed..f86c46f 100644 --- a/src/main/java/raven/popup/component/SimplePopupBorder.java +++ b/src/main/java/raven/popup/component/SimplePopupBorder.java @@ -65,8 +65,10 @@ private void init() { private void applyScrollStyle(JScrollBar scrollBar) { scrollBar.setUnitIncrement(10); scrollBar.putClientProperty(FlatClientProperties.STYLE, "" + - "thumbInsets:0,0,0,3;" + - "trackInsets:0,0,0,3;"); + "width:10;" + + "trackArc:999;" + + "thumbInsets:0,3,0,3;" + + "trackInsets:0,3,0,3;"); } protected Component createTitle(String title) { diff --git a/src/main/java/raven/swing/AnimateIcon.java b/src/main/java/raven/swing/AnimateIcon.java new file mode 100644 index 0000000..de53cf7 --- /dev/null +++ b/src/main/java/raven/swing/AnimateIcon.java @@ -0,0 +1,102 @@ +package raven.swing; + + +import com.formdev.flatlaf.extras.FlatSVGIcon; +import com.formdev.flatlaf.util.Animator; +import com.formdev.flatlaf.util.CubicBezierEasing; + +import java.awt.*; +import java.awt.geom.AffineTransform; + +public class AnimateIcon extends FlatSVGIcon { + + private Component component; + + private Animator animator; + private AnimateOption animateOption; + private float animate; + + public AnimateIcon(String name, float scale) { + this(name, scale, new AnimateOption()); + } + + public AnimateIcon(String name, float scale, AnimateOption animateOption) { + super(name, scale); + this.animateOption = animateOption; + } + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if (c != component) { + component = c; + } + float scale = getInterpolator(animateOption.scaleInterpolator, animate, 1); + if (scale > 0) { + Graphics2D g2 = (Graphics2D) g; + AffineTransform tran = g2.getTransform(); + int centerX = x + getIconWidth() / 2; + int centerY = y + getIconHeight() / 2; + g2.translate(centerX, centerY); + g2.rotate(getInterpolator(animateOption.rotateInterpolator, animate, 0)); + g2.scale(scale, scale); + g2.translate(-centerX, -centerY); + super.paintIcon(c, g, x, y); + g2.setTransform(tran); + } + } + + protected float getInterpolator(Animator.Interpolator interpolator, float fraction, float isNull) { + if (interpolator != null) { + return interpolator.interpolate(fraction); + } else { + return isNull; + } + } + + + public void setAnimate(float f) { + this.animate = getInterpolator(animateOption.interpolator, f, f); + if (component != null) { + component.repaint(); + } + } + + public boolean animate() { + boolean act = false; + if (component != null) { + if (animator == null) { + animator = new Animator(2000, (float f) -> { + setAnimate(f); + }); + animator.setInterpolator(CubicBezierEasing.EASE); + } + if (!animator.isRunning()) { + animator.start(); + act = true; + } + } + return act; + } + + public static class AnimateOption { + + protected Animator.Interpolator interpolator; + protected Animator.Interpolator scaleInterpolator; + protected Animator.Interpolator rotateInterpolator; + + public AnimateOption setInterpolator(Animator.Interpolator interpolator) { + this.interpolator = interpolator; + return this; + } + + public AnimateOption setScaleInterpolator(Animator.Interpolator scaleInterpolator) { + this.scaleInterpolator = scaleInterpolator; + return this; + } + + public AnimateOption setRotateInterpolator(Animator.Interpolator rotateInterpolator) { + this.rotateInterpolator = rotateInterpolator; + return this; + } + } +} \ No newline at end of file diff --git a/src/main/java/raven/swing/animator/EasingInterpolator.java b/src/main/java/raven/swing/animator/EasingInterpolator.java new file mode 100644 index 0000000..545ff96 --- /dev/null +++ b/src/main/java/raven/swing/animator/EasingInterpolator.java @@ -0,0 +1,30 @@ +package raven.swing.animator; + +import com.formdev.flatlaf.util.Animator; + +public abstract class EasingInterpolator implements Animator.Interpolator { + + public static final EasingInterpolator EASE_OUT_BOUNCE = new EaseOutBounce(); + + + private static class EaseOutBounce extends EasingInterpolator { + + @Override + public float interpolate(float f) { + float n1 = 7.5625f; + float d1 = 2.75f; + double v; + if (f < 1 / d1) { + v = n1 * f * f; + } else if (f < 2 / d1) { + v = n1 * (f -= 1.5 / d1) * f + 0.75; + } else if (f < 2.5 / d1) { + v = n1 * (f -= 2.25 / d1) * f + 0.9375; + } else { + v = n1 * (f -= 2.625 / d1) * f + 0.984375; + } + return (float) v; + } + } + +} diff --git a/src/main/java/raven/swing/animator/Evaluator.java b/src/main/java/raven/swing/animator/Evaluator.java new file mode 100644 index 0000000..ad5088b --- /dev/null +++ b/src/main/java/raven/swing/animator/Evaluator.java @@ -0,0 +1,6 @@ +package raven.swing.animator; + +public abstract class Evaluator { + + public abstract T evaluate(T from, T target, float fraction); +} diff --git a/src/main/java/raven/swing/animator/EvaluatorFloat.java b/src/main/java/raven/swing/animator/EvaluatorFloat.java new file mode 100644 index 0000000..d603416 --- /dev/null +++ b/src/main/java/raven/swing/animator/EvaluatorFloat.java @@ -0,0 +1,9 @@ +package raven.swing.animator; + +public class EvaluatorFloat extends Evaluator { + + @Override + public Float evaluate(Float from, Float target, float fraction) { + return from + ((target - from) * fraction); + } +} diff --git a/src/main/java/raven/swing/animator/KeyFrames.java b/src/main/java/raven/swing/animator/KeyFrames.java new file mode 100644 index 0000000..fb76732 --- /dev/null +++ b/src/main/java/raven/swing/animator/KeyFrames.java @@ -0,0 +1,31 @@ +package raven.swing.animator; + +import com.formdev.flatlaf.util.Animator; + +public class KeyFrames implements Animator.Interpolator { + + private final EvaluatorFloat evaluator = new EvaluatorFloat(); + private final float values[]; + + public KeyFrames(float... values) { + if (values.length == 0) { + throw new IllegalArgumentException("number of array can't be empty"); + } else if (values.length == 1) { + throw new IllegalArgumentException("number of array must be > 1"); + } + this.values = values; + } + + @Override + public float interpolate(float fraction) { + float frame = fraction * (values.length - 1); + int index = (int) frame; + if (index >= values.length - 1) { + return values[values.length - 1]; + } + float time = frame - (float) index; + float from = values[index]; + float target = values[index + 1]; + return evaluator.evaluate(from, target, time); + } +} diff --git a/src/main/resources/raven/alerts/effect/balloon.svg b/src/main/resources/raven/alerts/effect/balloon.svg new file mode 100644 index 0000000..9fc9786 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/balloon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/check.svg b/src/main/resources/raven/alerts/effect/check.svg new file mode 100644 index 0000000..c18fa55 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/disclaimer.svg b/src/main/resources/raven/alerts/effect/disclaimer.svg new file mode 100644 index 0000000..a79c0b0 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/disclaimer.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/error.svg b/src/main/resources/raven/alerts/effect/error.svg new file mode 100644 index 0000000..e9c324e --- /dev/null +++ b/src/main/resources/raven/alerts/effect/error.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/firework.svg b/src/main/resources/raven/alerts/effect/firework.svg new file mode 100644 index 0000000..d8199e7 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/firework.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/mark.svg b/src/main/resources/raven/alerts/effect/mark.svg new file mode 100644 index 0000000..f7ad079 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/mark.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/nothing.svg b/src/main/resources/raven/alerts/effect/nothing.svg new file mode 100644 index 0000000..041e7f9 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/nothing.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/query.svg b/src/main/resources/raven/alerts/effect/query.svg new file mode 100644 index 0000000..9396385 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/query.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/sad.svg b/src/main/resources/raven/alerts/effect/sad.svg new file mode 100644 index 0000000..cbe2da9 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/sad.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/shield.svg b/src/main/resources/raven/alerts/effect/shield.svg new file mode 100644 index 0000000..7dcf83d --- /dev/null +++ b/src/main/resources/raven/alerts/effect/shield.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/star.svg b/src/main/resources/raven/alerts/effect/star.svg new file mode 100644 index 0000000..3d6ef0e --- /dev/null +++ b/src/main/resources/raven/alerts/effect/star.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/effect/warning.svg b/src/main/resources/raven/alerts/effect/warning.svg new file mode 100644 index 0000000..1b98693 --- /dev/null +++ b/src/main/resources/raven/alerts/effect/warning.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/icon/error.svg b/src/main/resources/raven/alerts/icon/error.svg new file mode 100644 index 0000000..a207467 --- /dev/null +++ b/src/main/resources/raven/alerts/icon/error.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/icon/information.svg b/src/main/resources/raven/alerts/icon/information.svg new file mode 100644 index 0000000..d96170f --- /dev/null +++ b/src/main/resources/raven/alerts/icon/information.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/icon/question.svg b/src/main/resources/raven/alerts/icon/question.svg new file mode 100644 index 0000000..ba83784 --- /dev/null +++ b/src/main/resources/raven/alerts/icon/question.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/icon/success.svg b/src/main/resources/raven/alerts/icon/success.svg new file mode 100644 index 0000000..e8946ea --- /dev/null +++ b/src/main/resources/raven/alerts/icon/success.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/raven/alerts/icon/warning.svg b/src/main/resources/raven/alerts/icon/warning.svg new file mode 100644 index 0000000..4cb5824 --- /dev/null +++ b/src/main/resources/raven/alerts/icon/warning.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/test/Demo.java b/src/test/java/test/Demo.java index 9eba112..d2c8597 100644 --- a/src/test/java/test/Demo.java +++ b/src/test/java/test/Demo.java @@ -13,10 +13,10 @@ public class Demo extends JFrame { public Demo() { + // applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); GlassPanePopup.install(this); MyDrawerBuilder myDrawerBuilder = new MyDrawerBuilder(); Drawer.getInstance().setDrawerBuilder(myDrawerBuilder); - setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(new Dimension(1366, 768)); setLocationRelativeTo(null); diff --git a/src/test/java/test/DemoAlerts.java b/src/test/java/test/DemoAlerts.java new file mode 100644 index 0000000..61ef4d6 --- /dev/null +++ b/src/test/java/test/DemoAlerts.java @@ -0,0 +1,95 @@ +package test; + +import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.fonts.roboto.FlatRobotoFont; +import com.formdev.flatlaf.themes.FlatMacDarkLaf; +import net.miginfocom.swing.MigLayout; +import raven.alerts.MessageAlerts; +import raven.popup.GlassPanePopup; + +import javax.swing.*; +import java.awt.*; + +public class DemoAlerts extends JFrame { + + public DemoAlerts() { + //applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + GlassPanePopup.install(this); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(new Dimension(1366, 768)); + setLocationRelativeTo(null); + setLayout(new MigLayout("")); + JButton cmd = new JButton("Show Simple Alerts"); + cmd.addActionListener(e -> { + String title = "Data Save Successful"; + String message = getSample(); + // MessageAlerts.getInstance().showMessage(title, message, MessageAlerts.MessageType.DEFAULT, MessageAlerts.YES_NO_CANCEL_OPTION, (controller, action) -> { + //if(action==MessageAlerts.CLOSED_OPTION){ + // controller.consume(); + // System.out.println("User press yes"); + // } + // }); + MessageAlerts.getInstance().showMessage("Data Saving Failure", "Oops! We encountered an issue while attempting to save your data. Please try again later or contact support for assistance. Apologies for any inconvenience caused.", MessageAlerts.MessageType.ERROR,MessageAlerts.OK_CANCEL_OPTION,null); + }); + add(cmd); + } + + public String getSample() { + return "These terms and conditions outline the rules and regulations for the use of Raven Channel's Website.\n" + + "\n" + + "By accessing this website, we assume you accept these terms and conditions in full. Do not continue to use Raven Channel's website if you do not accept all of the terms and conditions stated on this page.\n" + + "\n" + + "The following terminology applies to these Terms and Conditions, Privacy Statement, and Disclaimer Notice and any or all Agreements: \"Client,\" \"You,\" and \"Your\" refers to you, the person accessing this website and accepting the Company's terms and conditions. \"The Company,\" \"Ourselves,\" \"We,\" \"Our,\" and \"Us,\" refers to Raven Channel. \"Party,\" \"Parties,\" or \"Us,\" refers to both the Client and ourselves, or either the Client or ourselves.\n" + + "\n" + + "Cookies\n" + + "\n" + + "We employ the use of cookies. By accessing Raven Channel's website, you agree to use cookies in agreement with Raven Channel's Privacy Policy.\n" + + "\n" + + "Most interactive websites use cookies to retrieve user details for each visit. Cookies are used by our website to enable the functionality of certain areas to make it easier for people visiting our website. Some of our affiliate/advertising partners may also use cookies.\n" + + "\n" + + "License\n" + + "\n" + + "Unless otherwise stated, Raven Channel and/or its licensors own the intellectual property rights for all material on Raven Channel. All intellectual property rights are reserved. You may access this from Raven Channel for your personal use subjected to restrictions set in these terms and conditions.\n" + + "\n" + + "You must not:\n" + + "\n" + + "Republish material from Raven Channel\n" + + "Sell, rent, or sub-license material from Raven Channel\n" + + "Reproduce, duplicate, or copy material from Raven Channel\n" + + "Redistribute content from Raven Channel\n" + + "This Agreement shall begin on the date hereof.\n" + + "\n" + + "Disclaimer\n" + + "\n" + + "To the maximum extent permitted by applicable law, we exclude all representations, warranties, and conditions relating to our website and the use of this website. Nothing in this disclaimer will:\n" + + "\n" + + "Limit or exclude our or your liability for death or personal injury.\n" + + "Limit or exclude our or your liability for fraud or fraudulent misrepresentation.\n" + + "Limit any of our or your liabilities in any way that is not permitted under applicable law.\n" + + "The limitations and prohibitions of liability set in this Section and elsewhere in this disclaimer: (a) are subject to the preceding paragraph; and (b) govern all liabilities arising under the disclaimer, including liabilities arising in contract, in tort, and for breach of statutory duty.\n" + + "\n" + + "As long as the website and the information and services on the website are provided free of charge, we will not be liable for any loss or damage of any nature.\n" + + "\n" + + "Reservation of Rights\n" + + "\n" + + "We reserve the right to request that you remove all links or any particular link to our website. You approve to immediately remove all links to our website upon request. We also reserve the right to amend these terms and conditions and it’s linking policy at any time. By continuously linking to our website, you agree to be bound to and follow these linking terms and conditions.\n" + + "\n" + + "Variation of Terms\n" + + "\n" + + "Raven Channel is permitted to revise these terms at any time as it sees fit, and by using this website, you are expected to review these terms on a regular basis.\n" + + "\n" + + "Governing Law & Jurisdiction\n" + + "\n" + + "These terms will be governed by and interpreted in accordance with the laws of the jurisdiction of [Your Company's Jurisdiction], and you submit to the non-exclusive jurisdiction of the state and federal courts located in [Your Company's Jurisdiction] for the resolution of any disputes.\n" + + "\n" + + "These terms and conditions have been generated at [Terms And Conditions Generator], the technology law firm."; + } + + public static void main(String[] args) { + FlatRobotoFont.install(); + FlatLaf.registerCustomDefaultsSource("themes"); + UIManager.put("defaultFont", new Font(FlatRobotoFont.FAMILY, Font.PLAIN, 13)); + FlatMacDarkLaf.setup(); + EventQueue.invokeLater(() -> new DemoAlerts().setVisible(true)); + } +} diff --git a/src/test/java/test/MyDrawerBuilder.java b/src/test/java/test/MyDrawerBuilder.java index 61c0cdb..c76f461 100644 --- a/src/test/java/test/MyDrawerBuilder.java +++ b/src/test/java/test/MyDrawerBuilder.java @@ -93,4 +93,9 @@ public void build(DrawerPanel drawerPanel) { // header.putClientProperty(FlatClientProperties.STYLE,"" + // "background:#E36E1D"); } + + @Override + public int getDrawerWidth() { + return 275; + } } diff --git a/src/test/java/test/TestSampleMessage.java b/src/test/java/test/TestSampleMessage.java new file mode 100644 index 0000000..cb1f854 --- /dev/null +++ b/src/test/java/test/TestSampleMessage.java @@ -0,0 +1,50 @@ +package test; + +import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.fonts.roboto.FlatRobotoFont; +import com.formdev.flatlaf.themes.FlatMacDarkLaf; +import net.miginfocom.swing.MigLayout; +import raven.drawer.Drawer; +import raven.popup.GlassPanePopup; +import raven.popup.component.SimplePopupBorder; +import raven.popup.component.SimplePopupBorderOption; + +import javax.swing.*; +import java.awt.*; + +public class TestSampleMessage extends JFrame { + + public TestSampleMessage() { + GlassPanePopup.install(this); + MyDrawerBuilder myDrawerBuilder = new MyDrawerBuilder(); + Drawer.getInstance().setDrawerBuilder(myDrawerBuilder); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(new Dimension(1366, 768)); + setLocationRelativeTo(null); + setLayout(new MigLayout("")); + JButton cmd = new JButton("Show Message"); + cmd.addActionListener(e -> { + JTextPane txt = new JTextPane(); + txt.setText("Your account has been logged into from a new device. If this was not you, please secure your account immediately by changing your password and enabling two-factor authentication. Thank you."); + txt.putClientProperty(FlatClientProperties.STYLE, "" + + "border:10,25,10,25;" + + "[light]foreground:lighten(@foreground,30%);" + + "[dark]foreground:darken(@foreground,30%)"); + txt.setEditable(false); + String actions[] = new String[]{"Cancel", "Ok"}; + GlassPanePopup.showPopup(new SimplePopupBorder(txt, "Sample Message",new SimplePopupBorderOption().useScroll(), actions, (controller, action) -> { + controller.closePopup(); + })); + }); + add(cmd); + } + + public static void main(String[] args) { + FlatRobotoFont.install(); + FlatLaf.registerCustomDefaultsSource("themes"); + UIManager.put("defaultFont", new Font(FlatRobotoFont.FAMILY, Font.PLAIN, 13)); + FlatMacDarkLaf.setup(); + EventQueue.invokeLater(() -> new TestSampleMessage().setVisible(true)); + } +} diff --git a/src/test/resources/themes/FlatLaf.properties b/src/test/resources/themes/FlatLaf.properties index 5c74111..4f7f3dc 100644 --- a/src/test/resources/themes/FlatLaf.properties +++ b/src/test/resources/themes/FlatLaf.properties @@ -1,3 +1,5 @@ +@accentColor=#1BC2BB + TitlePane.unifiedBackground=false TitlePane.buttonSize=35,23 \ No newline at end of file