roger
2 years ago
15 changed files with 763 additions and 28 deletions
@ -0,0 +1,194 @@
|
||||
package com.fr.design.mainframe.toast; |
||||
|
||||
import com.fr.concurrent.NamedThreadFactory; |
||||
import com.fr.design.dialog.UIDialog; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.module.ModuleContext; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.Icon; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingConstants; |
||||
import javax.swing.SwingUtilities; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Dimension; |
||||
import java.awt.Point; |
||||
import java.awt.Window; |
||||
import java.util.concurrent.ScheduledExecutorService; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
/** |
||||
* toast弹窗 |
||||
* */ |
||||
public class SimpleToast extends UIDialog { |
||||
private static final int MIN_HEIGHT = 36; |
||||
private static final String TOAST_MSG_TIMER = "TOAST_MSG_TIMER"; |
||||
private static final long DEFAULT_DISAPPEAR_DELAY = 5000; |
||||
private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS; |
||||
|
||||
|
||||
private ScheduledExecutorService timer; |
||||
private int hideHeight = 0; |
||||
private JPanel contentPane; |
||||
private boolean show = false; |
||||
private Window parent; |
||||
private boolean autoDisappear; |
||||
|
||||
public SimpleToast(Window parent, Icon icon, String text, boolean autoDisappear) { |
||||
super(parent); |
||||
this.parent = parent; |
||||
this.autoDisappear = autoDisappear; |
||||
JPanel panel = createContentPane(icon, text); |
||||
init(panel); |
||||
} |
||||
|
||||
private JPanel createContentPane(Icon icon, String text) { |
||||
JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
|
||||
UILabel iconLabel = new UILabel(icon); |
||||
iconLabel.setVerticalAlignment(SwingConstants.TOP); |
||||
iconLabel.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); |
||||
|
||||
|
||||
UILabel textLabel = new UILabel(text); |
||||
pane.add(iconLabel, BorderLayout.WEST); |
||||
pane.add(textLabel, BorderLayout.CENTER); |
||||
pane.setBorder(BorderFactory.createEmptyBorder(8, 15, 8, 15)); |
||||
|
||||
return pane; |
||||
} |
||||
|
||||
|
||||
private void init(JPanel panel) { |
||||
setFocusable(false); |
||||
setAutoRequestFocus(false); |
||||
setUndecorated(true); |
||||
contentPane = panel; |
||||
initComponent(); |
||||
} |
||||
|
||||
private void initComponent() { |
||||
this.getContentPane().setLayout(null); |
||||
this.getContentPane().add(contentPane); |
||||
Dimension dimension = calculatePreferSize(); |
||||
hideHeight = dimension.height; |
||||
setSize(new Dimension(dimension.width, 0)); |
||||
contentPane.setSize(dimension); |
||||
setRelativeLocation(dimension); |
||||
if (autoDisappear) { |
||||
disappear(contentPane); |
||||
} |
||||
} |
||||
|
||||
private void setRelativeLocation(Dimension dimension) { |
||||
int positionX = parent.getLocationOnScreen().x + (parent.getWidth() - dimension.width) / 2; |
||||
int positionY = parent.getLocationOnScreen().y + 10; |
||||
this.setLocation(positionX, positionY); |
||||
} |
||||
|
||||
private Dimension calculatePreferSize() { |
||||
Dimension contentDimension = contentPane.getPreferredSize(); |
||||
int height = Math.max(MIN_HEIGHT, contentDimension.height); |
||||
return new Dimension(contentDimension.width, height); |
||||
} |
||||
|
||||
|
||||
public void display(JPanel outerPanel) { |
||||
show = true; |
||||
outerPanel.setLocation(0, -hideHeight); |
||||
ScheduledExecutorService tipToolTimer = createToastScheduleExecutorService(); |
||||
tipToolTimer.scheduleAtFixedRate(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
SwingUtilities.invokeLater(()->{ |
||||
displayStep(outerPanel, tipToolTimer); |
||||
}); |
||||
} |
||||
}, 0, 50, TimeUnit.MILLISECONDS); |
||||
|
||||
} |
||||
|
||||
void displayStep(JPanel outerPanel, ScheduledExecutorService timer) { |
||||
Point point = outerPanel.getLocation(); |
||||
if (point.y >= 0 && !timer.isShutdown()) { |
||||
timer.shutdown(); |
||||
} |
||||
int showDistance = 5 + point.y < 0 ? 5 : -point.y; |
||||
outerPanel.setLocation(point.x, point.y + showDistance); |
||||
Dimension dimension = SimpleToast.this.getSize(); |
||||
SimpleToast.this.setSize(new Dimension(dimension.width, dimension.height + showDistance)); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void disappear(JPanel outerPanel, long delay, TimeUnit timeUnit) { |
||||
timer = createToastScheduleExecutorService(); |
||||
timer.schedule(new DisappearMotion(outerPanel), delay, timeUnit); |
||||
} |
||||
|
||||
/** |
||||
* toast消失的动画效果 |
||||
* */ |
||||
class DisappearMotion implements Runnable { |
||||
JPanel panel; |
||||
|
||||
DisappearMotion(JPanel panel) { |
||||
this.panel = panel; |
||||
} |
||||
|
||||
@Override |
||||
public void run() { |
||||
ScheduledExecutorService tipToolTimer = createToastScheduleExecutorService(); |
||||
tipToolTimer.scheduleAtFixedRate(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
SwingUtilities.invokeLater(()->{ |
||||
disappearStep(tipToolTimer); |
||||
}); |
||||
} |
||||
}, 0, 50, TimeUnit.MILLISECONDS); |
||||
} |
||||
|
||||
void disappearStep(ScheduledExecutorService timer) { |
||||
Point point = panel.getLocation(); |
||||
if (point.y <= -hideHeight && !timer.isShutdown()) { |
||||
timer.shutdown(); |
||||
SimpleToast.this.setVisible(false); |
||||
SimpleToast.this.dispose(); |
||||
SimpleToast.this.show = false; |
||||
} |
||||
panel.setLocation(point.x, point.y - 5); |
||||
Dimension dimension = SimpleToast.this.getSize(); |
||||
SimpleToast.this.setSize(new Dimension(dimension.width, dimension.height - 5)); |
||||
} |
||||
} |
||||
|
||||
private void disappear(JPanel outerPanel) { |
||||
disappear(outerPanel, DEFAULT_DISAPPEAR_DELAY, DEFAULT_TIME_UNIT); |
||||
} |
||||
|
||||
private ScheduledExecutorService createToastScheduleExecutorService() { |
||||
return ModuleContext.getExecutor().newSingleThreadScheduledExecutor(new NamedThreadFactory(TOAST_MSG_TIMER)); |
||||
} |
||||
|
||||
@Override |
||||
public void checkValid() throws Exception { |
||||
} |
||||
|
||||
public void setVisible(boolean visible) { |
||||
super.setVisible(visible); |
||||
if (visible) { |
||||
display(contentPane); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void dispose() { |
||||
super.dispose(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,10 @@
|
||||
package com.fr.design.mainframe.alphafine.download; |
||||
|
||||
public class FineMarketConstants { |
||||
|
||||
public static final String REPORTLETS = "/reportlets"; |
||||
public static final String ZIP = ".zip"; |
||||
public static final String RAR = ".rar"; |
||||
public static final String CPT = ".cpt"; |
||||
public static final String FRM = ".frm"; |
||||
} |
@ -0,0 +1,149 @@
|
||||
package com.fr.design.mainframe.alphafine.download; |
||||
|
||||
import com.fr.base.svg.IconUtils; |
||||
import com.fr.common.util.Strings; |
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.extra.Process; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.login.DesignerLoginHelper; |
||||
import com.fr.design.login.DesignerLoginSource; |
||||
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||
import com.fr.design.mainframe.alphafine.model.TemplateResource; |
||||
import com.fr.design.mainframe.alphafine.search.helper.FineMarketClientHelper; |
||||
import com.fr.design.mainframe.toast.SimpleToast; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.third.jodd.io.ZipUtil; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import javax.swing.SwingUtilities; |
||||
import java.awt.Window; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
|
||||
|
||||
/** |
||||
* 在这里统一管理帆软市场的下载 |
||||
* 下载的流程控制尽量都在这个类内部完成 |
||||
* 通过Process类来实现下载流程控制 |
||||
* */ |
||||
public class FineMarketDownloadManager { |
||||
|
||||
private static final FineMarketDownloadManager INSTANCE = new FineMarketDownloadManager(); |
||||
public static final FineMarketDownloadManager getInstance() { |
||||
return INSTANCE; |
||||
} |
||||
|
||||
|
||||
public static final double PROCESS_SUCCESS = 1d; |
||||
public static final double PROCESS_FAILED = -1d; |
||||
public static final double OPENING_FILE = 2d; |
||||
|
||||
private static final String OPENING_PLEASE_WAIT = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Opening"); |
||||
private static final String DOWNLOAD_FAILED = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Download_Failed_Check_Network"); |
||||
|
||||
|
||||
/** |
||||
* 下载资源并解压 |
||||
* */ |
||||
public String installResource(TemplateResource resource, Window parentWindow){ |
||||
// 验证登录
|
||||
String token = DesignerEnvManager.getEnvManager().getDesignerLoginRefreshToken(); |
||||
if (Strings.isEmpty(token)) { |
||||
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), AlphaFineHelper.getAlphaFineDialog()); |
||||
return null; |
||||
} |
||||
return install(resource, parentWindow); |
||||
} |
||||
|
||||
private String install(TemplateResource resource, Window parentWindow) { |
||||
// 获取报表录作为下载位置
|
||||
String workDir = WorkContext.getCurrent().getPath() + FineMarketConstants.REPORTLETS; |
||||
File destDir = new File(workDir); |
||||
|
||||
DownloadProcess downloadProcess = new DownloadProcess(parentWindow); |
||||
String fileName = null; |
||||
try { |
||||
fileName = FineMarketClientHelper.getInstance().download(resource, destDir, downloadProcess); |
||||
unzip(fileName, downloadProcess); |
||||
return fileName; |
||||
} catch (Exception e) { |
||||
downloadProcess.process(FineMarketDownloadManager.PROCESS_FAILED); |
||||
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void unzip(String fileName, DownloadProcess process) throws IOException { |
||||
process.process(OPENING_FILE); |
||||
|
||||
if (fileName.endsWith(FineMarketConstants.ZIP)) { |
||||
File file = new File(fileName); |
||||
File parentDir = file.getParentFile(); |
||||
ZipUtil.unzip(file, parentDir); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
/** |
||||
* 下载流程控制,主要控制ui的显示 |
||||
* */ |
||||
class DownloadProcess implements Process<Double> { |
||||
|
||||
SimpleToast downloadingToast; |
||||
SimpleToast openingToast; |
||||
SimpleToast failedToast; |
||||
Window parent; |
||||
|
||||
public DownloadProcess(Window parentWindow) { |
||||
this.parent = parentWindow; |
||||
init(); |
||||
} |
||||
|
||||
void init() { |
||||
showLoadingToast(); |
||||
} |
||||
|
||||
@Override |
||||
public void process(Double aDouble) { |
||||
SwingUtilities.invokeLater(()->{ |
||||
if (aDouble == PROCESS_FAILED) { |
||||
downloadFailed(); |
||||
} else if (aDouble == PROCESS_SUCCESS) { |
||||
downloadSuccess(); |
||||
} else if (aDouble == OPENING_FILE) { |
||||
openingFile(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public void downloadFailed() { |
||||
downloadingToast.setVisible(false); |
||||
showFailedToast(); |
||||
} |
||||
|
||||
public void downloadSuccess() { |
||||
downloadingToast.setVisible(false); |
||||
} |
||||
|
||||
|
||||
private void openingFile() { |
||||
downloadingToast.setVisible(false); |
||||
openingToast = new SimpleToast(AlphaFineHelper.getAlphaFineDialog(), IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/loading.svg"), OPENING_PLEASE_WAIT, true); |
||||
openingToast.setVisible(true); |
||||
} |
||||
|
||||
private void showLoadingToast() { |
||||
downloadingToast = new SimpleToast(AlphaFineHelper.getAlphaFineDialog(), IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/loading.svg"), OPENING_PLEASE_WAIT, false); |
||||
downloadingToast.setVisible(true); |
||||
} |
||||
|
||||
private void showFailedToast() { |
||||
failedToast = new SimpleToast(AlphaFineHelper.getAlphaFineDialog(), IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/caution.svg"), DOWNLOAD_FAILED, true); |
||||
failedToast.setVisible(true); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,67 @@
|
||||
package com.fr.market.key; |
||||
|
||||
import com.fr.general.IOUtils; |
||||
import com.fr.io.utils.ResourceIOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
|
||||
/** |
||||
* @author Link |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/8/25 |
||||
*/ |
||||
public class FineMarketDefaultKeyProperties { |
||||
|
||||
private Properties properties = new Properties(); |
||||
|
||||
private Map<String, String> publicKeyMap = new HashMap<>(); |
||||
|
||||
private String propertyPath; |
||||
|
||||
private FineMarketDefaultKeyProperties(String propertyPath) { |
||||
this.propertyPath = propertyPath; |
||||
load(); |
||||
} |
||||
|
||||
public static FineMarketDefaultKeyProperties create(String propertyPath) { |
||||
return new FineMarketDefaultKeyProperties(propertyPath); |
||||
} |
||||
|
||||
private void load() { |
||||
try (InputStream inputStream = IOUtils.readResource(getPropertyPath())) { |
||||
byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); |
||||
properties.load(new ByteArrayInputStream(data)); |
||||
trims(properties); |
||||
publicKeyMap.put(FineMarketPublicKeyConstants.DEFAULT_KEY_KEY, properties.getProperty(FineMarketPublicKeyConstants.DEFAULT_KEY_KEY)); |
||||
} catch (IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
private String getPropertyPath() { |
||||
return this.propertyPath; |
||||
} |
||||
|
||||
public String getPublicKey() { |
||||
return publicKeyMap.get(FineMarketPublicKeyConstants.DEFAULT_KEY_KEY); |
||||
} |
||||
|
||||
/** |
||||
* 去除properties中value末尾的空格 |
||||
* @param properties |
||||
*/ |
||||
public static void trims(Properties properties) { |
||||
for (String key : properties.stringPropertyNames()) { |
||||
String value = properties.getProperty(key); |
||||
if (value != null) { |
||||
properties.put(key, value.trim()); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
package com.fr.market.key; |
||||
|
||||
|
||||
/** |
||||
* @author Link |
||||
* @version 11.0 |
||||
* Created by Link on 2022/8/25 |
||||
*/ |
||||
public class FineMarketPublicKeyConstants { |
||||
|
||||
public static final String DEFAULT_KEY_KEY = "defaultKey"; |
||||
|
||||
public static final String DEFAULT_KEY_DIRECTORY = "/com/fr/market/key"; |
||||
|
||||
/** |
||||
* 公钥第一段 |
||||
*/ |
||||
public static final String FIRST_PROPERTY = "76c1/default"; |
||||
|
||||
/** |
||||
* 公钥第二段 |
||||
*/ |
||||
public static final String SECOND_PROPERTY = "943f/default"; |
||||
|
||||
/** |
||||
* 公钥第三段 |
||||
*/ |
||||
public static final String THIRD_PROPERTY = "d8a3/default"; |
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.fr.market.key; |
||||
|
||||
import com.fr.stable.StableUtils; |
||||
|
||||
/** |
||||
* 帆软市场公钥Holder |
||||
* @author Link |
||||
* @version 10.0 |
||||
* Created by Link on 2022/8/25 |
||||
*/ |
||||
public class FineMarketPublicKeyHolder { |
||||
|
||||
private static FineMarketPublicKeyHolder instance = null; |
||||
|
||||
private String defaultKey; |
||||
|
||||
public static FineMarketPublicKeyHolder getInstance() { |
||||
|
||||
if (instance == null) { |
||||
synchronized (FineMarketPublicKeyHolder.class) { |
||||
if (instance == null) { |
||||
instance = new FineMarketPublicKeyHolder(); |
||||
} |
||||
} |
||||
} |
||||
return instance; |
||||
} |
||||
|
||||
private FineMarketPublicKeyHolder() { |
||||
init(); |
||||
} |
||||
|
||||
private void init() { |
||||
// 读取三个default.properties文件,组成公钥
|
||||
String firstPart = FineMarketDefaultKeyProperties.create(StableUtils.pathJoin(FineMarketPublicKeyConstants.DEFAULT_KEY_DIRECTORY, FineMarketPublicKeyConstants.FIRST_PROPERTY)).getPublicKey(); |
||||
String secondPart = FineMarketDefaultKeyProperties.create(StableUtils.pathJoin(FineMarketPublicKeyConstants.DEFAULT_KEY_DIRECTORY, FineMarketPublicKeyConstants.SECOND_PROPERTY)).getPublicKey(); |
||||
String thirdPart = FineMarketDefaultKeyProperties.create(StableUtils.pathJoin(FineMarketPublicKeyConstants.DEFAULT_KEY_DIRECTORY, FineMarketPublicKeyConstants.THIRD_PROPERTY)).getPublicKey(); |
||||
this.defaultKey = firstPart + secondPart + thirdPart; |
||||
} |
||||
|
||||
/** |
||||
* 获取默认公钥 |
||||
* @return 公钥 |
||||
*/ |
||||
public String getDefaultKey() { |
||||
return this.defaultKey; |
||||
} |
||||
} |
After Width: | Height: | Size: 820 B |
After Width: | Height: | Size: 936 B |
@ -0,0 +1 @@
|
||||
defaultKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtsz62CPSWXZE/IYZRiAuTSZkw |
@ -0,0 +1 @@
|
||||
defaultKey=1WOwer8+JFktK0uKLAUuQoBr+UjAMFtRA8W7JgKMDwZy/2liEAiXEOSPU/hrdV8D |
Loading…
Reference in new issue