forked from fanruan/design
Browse Source
* commit 'ba85608517815a68ca01eb8cec3e29636a27216e': 无jira任务 继承替换 REPORT-19945 设计器启动优化和启动速度监控 REPORT-16346 优化一些UI上突出的一些重复创建的界面persist/11.0
vito
5 years ago
41 changed files with 1081 additions and 498 deletions
@ -0,0 +1,49 @@ |
|||||||
|
package com.fr.design.ui.util; |
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import java.lang.reflect.InvocationTargetException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 事件分发线程管理器。用于管理用户线程 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @version 10.0 |
||||||
|
* Created by vito on 2019/9/16 |
||||||
|
*/ |
||||||
|
public abstract class EdtInvocationManager { |
||||||
|
@NotNull |
||||||
|
private static EdtInvocationManager ourInstance = new SwingEdtInvocationManager(); |
||||||
|
|
||||||
|
public abstract boolean isEventDispatchThread(); |
||||||
|
|
||||||
|
public abstract void invokeLater(@NotNull Runnable task); |
||||||
|
|
||||||
|
public abstract void invokeAndWait(@NotNull Runnable task) throws InvocationTargetException, InterruptedException; |
||||||
|
|
||||||
|
@NotNull |
||||||
|
public static EdtInvocationManager getInstance() { |
||||||
|
return ourInstance; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* The default {@link EdtInvocationManager} implementation which works with the EDT via SwingUtilities. |
||||||
|
*/ |
||||||
|
private static class SwingEdtInvocationManager extends EdtInvocationManager { |
||||||
|
@Override |
||||||
|
public boolean isEventDispatchThread() { |
||||||
|
return SwingUtilities.isEventDispatchThread(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void invokeLater(@NotNull Runnable task) { |
||||||
|
SwingUtilities.invokeLater(task); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void invokeAndWait(@NotNull Runnable task) throws InvocationTargetException, InterruptedException { |
||||||
|
SwingUtilities.invokeAndWait(task); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
package com.fr.design.ui.util; |
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 图形渲染配置 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @version 10.0 |
||||||
|
* Created by vito on 2019/9/18 |
||||||
|
*/ |
||||||
|
public class GraphicsConfig { |
||||||
|
private final Graphics2D myG; |
||||||
|
private final Map myHints; |
||||||
|
private final Composite myComposite; |
||||||
|
private final Stroke myStroke; |
||||||
|
|
||||||
|
public GraphicsConfig(@NotNull Graphics g) { |
||||||
|
myG = (Graphics2D) g; |
||||||
|
myHints = (Map) myG.getRenderingHints().clone(); |
||||||
|
myComposite = myG.getComposite(); |
||||||
|
myStroke = myG.getStroke(); |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig setAntialiasing(boolean on) { |
||||||
|
myG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, on ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig setAlpha(float alpha) { |
||||||
|
myG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { |
||||||
|
myG.setRenderingHint(hintKey, hintValue); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Graphics2D getG() { |
||||||
|
return myG; |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig setComposite(Composite composite) { |
||||||
|
myG.setComposite(composite); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig setStroke(Stroke stroke) { |
||||||
|
myG.setStroke(stroke); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig setupAAPainting() { |
||||||
|
return setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) |
||||||
|
.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig disableAAPainting() { |
||||||
|
return setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF) |
||||||
|
.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); |
||||||
|
} |
||||||
|
|
||||||
|
public GraphicsConfig paintWithAlpha(float alpha) { |
||||||
|
assert 0.0f <= alpha && alpha <= 1.0f : "alpha should be in range 0.0f .. 1.0f"; |
||||||
|
return setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); |
||||||
|
} |
||||||
|
|
||||||
|
public void restore() { |
||||||
|
myG.setRenderingHints(myHints); |
||||||
|
myG.setComposite(myComposite); |
||||||
|
myG.setStroke(myStroke); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package com.fr.design.ui.util; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
|
||||||
|
/** |
||||||
|
* 一些常用的 GUI 工具。 |
||||||
|
* <p> |
||||||
|
* 为什么提供 invokeLaterIfNeeded 和 invokeAndWaitIfNeeded这样的方法? |
||||||
|
* 因为 swing 渲染 UI 是单线程的,如果直接使用 |
||||||
|
* {@link SwingUtilities#invokeLater(Runnable)},当 invokeLater 方法 |
||||||
|
* 嵌套的时候,Runnable 会被放到事件循环队列的末尾,从而变成异步而非立即执行, |
||||||
|
* 这是一处坑点。invokeLaterIfNeeded 的行为,当处于事件分发线程(EDT), |
||||||
|
* 则直接运行,当处于其他线程,则使用 EDT 来执行。 |
||||||
|
* <p> |
||||||
|
* 方法{@link SwingUtilities#invokeAndWait(Runnable)},也有一个注意点, |
||||||
|
* 不允许在事件分发线程(EDT)中调用,否则抛错,所以也有必要加上判断 EDT 的逻辑。 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @version 10.0 |
||||||
|
* Created by vito on 2019/9/16 |
||||||
|
*/ |
||||||
|
public class UIUtil { |
||||||
|
/** |
||||||
|
* 在 AWT 线程上立即调用runnable,否则使用 {@link SwingUtilities#invokeLater(Runnable)} 代替。 |
||||||
|
* |
||||||
|
* @param runnable 等待调用的 runnable |
||||||
|
*/ |
||||||
|
public static void invokeLaterIfNeeded(@NotNull Runnable runnable) { |
||||||
|
if (EdtInvocationManager.getInstance().isEventDispatchThread()) { |
||||||
|
runnable.run(); |
||||||
|
} else { |
||||||
|
EdtInvocationManager.getInstance().invokeLater(runnable); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 在 AWT 线程上立即调用runnable,否则使用 {@link SwingUtilities#invokeAndWait(Runnable)} 代替。 |
||||||
|
* |
||||||
|
* @param runnable 等待调用的 runnable |
||||||
|
*/ |
||||||
|
public static void invokeAndWaitIfNeeded(@NotNull Runnable runnable) { |
||||||
|
if (EdtInvocationManager.getInstance().isEventDispatchThread()) { |
||||||
|
runnable.run(); |
||||||
|
} else { |
||||||
|
try { |
||||||
|
EdtInvocationManager.getInstance().invokeAndWait(runnable); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
package com.fr.start.common; |
||||||
|
|
||||||
|
import com.fr.design.ui.util.UIUtil; |
||||||
|
import com.fr.start.SplashStrategy; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 静态启动画面 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @version 10.0 |
||||||
|
* Created by vito on 2019年9月16日 |
||||||
|
*/ |
||||||
|
public class SplashCommon implements SplashStrategy { |
||||||
|
|
||||||
|
private SplashWindow splashWindow; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void show() { |
||||||
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
splashWindow = new SplashWindow(); |
||||||
|
splashWindow.setVisible(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void hide() { |
||||||
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (splashWindow != null) { |
||||||
|
splashWindow.setVisible(false); |
||||||
|
splashWindow.dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateModuleLog(final String text) { |
||||||
|
UIUtil.invokeAndWaitIfNeeded(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (splashWindow != null) { |
||||||
|
splashWindow.updateModuleLog(text); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateThanksLog(final String text) { |
||||||
|
UIUtil.invokeLaterIfNeeded(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
if (splashWindow != null) { |
||||||
|
splashWindow.updateThanksLog(text); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,120 @@ |
|||||||
|
package com.fr.start.common; |
||||||
|
|
||||||
|
import com.bulenkov.iconloader.IconLoader; |
||||||
|
import com.bulenkov.iconloader.util.JBUI; |
||||||
|
import com.fr.base.GraphHelper; |
||||||
|
import com.fr.design.ui.util.GraphicsConfig; |
||||||
|
import com.fr.stable.GraphDrawHelper; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.os.OperatingSystem; |
||||||
|
import com.fr.value.NotNullLazyValue; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
/** |
||||||
|
* 启动画面面板 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @version 10.0 |
||||||
|
* Created by vito on 2019/09/12 |
||||||
|
*/ |
||||||
|
public class SplashPane extends JPanel { |
||||||
|
|
||||||
|
private static String OEM_PATH = "/com/fr/design/images/splash_10.png"; |
||||||
|
private static float JBUI_INIT_SCALE = JBUI.scale(1f); |
||||||
|
|
||||||
|
private static final Color MODULE_COLOR = new Color(255, 255, 255); |
||||||
|
private static final int MODULE_INFO_X = uiScale(36); |
||||||
|
private static final int MODULE_INFO_Y = uiScale(339); |
||||||
|
|
||||||
|
private static final Color THANK_COLOR = new Color(255, 255, 255, (int) (0.6 * 255 + 0.5)); |
||||||
|
private static final int THANK_INFO_X = uiScale(470); |
||||||
|
private static final int FONT_SIZE = uiScale(12); |
||||||
|
|
||||||
|
private static final int MODULE_INFO_WIDTH = uiScale(150); |
||||||
|
private static final int MODULE_INFO_HEIGHT = uiScale(20); |
||||||
|
|
||||||
|
private static final String ARIAL_FONT_NAME = "Arial"; |
||||||
|
private static final String YAHEI_FONT_NAME = "Microsoft YaHei"; |
||||||
|
|
||||||
|
private String thanksLog = StringUtils.EMPTY; |
||||||
|
private String moduleText = StringUtils.EMPTY; |
||||||
|
|
||||||
|
private static int uiScale(int i) { |
||||||
|
return (int) (i * JBUI_INIT_SCALE); |
||||||
|
} |
||||||
|
|
||||||
|
private NotNullLazyValue<Font> fontValue = new NotNullLazyValue<Font>() { |
||||||
|
@NotNull |
||||||
|
@Override |
||||||
|
protected Font compute() { |
||||||
|
Font font = null; |
||||||
|
if (OperatingSystem.isWindows()) { |
||||||
|
font = createFont(YAHEI_FONT_NAME); |
||||||
|
} |
||||||
|
if (font == null || isDialogFont(font)) { |
||||||
|
font = createFont(ARIAL_FONT_NAME); |
||||||
|
} |
||||||
|
return font; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintComponent(Graphics g) { |
||||||
|
super.paintComponent(g); |
||||||
|
Icon icon = IconLoader.getIcon(OEM_PATH); |
||||||
|
icon.paintIcon(null, g, 0, 0); |
||||||
|
paintShowText((Graphics2D) g); |
||||||
|
g.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
protected void paintShowText(Graphics2D g) { |
||||||
|
GraphicsConfig config = new GraphicsConfig(g).setupAAPainting(); |
||||||
|
|
||||||
|
g.setPaint(MODULE_COLOR); |
||||||
|
g.setFont(fontValue.getValue()); |
||||||
|
|
||||||
|
//加载模块信息
|
||||||
|
GraphDrawHelper.drawString(g, moduleText, MODULE_INFO_X, MODULE_INFO_Y); |
||||||
|
|
||||||
|
//感谢用户信息
|
||||||
|
if (StringUtils.isNotEmpty(thanksLog)) { |
||||||
|
g.setPaint(THANK_COLOR); |
||||||
|
GraphHelper.drawString(g, thanksLog, THANK_INFO_X, MODULE_INFO_Y); |
||||||
|
} |
||||||
|
config.restore(); |
||||||
|
} |
||||||
|
|
||||||
|
Dimension getSplashDimension() { |
||||||
|
Icon icon = IconLoader.getIcon(OEM_PATH); |
||||||
|
return new Dimension(icon.getIconWidth(), icon.getIconHeight()); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isDialogFont(Font font) { |
||||||
|
return Font.DIALOG.equals(font.getFamily(Locale.US)); |
||||||
|
} |
||||||
|
|
||||||
|
private Font createFont(String fontName) { |
||||||
|
return new Font(fontName, Font.PLAIN, FONT_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置在启动过程中, 动态改变的文本, 如 当前启动的模块信息 |
||||||
|
* |
||||||
|
* @param text 指定的文本 |
||||||
|
*/ |
||||||
|
void updateModuleLog(String text) { |
||||||
|
moduleText = text; |
||||||
|
repaint(MODULE_INFO_X, MODULE_INFO_Y - FONT_SIZE, MODULE_INFO_WIDTH, MODULE_INFO_HEIGHT); |
||||||
|
} |
||||||
|
|
||||||
|
void updateThanksLog(String text) { |
||||||
|
thanksLog = text; |
||||||
|
repaint(THANK_INFO_X, MODULE_INFO_Y - FONT_SIZE, MODULE_INFO_WIDTH, MODULE_INFO_HEIGHT); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.fr.start.common; |
||||||
|
|
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.stable.os.OperatingSystem; |
||||||
|
import com.sun.awt.AWTUtilities; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* 启动画面窗口 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @version 10.0 |
||||||
|
* Created by vito on 2019/10/16 |
||||||
|
*/ |
||||||
|
public class SplashWindow extends JFrame { |
||||||
|
|
||||||
|
private SplashPane splash; |
||||||
|
|
||||||
|
public SplashWindow() { |
||||||
|
// alex:必须设置这个属性为true,才可以用透明背景
|
||||||
|
System.setProperty("sun.java2d.noddraw", "true"); |
||||||
|
|
||||||
|
//slash pane
|
||||||
|
this.splash = new SplashPane(); |
||||||
|
|
||||||
|
splash.setBackground(null); |
||||||
|
this.setContentPane(splash); |
||||||
|
this.setSize(splash.getSplashDimension()); |
||||||
|
|
||||||
|
this.setAlwaysOnTop(false); |
||||||
|
this.setUndecorated(true); |
||||||
|
AWTUtilities.setWindowOpaque(this, false); |
||||||
|
|
||||||
|
//使窗体背景透明
|
||||||
|
if (OperatingSystem.isWindows()) { |
||||||
|
this.setBackground(new Color(0, 0, 0, 0)); |
||||||
|
} |
||||||
|
|
||||||
|
GUICoreUtils.centerWindow(this); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 注销窗口 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void dispose() { |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置在启动过程中, 动态改变的文本, 如 当前启动的模块信息 |
||||||
|
* |
||||||
|
* @param text 指定的文本 |
||||||
|
*/ |
||||||
|
void updateModuleLog(String text) { |
||||||
|
splash.updateModuleLog(text); |
||||||
|
} |
||||||
|
|
||||||
|
void updateThanksLog(String text) { |
||||||
|
splash.updateThanksLog(text); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
SplashWindow splashWindow = new SplashWindow(); |
||||||
|
splashWindow.setVisible(true); |
||||||
|
} |
||||||
|
} |
@ -1,21 +0,0 @@ |
|||||||
package com.fr.start.module; |
|
||||||
|
|
||||||
import com.fr.module.Activator; |
|
||||||
import com.fr.start.DesignerInitial; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by juhaoyu on 2019-06-14. |
|
||||||
*/ |
|
||||||
public class DesignerInitActivator extends Activator { |
|
||||||
|
|
||||||
@Override |
|
||||||
public void start() { |
|
||||||
|
|
||||||
DesignerInitial.init(upFindSingleton(StartupArgs.class).get()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void stop() { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,19 +0,0 @@ |
|||||||
package com.fr.start.module; |
|
||||||
|
|
||||||
import com.fr.design.fun.impl.GlobalListenerProviderManager; |
|
||||||
import com.fr.module.Activator; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by juhaoyu on 2018/1/8. |
|
||||||
*/ |
|
||||||
public class StartFinishActivator extends Activator { |
|
||||||
|
|
||||||
@Override |
|
||||||
public void start() { |
|
||||||
GlobalListenerProviderManager.getInstance().init(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void stop() { |
|
||||||
} |
|
||||||
} |
|
After Width: | Height: | Size: 264 KiB |
After Width: | Height: | Size: 814 KiB |
Loading…
Reference in new issue