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