zheng
3 years ago
804 changed files with 54535 additions and 4994 deletions
@ -0,0 +1,193 @@
|
||||
package com.fr.design; |
||||
|
||||
import com.fr.concurrent.NamedThreadFactory; |
||||
import com.fr.general.CloudCenter; |
||||
import com.fr.general.CloudCenterConfig; |
||||
import com.fr.general.http.HttpToolbox; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.ProductConstants; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLReaderHelper; |
||||
import com.fr.stable.xml.XMLTools; |
||||
import com.fr.stable.xml.XMLable; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
import com.fr.third.javax.xml.stream.XMLStreamException; |
||||
import com.fr.third.org.apache.commons.io.FileUtils; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileNotFoundException; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ExecutorService; |
||||
import java.util.concurrent.Executors; |
||||
|
||||
/** |
||||
* Created by kerry on 2021/10/22 |
||||
*/ |
||||
public class DesignerCloudURLManager implements XMLable { |
||||
private static final String CLOUD_URL_INFO = "cloudUrl.info"; |
||||
private static final String ROOT_XML_TAG = "CloudUrlInfoList"; |
||||
private static final String CHILD_XML_TAG = "CloudUrlInfo"; |
||||
private final Map<String, String> urlMap = new HashMap<>(); |
||||
|
||||
public static DesignerCloudURLManager getInstance() { |
||||
return DesignerCloudURLManager.HOLDER.singleton; |
||||
} |
||||
|
||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("TestCloudConnectThread")); |
||||
|
||||
private volatile boolean testResult; |
||||
|
||||
|
||||
private static class HOLDER { |
||||
private static final DesignerCloudURLManager singleton = new DesignerCloudURLManager(); |
||||
} |
||||
|
||||
private DesignerCloudURLManager() { |
||||
loadURLXMLFile(); |
||||
} |
||||
|
||||
public String acquireUrlByKind(String key) { |
||||
String url = urlMap.getOrDefault(key, StringUtils.EMPTY); |
||||
if (StringUtils.isEmpty(url)) { |
||||
//本地缓存中为空时,直接从云中心获取,获取完成后异步更新本地缓存文件
|
||||
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY); |
||||
executorService.submit(() -> { |
||||
updateURLXMLFile(key, latestUrl); |
||||
}); |
||||
return latestUrl; |
||||
} |
||||
//本地缓存不为空时,直接返回对应 url,同时异步更新
|
||||
executorService.submit(() -> { |
||||
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY); |
||||
updateURLXMLFile(key, latestUrl); |
||||
}); |
||||
return url; |
||||
} |
||||
|
||||
private synchronized void updateURLXMLFile(String key, String url) { |
||||
if (StringUtils.isNotEmpty(url) && (!urlMap.containsKey(key) || !url.equals(urlMap.get(key)))) { |
||||
urlMap.put(key, url); |
||||
saveURLXMLFile(); |
||||
} |
||||
} |
||||
|
||||
|
||||
public void testConnect() { |
||||
executorService.submit(() -> { |
||||
testResult = isOnline(); |
||||
}); |
||||
} |
||||
|
||||
public boolean isConnected() { |
||||
return testResult; |
||||
} |
||||
|
||||
public boolean isOnline() { |
||||
if (CloudCenterConfig.getInstance().isOnline()) { |
||||
String ping = acquireUrlByKind("ping"); |
||||
if (StringUtils.isNotEmpty(ping)) { |
||||
try { |
||||
return StringUtils.isEmpty(HttpToolbox.get(ping)); |
||||
} catch (Exception ignore) { |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 加载本地 url 管理文件 |
||||
*/ |
||||
private void loadURLXMLFile() { |
||||
if (!getInfoFile().exists()) { |
||||
return; |
||||
} |
||||
XMLableReader reader = null; |
||||
try (InputStream in = new FileInputStream(getInfoFile())) { |
||||
// XMLableReader 还是应该考虑实现 Closable 接口的,这样就能使用 try-with 语句了
|
||||
reader = XMLReaderHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); |
||||
if (reader == null) { |
||||
return; |
||||
} |
||||
reader.readXMLObject(this); |
||||
} catch (FileNotFoundException e) { |
||||
// do nothing
|
||||
} catch (XMLStreamException | IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} finally { |
||||
try { |
||||
if (reader != null) { |
||||
reader.close(); |
||||
} |
||||
} catch (XMLStreamException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private File getInfoFile() { |
||||
|
||||
File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), CLOUD_URL_INFO)); |
||||
try { |
||||
if (!file.exists()) { |
||||
file.createNewFile(); |
||||
} |
||||
} catch (Exception ex) { |
||||
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
/** |
||||
* 保存到本地 URL 管理文件中,存放在 .Finereport110 中 |
||||
*/ |
||||
void saveURLXMLFile() { |
||||
try { |
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
XMLTools.writeOutputStreamXML(this, out); |
||||
out.flush(); |
||||
out.close(); |
||||
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); |
||||
FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); |
||||
} catch (Exception ex) { |
||||
FineLoggerFactory.getLogger().error(ex.getMessage()); |
||||
} |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void readXML(XMLableReader reader) { |
||||
String tagName = reader.getTagName(); |
||||
if (tagName.equals(CHILD_XML_TAG)) { |
||||
String key = reader.getAttrAsString("key", StringUtils.EMPTY); |
||||
String value = reader.getAttrAsString("url", StringUtils.EMPTY); |
||||
this.urlMap.put(key, value); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void writeXML(XMLPrintWriter xmlPrintWriter) { |
||||
xmlPrintWriter.startTAG(ROOT_XML_TAG); |
||||
Iterator<Map.Entry<String, String>> iterable = urlMap.entrySet().iterator(); |
||||
while (iterable.hasNext()) { |
||||
Map.Entry<String, String> entry = iterable.next(); |
||||
xmlPrintWriter.startTAG(CHILD_XML_TAG).attr("key", entry.getKey()).attr("url", entry.getValue()).end(); |
||||
} |
||||
xmlPrintWriter.end(); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,47 @@
|
||||
package com.fr.design.actions.file; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.menu.MenuKeySet; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.nx.app.designer.transform.ui.BatchTransformPane; |
||||
|
||||
import javax.swing.KeyStroke; |
||||
import java.awt.Dialog; |
||||
import java.awt.event.ActionEvent; |
||||
|
||||
/** |
||||
* Created by kerry on 2019-12-10 |
||||
*/ |
||||
public class BatchCompileAction extends UpdateAction { |
||||
public BatchCompileAction() { |
||||
this.setMenuKeySet(COMPILE); |
||||
this.setName(getMenuKeySet().getMenuKeySetName() + "..."); |
||||
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/batch_transform.png")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
BatchTransformPane batchTransformPane = new BatchTransformPane(); |
||||
Dialog dialog = batchTransformPane.showDialog(); |
||||
dialog.setVisible(true); |
||||
} |
||||
|
||||
private static final MenuKeySet COMPILE = new MenuKeySet() { |
||||
@Override |
||||
public char getMnemonic() { |
||||
return 'C'; |
||||
} |
||||
|
||||
@Override |
||||
public String getMenuName() { |
||||
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Batch_Transform"); |
||||
} |
||||
|
||||
@Override |
||||
public KeyStroke getKeyStroke() { |
||||
return null; |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,49 @@
|
||||
package com.fr.design.actions.server; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.menu.MenuKeySet; |
||||
import com.fr.design.utils.DesignUtils; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.nx.app.web.URLConstants; |
||||
import com.fr.stable.StableUtils; |
||||
|
||||
import javax.swing.KeyStroke; |
||||
import java.awt.event.ActionEvent; |
||||
|
||||
/** |
||||
* @author Maksim |
||||
* Created in 2020/11/5 11:44 上午 |
||||
*/ |
||||
public class LocalAnalyzerAction extends UpdateAction { |
||||
|
||||
public LocalAnalyzerAction() { |
||||
this.setMenuKeySet(ANALYZER); |
||||
this.setName(getMenuKeySet().getMenuKeySetName()); |
||||
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/analyzer.png")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
String path = StableUtils.pathJoin("/nx", URLConstants.ANALYZE_VIEW); |
||||
DesignUtils.visitEnvServerByParameters(path, new String[]{}, new String[]{}); |
||||
} |
||||
|
||||
private static final MenuKeySet ANALYZER = new MenuKeySet() { |
||||
@Override |
||||
public char getMnemonic() { |
||||
return 'R'; |
||||
} |
||||
|
||||
@Override |
||||
public String getMenuName() { |
||||
return InterProviderFactory.getProvider().getLocText("Fine-Plugin-Engine_Analyzer_Menu_Name"); |
||||
} |
||||
|
||||
@Override |
||||
public KeyStroke getKeyStroke() { |
||||
return null; |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,32 @@
|
||||
package com.fr.design.border; |
||||
|
||||
import com.fr.design.constants.UIConstants; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.border.TitledBorder; |
||||
import java.awt.Color; |
||||
|
||||
public class UITitledMatteBorder extends TitledBorder { |
||||
public static UITitledMatteBorder createTitledTopBorder(String title, Color color) { |
||||
return new UITitledMatteBorder(title, 1, 0, 0, 0, color); |
||||
} |
||||
|
||||
public static UITitledMatteBorder createTitledBorder(String title, Color color) { |
||||
return new UITitledMatteBorder(title, 1, 1, 1, 1, color); |
||||
} |
||||
|
||||
public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) { |
||||
return new UITitledMatteBorder(title, top, left, bottom, right, color); |
||||
} |
||||
|
||||
private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) { |
||||
super( |
||||
BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR), |
||||
title, |
||||
TitledBorder.LEADING, |
||||
TitledBorder.TOP, |
||||
null, |
||||
color |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,117 @@
|
||||
package com.fr.design.cell; |
||||
|
||||
import com.fr.base.NameStyle; |
||||
import com.fr.base.ScreenResolution; |
||||
import com.fr.base.Style; |
||||
import com.fr.general.IOUtils; |
||||
|
||||
import javax.swing.JPanel; |
||||
import java.awt.AlphaComposite; |
||||
import java.awt.Color; |
||||
import java.awt.Composite; |
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.RenderingHints; |
||||
import java.awt.image.BufferedImage; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/3 |
||||
*/ |
||||
public class CellStylePreviewPane extends JPanel { |
||||
|
||||
private static final BufferedImage transparentBackgroundImage = IOUtils.readImage("/com/fr/design/images/transparent_background.png"); |
||||
private final float transparentBackgroundWidth; |
||||
private final float transparentBackgroundHeight; |
||||
private String paintText = "Report"; |
||||
private Style style = Style.DEFAULT_STYLE; |
||||
|
||||
public CellStylePreviewPane() { |
||||
transparentBackgroundWidth = transparentBackgroundImage.getWidth(null); |
||||
transparentBackgroundHeight = transparentBackgroundImage.getHeight(null); |
||||
} |
||||
|
||||
public void setStyle(Style style) { |
||||
this.style = style; |
||||
if (style instanceof NameStyle) { |
||||
paintText = ((NameStyle) style).getName(); |
||||
} |
||||
repaint(); |
||||
} |
||||
|
||||
@Override |
||||
public void paint(Graphics g) { |
||||
Graphics2D g2d = (Graphics2D) g; |
||||
g.clearRect(0, 0, getWidth(), getHeight()); |
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
||||
|
||||
paintTransparentBackground(g2d, style); |
||||
paintCellStyle(g2d, style); |
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); |
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); |
||||
} |
||||
|
||||
private void paintTransparentBackground(Graphics2D g2d, Style style) { |
||||
float alpha = computeTransparentBackgroundAlpha(style); |
||||
|
||||
float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth; |
||||
float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight; |
||||
float maxScale = Math.max(scaleWidth, scaleHeight); |
||||
|
||||
if (maxScale <= 1) { |
||||
scaleWidth = scaleHeight = 1; |
||||
} else { |
||||
scaleHeight = scaleWidth = maxScale; |
||||
} |
||||
|
||||
Composite oldComposite = g2d.getComposite(); |
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); |
||||
g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null); |
||||
g2d.setComposite(oldComposite); |
||||
} |
||||
|
||||
private float computeTextColorBrightness(Style style) { |
||||
Color fontColor = style.getFRFont().getForeground(); |
||||
return fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F + fontColor.getBlue() * 0.114F; |
||||
} |
||||
|
||||
private float computeTransparentBackgroundAlpha(Style style) { |
||||
float textBrightness = computeTextColorBrightness(style); |
||||
|
||||
float alpha = 1.0F; |
||||
if (textBrightness < 50) { |
||||
alpha = 0.2F; |
||||
} else if (textBrightness < 160){ |
||||
alpha = 0.5F; |
||||
} |
||||
return alpha; |
||||
} |
||||
|
||||
private void paintCellStyle(Graphics2D g2d, Style style) { |
||||
int resolution = ScreenResolution.getScreenResolution(); |
||||
|
||||
int width = getWidth(); |
||||
int height = getHeight(); |
||||
|
||||
if (style == Style.DEFAULT_STYLE) { |
||||
// 如果是默认的style,就只写"Report"上去
|
||||
Style.paintContent(g2d, paintText, style, width, height, resolution); |
||||
return; |
||||
} |
||||
|
||||
Style.paintBackground(g2d, style, width, height); |
||||
|
||||
Style.paintContent(g2d, paintText, style, width, height, resolution); |
||||
|
||||
Style.paintBorder(g2d, style, width, height); |
||||
} |
||||
|
||||
@Override |
||||
public Dimension getMinimumSize() { |
||||
return getPreferredSize(); |
||||
} |
||||
} |
@ -0,0 +1,27 @@
|
||||
package com.fr.design.data; |
||||
|
||||
public class NameChangeBean { |
||||
private String oldName; |
||||
private String changedName; |
||||
|
||||
public NameChangeBean(String oldName, String changedName) { |
||||
this.oldName = oldName; |
||||
this.changedName = changedName; |
||||
} |
||||
|
||||
public String getOldName() { |
||||
return oldName; |
||||
} |
||||
|
||||
public void setOldName(String oldName) { |
||||
this.oldName = oldName; |
||||
} |
||||
|
||||
public String getChangedName() { |
||||
return changedName; |
||||
} |
||||
|
||||
public void setChangedName(String changedName) { |
||||
this.changedName = changedName; |
||||
} |
||||
} |
@ -0,0 +1,136 @@
|
||||
package com.fr.design.data; |
||||
|
||||
import com.fr.base.io.IOFile; |
||||
import com.fr.design.file.HistoryTemplateListCache; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.esd.core.strategy.config.StrategyConfig; |
||||
import com.fr.esd.core.strategy.config.StrategyConfigHelper; |
||||
import com.fr.esd.core.strategy.config.service.StrategyConfigService; |
||||
import com.fr.esd.core.strategy.persistence.StrategyConfigsAttr; |
||||
import com.fr.esd.event.DSMapping; |
||||
import com.fr.esd.event.DsNameTarget; |
||||
import com.fr.esd.event.StrategyEventsNotifier; |
||||
import com.fr.esd.event.xml.XMLSavedHook; |
||||
import com.fr.file.FILE; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.HashSet; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2020/10/28 |
||||
*/ |
||||
public class StrategyConfigAttrUtils { |
||||
|
||||
/** |
||||
* 获取当前编辑模版的数据集缓存配置属性 |
||||
* |
||||
* @return |
||||
*/ |
||||
private static StrategyConfigsAttr getStrategyConfigsAttr() { |
||||
StrategyConfigsAttr attr; |
||||
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||
if (jTemplate != null) { |
||||
IOFile ioFile = (IOFile) jTemplate.getTarget(); |
||||
|
||||
attr = ioFile.getAttrMark(StrategyConfigsAttr.ATTR_MARK); |
||||
if (attr == null) { |
||||
attr = new StrategyConfigsAttr(); |
||||
ioFile.addAttrMark(attr); |
||||
} |
||||
|
||||
//新建模版此时不存在,不需要注册钩子
|
||||
if (attr.getXmlSavedHook() == null && WorkContext.getWorkResource().exist(jTemplate.getPath())) { |
||||
attr.setXmlSavedHook(new StrategyConfigsAttrSavedHook(jTemplate.getPath(), attr)); |
||||
} |
||||
return attr; |
||||
} else { |
||||
throw new IllegalStateException("[ESD]No editing template found."); |
||||
} |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 获取模版数据集配置 |
||||
* |
||||
* @param dsName |
||||
* @return |
||||
*/ |
||||
public static StrategyConfig getStrategyConfig(String dsName) { |
||||
|
||||
return getStrategyConfigsAttr().getStrategyConfig(dsName); |
||||
} |
||||
|
||||
/** |
||||
* 移除模版数据集配置 |
||||
* |
||||
* @param dsName |
||||
* @return |
||||
*/ |
||||
public static StrategyConfig removeStrategyConfig(String dsName) { |
||||
|
||||
return getStrategyConfigsAttr().removeStrategyConfig(dsName); |
||||
} |
||||
|
||||
/** |
||||
* 添加模版数据集配置 |
||||
* |
||||
* @param strategyConfig |
||||
*/ |
||||
public static void addStrategyConfig(StrategyConfig strategyConfig) { |
||||
|
||||
getStrategyConfigsAttr().addStrategyConfig(strategyConfig); |
||||
} |
||||
|
||||
|
||||
private static class StrategyConfigsAttrSavedHook implements XMLSavedHook<StrategyConfigsAttr> { |
||||
|
||||
private static final long serialVersionUID = -8843201977112289321L; |
||||
|
||||
private final String tplPath; |
||||
private final Map<String, StrategyConfig> origStrategyConfigs; |
||||
|
||||
public StrategyConfigsAttrSavedHook(String tplPath, StrategyConfigsAttr raw) { |
||||
this.tplPath = tplPath; |
||||
this.origStrategyConfigs = new HashMap<>(); |
||||
this.initOrigStrategyConfigs(raw); |
||||
} |
||||
|
||||
|
||||
private void initOrigStrategyConfigs(StrategyConfigsAttr raw) { |
||||
origStrategyConfigs.clear(); |
||||
raw.getStrategyConfigs().forEach((k, v) -> { |
||||
try { |
||||
origStrategyConfigs.put(k, v.clone()); |
||||
} catch (CloneNotSupportedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public void doAfterSaved(StrategyConfigsAttr saved) { |
||||
|
||||
FineLoggerFactory.getLogger().info("[ESD]Write StrategyConfigsAttr done, now check change."); |
||||
Set<String> dsNames = new HashSet<>(); |
||||
dsNames.addAll(origStrategyConfigs.keySet()); |
||||
dsNames.addAll(saved.getStrategyConfigs().keySet()); |
||||
|
||||
if (StringUtils.isNotEmpty(tplPath)) { |
||||
dsNames.forEach(dsName -> { |
||||
if (StringUtils.isNotEmpty(dsName)) { |
||||
StrategyEventsNotifier.compareAndFireConfigEvents(origStrategyConfigs.get(dsName), saved.getStrategyConfig(dsName), new DSMapping(tplPath, new DsNameTarget(dsName))); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
initOrigStrategyConfigs(saved); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,226 @@
|
||||
package com.fr.design.data.datapane; |
||||
|
||||
import com.fr.design.beans.BasicBeanPane; |
||||
import com.fr.design.gui.ibutton.UIRadioButton; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.ilable.ActionLabel; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.esd.common.CacheConstants; |
||||
import com.fr.esd.core.strategy.config.StrategyConfig; |
||||
import com.fr.esd.core.strategy.config.StrategyConfigHelper; |
||||
import com.fr.esd.util.ESDUtils; |
||||
import com.fr.locale.InterProviderFactory; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.AbstractAction; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Desktop; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.net.URI; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2020/7/22 |
||||
*/ |
||||
public class ESDStrategyConfigPane extends BasicBeanPane<StrategyConfig> { |
||||
private static final String CRON_HELP_URL = "http://help.fanruan.com/finereport/doc-view-693.html"; |
||||
|
||||
private UIRadioButton selectAutoUpdate; |
||||
private UIRadioButton selectBySchema; |
||||
private UICheckBox shouldEvolve; |
||||
private UILabel updateIntervalCheckTips; |
||||
private UITextField updateInterval; |
||||
private UITextField schemaTime; |
||||
private ActionLabel actionLabel; |
||||
private UILabel schemaTimeCheckTips; |
||||
private final boolean global; |
||||
private StrategyConfig strategyConfig; |
||||
|
||||
|
||||
public ESDStrategyConfigPane(boolean global) { |
||||
this.global = global; |
||||
init(); |
||||
} |
||||
|
||||
private void init() { |
||||
setLayout(FRGUIPaneFactory.createM_BorderLayout()); |
||||
|
||||
this.selectAutoUpdate = new UIRadioButton(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Every_Interval")); |
||||
|
||||
this.updateInterval = new UITextField(4); |
||||
this.shouldEvolve = new UICheckBox(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Auto_Evolved_Strategy"), false); |
||||
this.shouldEvolve.setEnabled(false); |
||||
this.updateIntervalCheckTips = new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Interval_Format")); |
||||
this.updateIntervalCheckTips.setForeground(Color.RED); |
||||
this.updateIntervalCheckTips.setVisible(false); |
||||
|
||||
this.selectBySchema = new UIRadioButton(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cron")); |
||||
this.schemaTime = new UITextField(10); |
||||
this.schemaTimeCheckTips = new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Time_Format")); |
||||
this.schemaTimeCheckTips.setVisible(false); |
||||
this.schemaTimeCheckTips.setForeground(Color.RED); |
||||
|
||||
|
||||
this.selectAutoUpdate.addActionListener(new AbstractAction() { |
||||
public void actionPerformed(ActionEvent e) { |
||||
ESDStrategyConfigPane.this.selectBySchema.setSelected(!ESDStrategyConfigPane.this.selectAutoUpdate.isSelected()); |
||||
ESDStrategyConfigPane.this.schemaTime.setEnabled(false); |
||||
ESDStrategyConfigPane.this.updateInterval.setEnabled(true); |
||||
ESDStrategyConfigPane.this.shouldEvolve.setEnabled(true); |
||||
} |
||||
}); |
||||
|
||||
this.selectBySchema.addActionListener(new AbstractAction() { |
||||
public void actionPerformed(ActionEvent e) { |
||||
ESDStrategyConfigPane.this.selectAutoUpdate.setSelected(!ESDStrategyConfigPane.this.selectBySchema.isSelected()); |
||||
ESDStrategyConfigPane.this.schemaTime.setEnabled(true); |
||||
ESDStrategyConfigPane.this.updateInterval.setEnabled(false); |
||||
ESDStrategyConfigPane.this.shouldEvolve.setEnabled(false); |
||||
} |
||||
}); |
||||
|
||||
JPanel pane = FRGUIPaneFactory.createVerticalTitledBorderPane(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cache_Update_Strategy")); |
||||
add(pane, BorderLayout.NORTH); |
||||
|
||||
JPanel row1 = GUICoreUtils.createFlowPane(new Component[]{ |
||||
this.selectAutoUpdate, |
||||
this.updateInterval, |
||||
new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Minute_Update_Cache")), |
||||
this.shouldEvolve, |
||||
this.updateIntervalCheckTips |
||||
}, 0, 5); |
||||
pane.add(row1); |
||||
|
||||
ActionLabel actionLabel = new ActionLabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cron_Help")); |
||||
actionLabel.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
try { |
||||
Desktop.getDesktop().browse(new URI(CRON_HELP_URL)); |
||||
} catch (Exception exp) { |
||||
FineLoggerFactory.getLogger().error(exp.getMessage(), e); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
JPanel row2 = GUICoreUtils.createFlowPane(new Component[]{ |
||||
this.selectBySchema, |
||||
this.schemaTime, |
||||
actionLabel, |
||||
this.schemaTimeCheckTips |
||||
}, 0, 5); |
||||
pane.add(row2); |
||||
} |
||||
|
||||
|
||||
public void populateBean(StrategyConfig ob) { |
||||
|
||||
if (ob == null && !global) { |
||||
ob = StrategyConfigHelper.createStrategyConfig(true, false, true); |
||||
} |
||||
this.strategyConfig = ob; |
||||
|
||||
this.updateInterval.setText(ob.getUpdateInterval() <= 0 ? "0" : String.valueOf(ob.getUpdateInterval() / (double) CacheConstants.MILLIS_OF_MINUTE)); |
||||
this.schemaTime.setText(StringUtils.join(",", ob.getUpdateSchema().toArray(new String[0]))); |
||||
this.shouldEvolve.setSelected(ob.shouldEvolve()); |
||||
this.selectBySchema.setSelected(ob.isScheduleBySchema()); |
||||
this.selectAutoUpdate.setSelected(!ob.isScheduleBySchema()); |
||||
|
||||
if (global) { |
||||
//使用全局配置,禁用面板编辑
|
||||
disablePane(); |
||||
} else { |
||||
setSchemaEnable(!this.selectAutoUpdate.isSelected()); |
||||
} |
||||
} |
||||
|
||||
|
||||
private void disablePane() { |
||||
this.selectAutoUpdate.setEnabled(false); |
||||
this.updateInterval.setEnabled(false); |
||||
this.shouldEvolve.setEnabled(false); |
||||
|
||||
this.selectBySchema.setEnabled(false); |
||||
this.schemaTime.setEnabled(false); |
||||
} |
||||
|
||||
private void setSchemaEnable(boolean enable) { |
||||
this.updateInterval.setEnabled(!enable); |
||||
this.shouldEvolve.setEnabled(!enable); |
||||
|
||||
this.schemaTime.setEnabled(enable); |
||||
} |
||||
|
||||
|
||||
public StrategyConfig updateBean() { |
||||
StrategyConfig config = null; |
||||
if (!this.global) { |
||||
try { |
||||
//这里是new的config
|
||||
config = this.strategyConfig.clone(); |
||||
|
||||
if (this.selectBySchema.isSelected()) { |
||||
List<String> schemaTimes = new ArrayList<>(); |
||||
String text = this.schemaTime.getText(); |
||||
|
||||
if (ESDUtils.checkUpdateTimeSchema(text)) { |
||||
if (ESDUtils.isCronExpression(text)) { |
||||
schemaTimes.add(text); |
||||
} else { |
||||
Collections.addAll(schemaTimes, text.split(",")); |
||||
} |
||||
} else { |
||||
this.schemaTimeCheckTips.setVisible(true); |
||||
throw new IllegalArgumentException("[ESD]Update schema time format error."); |
||||
} |
||||
config.setScheduleBySchema(true); |
||||
config.setUpdateSchema(schemaTimes); |
||||
} else { |
||||
String interval = this.updateInterval.getText(); |
||||
if (checkUpdateInterval(interval)) { |
||||
long intervalMillis = StringUtils.isEmpty(interval) ? 0 : (long) (Double.parseDouble(interval) * CacheConstants.MILLIS_OF_MINUTE); |
||||
config.setUpdateInterval(intervalMillis); |
||||
} else { |
||||
this.updateIntervalCheckTips.setVisible(true); |
||||
throw new IllegalArgumentException("[ESD]Error update interval format."); |
||||
} |
||||
|
||||
config.setShouldEvolve(this.shouldEvolve.isSelected()); |
||||
config.setScheduleBySchema(false); |
||||
} |
||||
} catch (CloneNotSupportedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
return config; |
||||
} |
||||
|
||||
|
||||
private boolean checkUpdateInterval(String intervalValue) { |
||||
try { |
||||
return !StringUtils.isEmpty(intervalValue) && !(Double.parseDouble(intervalValue) <= 0); |
||||
} catch (NumberFormatException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
|
||||
protected String title4PopupWindow() { |
||||
return InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cache_Strategy_Config_Title"); |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
package com.fr.design.data.datapane.connect; |
||||
|
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.editlock.EditLockUtils; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.file.ConnectionConfig; |
||||
import com.fr.report.LockItem; |
||||
|
||||
/** |
||||
* @author hades |
||||
* @version 11.0 |
||||
* Created by hades on 2021/9/8 |
||||
*/ |
||||
public class ConnectionListDialogActionAdapter extends DialogActionAdapter { |
||||
|
||||
private final ConnectionManagerPane connectionManagerPane; |
||||
private final BasicDialog connectionListDialog; |
||||
private final ConnectionConfig connectionConfig; |
||||
|
||||
public ConnectionListDialogActionAdapter(ConnectionManagerPane connectionManagerPane, |
||||
BasicDialog connectionListDialog, |
||||
ConnectionConfig connectionConfig) { |
||||
this.connectionManagerPane = connectionManagerPane; |
||||
this.connectionListDialog = connectionListDialog; |
||||
this.connectionConfig = connectionConfig; |
||||
} |
||||
|
||||
@Override |
||||
public void doOk() { |
||||
if (!connectionManagerPane.isNamePermitted()) { |
||||
connectionListDialog.setDoOKSucceed(false); |
||||
return; |
||||
} |
||||
connectionManagerPane.update(connectionConfig); |
||||
DesignerContext.getDesignerBean("databasename").refreshBeanElement(); |
||||
// 关闭定义数据连接页面,为其解锁
|
||||
EditLockUtils.unlock(LockItem.CONNECTION); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void doCancel() { |
||||
// 关闭定义数据连接页面,为其解锁
|
||||
super.doCancel(); |
||||
EditLockUtils.unlock(LockItem.CONNECTION); |
||||
} |
||||
} |
@ -0,0 +1,37 @@
|
||||
package com.fr.design.data.tabledata.strategy; |
||||
|
||||
import com.fr.esd.core.strategy.config.StrategyConfig; |
||||
import com.fr.esd.query.StrategicTableData; |
||||
|
||||
/** |
||||
* @author rinoux |
||||
* @version 10.0 |
||||
* Created by rinoux on 2021/3/19 |
||||
*/ |
||||
public abstract class StrategyConfigHandler<T extends StrategicTableData> { |
||||
|
||||
private final T tableData; |
||||
|
||||
public StrategyConfigHandler(T tableData) { |
||||
this.tableData = tableData; |
||||
} |
||||
|
||||
protected T getTableData() { |
||||
return tableData; |
||||
} |
||||
|
||||
/** |
||||
* 查找配置 |
||||
* |
||||
* @return 缓存配置 |
||||
*/ |
||||
public abstract StrategyConfig find(); |
||||
|
||||
|
||||
/** |
||||
* 保存配置 |
||||
* |
||||
* @param config 缓存配置 |
||||
*/ |
||||
public abstract void save(T saved, StrategyConfig config); |
||||
} |
@ -0,0 +1,33 @@
|
||||
package com.fr.design.data.tabledata.tabledatapane.db; |
||||
|
||||
import com.fr.design.i18n.Toolkit; |
||||
|
||||
public enum StrategyConfigFrom { |
||||
GLOBAL(0, Toolkit.i18nText("Fine-Design_ESD_Use_Global_Settings")), |
||||
|
||||
INDIVIDUAL(1, Toolkit.i18nText("Fine-Design_ESD_Use_Individual_Settings")); |
||||
|
||||
int index; |
||||
|
||||
String displayText; |
||||
|
||||
StrategyConfigFrom(int index, String displayText) { |
||||
this.index = index; |
||||
this.displayText = displayText; |
||||
} |
||||
|
||||
|
||||
public int getIndex() { |
||||
return this.index; |
||||
} |
||||
|
||||
|
||||
public String getDisplayText() { |
||||
return this.displayText; |
||||
} |
||||
|
||||
|
||||
public String toString() { |
||||
return getDisplayText(); |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
import com.fr.design.formula.exception.FormulaExceptionTipsProcessor; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.parser.FRParser; |
||||
import com.fr.script.checker.FunctionCheckerDispatcher; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.script.Expression; |
||||
import com.fr.stable.script.Node; |
||||
import com.fr.third.antlr.TokenStreamRecognitionException; |
||||
|
||||
import java.io.StringReader; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/9/28 |
||||
*/ |
||||
public class FormulaChecker { |
||||
public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula"); |
||||
public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"); |
||||
private static FormulaExceptionTipsProcessor processor = FormulaExceptionTipsProcessor.getProcessor(); |
||||
|
||||
public static FormulaCheckResult check(String formulaText) { |
||||
if (StringUtils.isEmpty(formulaText) || formulaText.equals(Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Tips"))) { |
||||
return new FormulaCheckResult(true, VALID_FORMULA, FormulaCoordinates.INVALID, true); |
||||
} |
||||
//过滤一些空格等符号
|
||||
StringReader in = new StringReader(formulaText); |
||||
//此lexer为公式校验定制
|
||||
FRFormulaLexer lexer = new FRFormulaLexer(in); |
||||
FRParser parser = new FRParser(lexer); |
||||
|
||||
try { |
||||
Expression expression = parser.parse(); |
||||
Node node = expression.getConditionalExpression(); |
||||
boolean valid = FunctionCheckerDispatcher.getInstance().getFunctionChecker(node).checkFunction(formulaText, node); |
||||
return new FormulaCheckResult(valid, valid ? Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula") : |
||||
Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"), FormulaCoordinates.INVALID, true); |
||||
} catch (Exception e) { |
||||
if (e instanceof TokenStreamRecognitionException) { |
||||
return processor.getExceptionTips(((TokenStreamRecognitionException) e).recog); |
||||
} |
||||
return processor.getExceptionTips(e); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
public class FormulaCheckerException extends Exception { |
||||
public FormulaCheckerException() { |
||||
|
||||
} |
||||
|
||||
public FormulaCheckerException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package com.fr.design.formula; |
||||
|
||||
import com.fr.parser.BinaryExpression; |
||||
import com.fr.parser.DatasetFunctionCall; |
||||
import com.fr.parser.FunctionCall; |
||||
import com.fr.stable.script.Node; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/8/30 |
||||
*/ |
||||
public class UnsupportedFormulaScanner { |
||||
public final static String[] UNSUPPORTED_FORMULAS = new String[]{"PROPORTION", "TOIMAGE", |
||||
"WEBIMAGE", "SORT", "CROSSLAYERTOTAL", "CIRCULAR", "LAYERTOTAL", "MOM", "HIERARCHY", |
||||
"FILENAME", "FILESIZE", "FILETYPE", "TREELAYER", "GETUSERDEPARTMENTS", "GETUSERJOBTITLES"}; |
||||
|
||||
private String unSupportFormula = ""; |
||||
|
||||
public boolean travelFormula(Node node) { |
||||
if (node instanceof FunctionCall) { |
||||
if (isUnsupportedFomula(((FunctionCall) node).getName())) { |
||||
unSupportFormula = ((FunctionCall) node).getName(); |
||||
return false; |
||||
} else { |
||||
for (Node argument : ((FunctionCall) node).getArguments()) { |
||||
if (!travelFormula(argument)) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} else if (node instanceof BinaryExpression) { |
||||
for (Node array : ((BinaryExpression) node).getNodes()) { |
||||
if (!travelFormula(array)) { |
||||
return false; |
||||
} |
||||
} |
||||
} else if (node instanceof DatasetFunctionCall) { |
||||
DatasetFunctionCall datasetFunctionCall = (DatasetFunctionCall) node; |
||||
unSupportFormula = datasetFunctionCall.getSourceName() + "." + datasetFunctionCall.getFnName() + "()"; |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public String getUnSupportFormula() { |
||||
return unSupportFormula; |
||||
} |
||||
|
||||
private static boolean isUnsupportedFomula(String formula) { |
||||
return Arrays.asList(UNSUPPORTED_FORMULAS).contains(formula.toUpperCase()); |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.fr.design.formula.exception; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.formula.exception.function.FormulaCheckWrongFunction; |
||||
import com.fr.design.formula.exception.function.MismatchedCharFunction; |
||||
import com.fr.design.formula.exception.function.MismatchedTokenFunction; |
||||
import com.fr.design.formula.exception.function.NoViableAltForCharFunction; |
||||
import com.fr.design.formula.exception.function.NoViableAltFunction; |
||||
import com.fr.script.checker.exception.FunctionCheckWrongException; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.MismatchedCharException; |
||||
import com.fr.third.antlr.MismatchedTokenException; |
||||
import com.fr.third.antlr.NoViableAltException; |
||||
import com.fr.third.antlr.NoViableAltForCharException; |
||||
|
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/26 |
||||
*/ |
||||
public class FormulaExceptionTipsProcessor { |
||||
private static final Map<Class, Function<Exception, FormulaCheckResult>> EXCEPTION_TIPS = new ConcurrentHashMap<>(); |
||||
|
||||
private static final FormulaExceptionTipsProcessor PROCESSOR = new FormulaExceptionTipsProcessor(); |
||||
|
||||
static { |
||||
EXCEPTION_TIPS.put(FunctionCheckWrongException.class, FormulaCheckWrongFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(MismatchedCharException.class, MismatchedCharFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(MismatchedTokenException.class, MismatchedTokenFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(NoViableAltException.class, NoViableAltFunction.getFunction()); |
||||
EXCEPTION_TIPS.put(NoViableAltForCharException.class, NoViableAltForCharFunction.getFunction()); |
||||
|
||||
} |
||||
|
||||
public FormulaCheckResult getExceptionTips(Exception e) { |
||||
return EXCEPTION_TIPS.getOrDefault(e.getClass(), |
||||
e1 -> new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false)) |
||||
.apply(e); |
||||
} |
||||
|
||||
public static FormulaExceptionTipsProcessor getProcessor() { |
||||
return PROCESSOR; |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class FormulaCheckConstants { |
||||
public static final String COLON = ":"; |
||||
public static final String LEFT = "("; |
||||
public static final String COMMON = ","; |
||||
public static final String RIGHT = ")"; |
||||
public static final String BLANK = " "; |
||||
public static final String SINGLE_QUOTES = "'"; |
||||
} |
@ -0,0 +1,78 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.exception.FunctionCheckWrongException; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.script.rules.FunctionParameterType; |
||||
import com.fr.script.rules.FunctionRule; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.util.List; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/26 |
||||
*/ |
||||
public class FormulaCheckWrongFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static FormulaCheckWrongFunction FUNCTION = new FormulaCheckWrongFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof FunctionCheckWrongException) { |
||||
FunctionCheckWrongException ce = (FunctionCheckWrongException) e; |
||||
List<FunctionRule> rules = ce.getRules(); |
||||
String functionName = ce.getFunctionName(); |
||||
StringBuilder errorMsg = new StringBuilder(functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + FormulaCheckConstants.COLON); |
||||
for (int i = 0; i < rules.size(); i++) { |
||||
errorMsg.append(FormulaCheckConstants.LEFT); |
||||
if (rules.get(i).getParameterList().isEmpty()) { |
||||
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param")); |
||||
} |
||||
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) { |
||||
errorMsg.append(getTypeString(functionParameterType)).append(FormulaCheckConstants.COMMON); |
||||
} |
||||
if (FormulaCheckConstants.COMMON.equals(errorMsg.charAt(errorMsg.length() - 1) + StringUtils.EMPTY)) { |
||||
errorMsg.deleteCharAt(errorMsg.length() - 1); |
||||
} |
||||
errorMsg.append(FormulaCheckConstants.RIGHT); |
||||
if (i != rules.size() - 1) { |
||||
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or")); |
||||
} |
||||
} |
||||
return new FormulaCheckResult(false, errorMsg.toString(), new FormulaCoordinates(1, indexPosition(ce.getFormulaText(), ce.getNode().toString())), true); |
||||
} |
||||
return new FormulaCheckResult(false, StringUtils.EMPTY, new FormulaCoordinates(-1, -1), true); |
||||
} |
||||
|
||||
private static String getTypeString(FunctionParameterType type) { |
||||
switch (type) { |
||||
case NUMBER: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number"); |
||||
case STRING: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String"); |
||||
case ANY: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any"); |
||||
case DATE: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date"); |
||||
case BOOLEAN: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean"); |
||||
case ARRAY: |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array"); |
||||
} |
||||
return StringUtils.EMPTY; |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
private int indexPosition(String formulaText, String invalidFormula) { |
||||
//处理一下自己FunctionCall自己拼的逗号逻辑
|
||||
if (invalidFormula.contains(",")) { |
||||
invalidFormula = invalidFormula.substring(0, invalidFormula.indexOf(",")); |
||||
} |
||||
return formulaText.indexOf(invalidFormula); |
||||
} |
||||
} |
@ -0,0 +1,95 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.MismatchedCharException; |
||||
|
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class MismatchedCharFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static MismatchedCharFunction FUNCTION = new MismatchedCharFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof MismatchedCharException) { |
||||
MismatchedCharException charException = (MismatchedCharException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
private String getMessage(MismatchedCharException charException) { |
||||
StringBuffer sb = new StringBuffer(); |
||||
switch (charException.mismatchType) { |
||||
case 1: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": "); |
||||
appendCharName(sb, charException.expecting); |
||||
break; |
||||
case 2: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ") |
||||
.append(FormulaCheckConstants.BLANK) |
||||
.append(FormulaCheckConstants.SINGLE_QUOTES); |
||||
appendCharName(sb, charException.expecting); |
||||
sb.append("';").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway")); |
||||
break; |
||||
case 3: |
||||
case 4: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")); |
||||
if (charException.mismatchType == 4) { |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not")); |
||||
} |
||||
|
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")).append(": "); |
||||
appendCharName(sb, charException.expecting); |
||||
sb.append(".."); |
||||
appendCharName(sb, charException.upper); |
||||
break; |
||||
case 5: |
||||
case 6: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(charException.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append(" ("); |
||||
int[] elems = charException.set.toArray(); |
||||
|
||||
for (int i = 0; i < elems.length; ++i) { |
||||
appendCharName(sb, elems[i]); |
||||
} |
||||
break; |
||||
default: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Char")); |
||||
} |
||||
|
||||
return sb.toString(); |
||||
} |
||||
|
||||
private void appendCharName(StringBuffer sb, int c) { |
||||
switch (c) { |
||||
case 9: |
||||
sb.append("'\\t'"); |
||||
break; |
||||
case 10: |
||||
sb.append("'\\n'"); |
||||
break; |
||||
case 13: |
||||
sb.append("'\\r'"); |
||||
break; |
||||
case 65535: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF")); |
||||
break; |
||||
default: |
||||
sb.append((char) c); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,110 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.antlr.MismatchedTokenException; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class MismatchedTokenFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static MismatchedTokenFunction FUNCTION = new MismatchedTokenFunction(); |
||||
public static final String NULL_STRING = "null"; |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof MismatchedTokenException) { |
||||
MismatchedTokenException charException = (MismatchedTokenException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
public String getMessage(MismatchedTokenException exception) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
Object fieldValue = getFieldValue(exception, "tokenText"); |
||||
String tokenText = fieldValue == null ? NULL_STRING : fieldValue.toString(); |
||||
switch (exception.mismatchType) { |
||||
case 1: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(tokenName(exception.expecting, exception)); |
||||
break; |
||||
case 2: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ") |
||||
.append(tokenName(exception.expecting, exception)) |
||||
.append("; ") |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway")); |
||||
break; |
||||
case 3: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")) |
||||
.append(": ") |
||||
.append(tokenName(exception.expecting, exception)) |
||||
.append("..") |
||||
.append(tokenName(exception.upper, exception)); |
||||
break; |
||||
case 4: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token")) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not")) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")) |
||||
.append(": ") |
||||
.append(tokenName(exception.expecting, exception)) |
||||
.append("..") |
||||
.append(tokenName(exception.upper, exception)); |
||||
break; |
||||
case 5: |
||||
case 6: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ") |
||||
.append(exception.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK) |
||||
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append("("); |
||||
int[] elms = exception.set.toArray(); |
||||
|
||||
for (int i = 0; i < elms.length; ++i) { |
||||
sb.append(' '); |
||||
sb.append(tokenName(elms[i], exception)); |
||||
} |
||||
|
||||
break; |
||||
default: |
||||
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Token")); |
||||
} |
||||
|
||||
return sb.toString(); |
||||
} |
||||
|
||||
private String tokenName(int tokenType, MismatchedTokenException exception) { |
||||
if (tokenType == 0) { |
||||
return "<Set of tokens>"; |
||||
} else { |
||||
String[] tokenNames = (String[]) getFieldValue(exception, "tokenNames"); |
||||
return tokenType >= 0 && tokenType < tokenNames.length ? TranslateTokenUtils.translateToken(tokenNames[tokenType]) : "<" + tokenType + ">"; |
||||
} |
||||
} |
||||
|
||||
|
||||
private Object getFieldValue(Object object, String fieldName) { |
||||
try { |
||||
Field field = object.getClass().getDeclaredField(fieldName); |
||||
field.setAccessible(true); |
||||
return field.get(object); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().warn(e.getMessage(), e); |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.NoViableAltForCharException; |
||||
|
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class NoViableAltForCharFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static NoViableAltForCharFunction FUNCTION = new NoViableAltForCharFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof NoViableAltForCharException) { |
||||
NoViableAltForCharException charException = (NoViableAltForCharException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
public String getMessage(NoViableAltForCharException exception) { |
||||
String mesg = Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Char") + ": "; |
||||
if (exception.foundChar >= ' ' && exception.foundChar <= '~') { |
||||
mesg = mesg + '\''; |
||||
mesg = mesg + exception.foundChar; |
||||
mesg = mesg + '\''; |
||||
} else { |
||||
mesg = mesg + exception.foundChar; |
||||
} |
||||
|
||||
return mesg; |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.formula.FormulaChecker; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.script.checker.result.FormulaCheckResult; |
||||
import com.fr.script.checker.result.FormulaCoordinates; |
||||
import com.fr.third.antlr.NoViableAltException; |
||||
import com.fr.third.antlr.TreeParser; |
||||
|
||||
import java.util.function.Function; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/10/28 |
||||
*/ |
||||
public class NoViableAltFunction implements Function<Exception, FormulaCheckResult> { |
||||
private final static NoViableAltFunction FUNCTION = new NoViableAltFunction(); |
||||
|
||||
@Override |
||||
public FormulaCheckResult apply(Exception e) { |
||||
if (e instanceof NoViableAltException) { |
||||
NoViableAltException altException = (NoViableAltException) e; |
||||
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(altException.line, altException.column - 1); |
||||
return new FormulaCheckResult(false, getMessage(altException), formulaCoordinates, false); |
||||
} |
||||
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false); |
||||
} |
||||
|
||||
public static Function<Exception, FormulaCheckResult> getFunction() { |
||||
return FUNCTION; |
||||
} |
||||
|
||||
public String getMessage(NoViableAltException exception) { |
||||
if (exception.token != null) { |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Token") + ": " + exception.token.getText(); |
||||
} else { |
||||
return exception.node == TreeParser.ASTNULL ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_End_Of_Subtree") : |
||||
Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_AST_Node") + ": " + exception.node.toString(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,96 @@
|
||||
package com.fr.design.formula.exception.function; |
||||
|
||||
import com.fr.design.i18n.Toolkit; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/11/30 |
||||
*/ |
||||
public class TranslateTokenUtils { |
||||
public static String translateToken(String token) { |
||||
switch (token) { |
||||
case ("RPAREN"): |
||||
return ")"; |
||||
case ("LPAREN"): |
||||
return "("; |
||||
case ("COMMA"): |
||||
return ","; |
||||
case ("COLON"): |
||||
return ":"; |
||||
case ("EOF"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF"); |
||||
case ("DOT"): |
||||
return "."; |
||||
case ("FLOT_NUM"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Float_Number"); |
||||
case ("LOR"): |
||||
return "||"; |
||||
case ("LAND"): |
||||
return "&&"; |
||||
case ("EQUAL"): |
||||
return "="; |
||||
case ("EQUAL2"): |
||||
return "="; |
||||
case ("NOT_EQUAL"): |
||||
return "!="; |
||||
case ("NOT_EQUAL2"): |
||||
return "!="; |
||||
case ("GE"): |
||||
return ">="; |
||||
case ("LE"): |
||||
return "<="; |
||||
case ("LT"): |
||||
return "<"; |
||||
case ("PLUS"): |
||||
return "+"; |
||||
case ("MINUS"): |
||||
return "-"; |
||||
case ("STAR"): |
||||
return "*"; |
||||
case ("DIV"): |
||||
return "/"; |
||||
case ("MOD"): |
||||
return "%"; |
||||
case ("POWER"): |
||||
return "^"; |
||||
case ("LNOT"): |
||||
return "!"; |
||||
case ("WAVE"): |
||||
return "~"; |
||||
case ("LBRACK"): |
||||
return "["; |
||||
case ("SEMI"): |
||||
return ";"; |
||||
case ("RBRACK"): |
||||
return "]"; |
||||
case ("LCURLY"): |
||||
return "{"; |
||||
case ("RCURLY"): |
||||
return "}"; |
||||
case ("DCOLON"): |
||||
return ";"; |
||||
case ("INT_NUM"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Integer"); |
||||
case ("CR_ADRESS"): |
||||
return "\n"; |
||||
case ("SHARP"): |
||||
return "#"; |
||||
case ("AT"): |
||||
return "@"; |
||||
case ("QUESTION"): |
||||
return "?"; |
||||
case ("BOR"): |
||||
return "||"; |
||||
case ("BAND"): |
||||
return "&&"; |
||||
case ("Char"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Character"); |
||||
case ("DIGIT"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Digital"); |
||||
case ("XDIGIT"): |
||||
return Toolkit.i18nText("Fine-Design_Basic_Formula_Hexadecimal_Digital"); |
||||
default: |
||||
return token; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@
|
||||
package com.fr.design.fun; |
||||
|
||||
import com.fr.stable.fun.mark.Mutable; |
||||
|
||||
|
||||
public interface PcFitProvider extends Mutable { |
||||
String XML_TAG = "PcFitProvider"; |
||||
int CURRENT_LEVEL = 1; |
||||
|
||||
//设计器上看到的选项
|
||||
String getContentDisplayValue(); |
||||
|
||||
//返回给前端的值
|
||||
int getContentDisplayKey(); |
||||
|
||||
//设计器上的提示信息
|
||||
String getContentDisplayTip(); |
||||
|
||||
} |
@ -0,0 +1,19 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.design.fun.PcFitProvider; |
||||
import com.fr.stable.fun.mark.API; |
||||
|
||||
|
||||
@API(level = PcFitProvider.CURRENT_LEVEL) |
||||
public abstract class AbstractPcFitProvider implements PcFitProvider { |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
|
||||
@Override |
||||
public String mark4Provider() { |
||||
return getClass().getName(); |
||||
} |
||||
} |
@ -0,0 +1,28 @@
|
||||
package com.fr.design.fun.impl; |
||||
|
||||
import com.fr.file.FILE; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
|
||||
/** |
||||
* Created by rinoux on 2016/12/16. |
||||
*/ |
||||
@EnableMetrics |
||||
public class DesignerStartWithEmptyFile extends AbstractDesignerStartOpenFileProcessor { |
||||
|
||||
private static final DesignerStartWithEmptyFile INSTANCE = new DesignerStartWithEmptyFile(); |
||||
|
||||
private DesignerStartWithEmptyFile() { |
||||
} |
||||
|
||||
public static DesignerStartWithEmptyFile getInstance() { |
||||
return INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
@Focus(id = "com.fr.dzstartemptyfile", text = "Fine_Design_Start_Empty_File", source = Original.REPORT) |
||||
public FILE fileToShow() { |
||||
return null; |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
||||
package com.fr.design.gui.autocomplete; |
||||
|
||||
import javax.swing.Icon; |
||||
|
||||
/** |
||||
* @author Hoky |
||||
* @date 2021/11/5 |
||||
*/ |
||||
public class FormulaCompletion extends BasicCompletion { |
||||
private Icon icon; |
||||
|
||||
public FormulaCompletion(CompletionProvider provider, String replacementText, Icon icon) { |
||||
super(provider, replacementText); |
||||
this.icon = icon; |
||||
} |
||||
|
||||
@Override |
||||
public Icon getIcon() { |
||||
return icon; |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
package com.fr.design.gui.frpane; |
||||
|
||||
import java.awt.Component; |
||||
import java.awt.Container; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/17 |
||||
*/ |
||||
public class AttributeChangeUtils { |
||||
private static AbstractAttrNoScrollPane findNearestAttrNoScrollPaneAncestor(Component c) { |
||||
for(Container p = c.getParent(); p != null; p = p.getParent()) { |
||||
if (p instanceof AbstractAttrNoScrollPane) { |
||||
return (AbstractAttrNoScrollPane) p; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static void changeComposedUI(Component composedComponent, boolean fireMiddleStateChanged, UIChangeAction action) { |
||||
AbstractAttrNoScrollPane attrPane = findNearestAttrNoScrollPaneAncestor(composedComponent); |
||||
boolean oldAutoFire = true; |
||||
|
||||
if (!fireMiddleStateChanged) { |
||||
// 禁止属性面板自动处理属性更新
|
||||
if (attrPane != null) { |
||||
oldAutoFire = attrPane.isAutoFireAttributesChanged(); |
||||
attrPane.setAutoFireAttributesChanged(false); |
||||
} |
||||
} |
||||
|
||||
// 更新UI
|
||||
action.changeComposedUI(); |
||||
|
||||
if (!fireMiddleStateChanged) { |
||||
// 恢复属性面板自动处理属性更新
|
||||
if (attrPane != null) { |
||||
attrPane.setAutoFireAttributesChanged(oldAutoFire); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public interface UIChangeAction { |
||||
void changeComposedUI(); |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
package com.fr.design.gui.ibutton; |
||||
|
||||
import com.fr.design.gui.ipoppane.PopupHider; |
||||
import com.fr.design.style.color.ColorControlWindow; |
||||
|
||||
import javax.swing.Icon; |
||||
|
||||
|
||||
public class UINoThemeColorButton extends UIColorButton{ |
||||
|
||||
public UINoThemeColorButton(Icon icon) { |
||||
super(icon); |
||||
} |
||||
|
||||
protected ColorControlWindow initColorControlWindow(){ |
||||
return new NoThemeColorControlWindow(this); |
||||
} |
||||
|
||||
private class NoThemeColorControlWindow extends ColorControlWindow{ |
||||
|
||||
|
||||
public NoThemeColorControlWindow(PopupHider popupHider) { |
||||
super(popupHider); |
||||
} |
||||
|
||||
protected boolean supportThemeColor(){ |
||||
return false; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected void colorChanged() { |
||||
UINoThemeColorButton.this.setColor(this.getColor()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.general.act.BorderPacker; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/11 |
||||
*/ |
||||
public abstract class AbstractBorderPackerPane extends BasicPane { |
||||
|
||||
public abstract void populateBean(BorderPacker style); |
||||
public abstract void updateBean(BorderPacker style); |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,99 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.design.designer.IntervalConstants; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.gui.frpane.UIPercentDragPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.design.mainframe.backgroundpane.GradientBackgroundQuickPane; |
||||
import com.fr.design.widget.FRWidgetFactory; |
||||
import com.fr.general.Background; |
||||
import com.fr.general.act.BackgroundPacker; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.event.ChangeEvent; |
||||
import javax.swing.event.ChangeListener; |
||||
import java.awt.BorderLayout; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/11 |
||||
*/ |
||||
public abstract class AbstractTranslucentBackgroundSpecialPane<T extends BackgroundPacker> extends BasicPane { |
||||
|
||||
private final int uiLabelWidth; |
||||
private final int uiSettingWidth; |
||||
// 背景名称:如主题背景 或 标题背景
|
||||
private final String backgroundName; |
||||
// 背景
|
||||
protected BackgroundSpecialPane backgroundPane = new LayoutBackgroundSpecialPane(); |
||||
// 背景透明度
|
||||
protected UIPercentDragPane opacityPane = new UIPercentDragPane(); |
||||
|
||||
public AbstractTranslucentBackgroundSpecialPane(int uiLabelWidth, int uiSettingWidth, String backgroundName) { |
||||
this.uiLabelWidth = uiLabelWidth; |
||||
this.uiSettingWidth = uiSettingWidth; |
||||
this.backgroundName = backgroundName; |
||||
this.initializePane(); |
||||
} |
||||
|
||||
private void initializePane() { |
||||
setLayout(new BorderLayout(0, 0)); |
||||
|
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; |
||||
|
||||
// 确保BackgroundSpecialPane高度变化时,Label依然保持与其顶部对齐
|
||||
JPanel backgroundLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
backgroundLabelPane.setBorder(BorderFactory.createEmptyBorder(7, 0, 0, 0)); |
||||
backgroundLabelPane.add(FRWidgetFactory.createLineWrapLabel(backgroundName), BorderLayout.NORTH); |
||||
|
||||
JPanel backgroundComposedPane = TableLayoutHelper.createGapTableLayoutPane( |
||||
new JComponent[][]{ |
||||
{backgroundLabelPane, backgroundPane} |
||||
}, |
||||
new double[]{p}, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); |
||||
|
||||
JPanel opacityComposedPane = TableLayoutHelper.createGapTableLayoutPane( |
||||
new JComponent[][]{ |
||||
{new UILabel(""), FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))}, |
||||
{new UILabel(""), opacityPane} |
||||
}, |
||||
new double[]{p, p}, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); |
||||
opacityComposedPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); |
||||
opacityComposedPane.setVisible(false); |
||||
|
||||
backgroundPane.addChangeListener(new ChangeListener() { |
||||
@Override |
||||
public void stateChanged(ChangeEvent e) { |
||||
Background background = backgroundPane.update(); |
||||
opacityComposedPane.setVisible(background != null); |
||||
} |
||||
}); |
||||
|
||||
add(backgroundComposedPane, BorderLayout.NORTH, 0); |
||||
add(opacityComposedPane, BorderLayout.CENTER, 1); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return null; |
||||
} |
||||
|
||||
public abstract void populateBean(T style); |
||||
|
||||
public abstract void updateBean(T style); |
||||
|
||||
protected static class LayoutBackgroundSpecialPane extends BackgroundSpecialPane { |
||||
@Override |
||||
protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() { |
||||
return new GradientBackgroundQuickPane(140); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,33 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.general.act.BorderPacker; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/11 |
||||
*/ |
||||
public class ComponentBodyStylePane extends AbstractTranslucentBackgroundSpecialPane<BorderPacker> { |
||||
|
||||
public ComponentBodyStylePane(int uiLabelWidth) { |
||||
this(uiLabelWidth, -1); |
||||
} |
||||
|
||||
public ComponentBodyStylePane(int uiLabelWidth, int uiSettingWidth) { |
||||
super(uiLabelWidth, uiSettingWidth, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Fill")); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(BorderPacker style) { |
||||
this.backgroundPane.populateBean(style.getBackground()); |
||||
if (this.opacityPane != null) { |
||||
this.opacityPane.populateBean(style.getAlpha()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void updateBean(BorderPacker style) { |
||||
style.setBackground(backgroundPane.update()); |
||||
style.setAlpha((float)opacityPane.updateBean()); |
||||
} |
||||
} |
@ -0,0 +1,109 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.design.designer.IntervalConstants; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.gui.ispinner.UISpinner; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.design.widget.FRWidgetFactory; |
||||
import com.fr.general.act.BorderPacker; |
||||
|
||||
import javax.swing.JComponent; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/11 |
||||
*/ |
||||
public class ComponentIntegralStylePane extends AbstractBorderPackerPane { |
||||
public static final String[] BORDER_STYLE = new String[]{ |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Common"), |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Shadow") |
||||
}; |
||||
|
||||
//渲染风格:有无阴影
|
||||
protected UIComboBox borderStyleCombo; |
||||
// 含图片类型边框的边框配置面板(图片类型边框 + 阴影时存在默认的阴影颜色)
|
||||
protected TranslucentBorderSpecialPane borderPane; |
||||
//边框圆角或圆角裁剪
|
||||
protected UISpinner cornerSpinner; |
||||
|
||||
private final int uiLabelWidth; |
||||
private final int uiSettingWidth; |
||||
private final boolean supportBorderImage; |
||||
private final boolean supportCornerRadius; |
||||
|
||||
public ComponentIntegralStylePane(int uiLabelWidth, |
||||
boolean supportBorderImage, boolean supportCornerRadius) { |
||||
this(uiLabelWidth, -1, supportBorderImage, supportCornerRadius); |
||||
} |
||||
|
||||
public ComponentIntegralStylePane(int uiLabelWidth, int uiSettingWidth) { |
||||
this(uiLabelWidth, uiSettingWidth, true, true); |
||||
} |
||||
|
||||
public ComponentIntegralStylePane( |
||||
int uiLabelWidth, int uiSettingWidth, |
||||
boolean supportBorderImage, boolean supportCornerRadius) { |
||||
this.uiLabelWidth = uiLabelWidth; |
||||
this.uiSettingWidth = uiSettingWidth; |
||||
this.supportBorderImage = supportBorderImage; |
||||
this.supportCornerRadius = supportCornerRadius; |
||||
|
||||
this.initializePane(); |
||||
} |
||||
|
||||
private void initializeComponents() { |
||||
borderStyleCombo = new UIComboBox(BORDER_STYLE); |
||||
borderPane = new TranslucentBorderSpecialPane(this.supportBorderImage); |
||||
cornerSpinner = new UISpinner(0,1000,1,0); |
||||
} |
||||
|
||||
protected void initializePane() { |
||||
setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
this.initializeComponents(); |
||||
|
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
double[] rowSize = supportCornerRadius ? new double[] {p, p, p} : new double[]{p, p}; |
||||
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; |
||||
|
||||
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ |
||||
{FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), FRGUIPaneFactory.createBorderLayoutNorthPaneWithComponent(borderStyleCombo)}, |
||||
{this.borderPane, null}, |
||||
{FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner}, |
||||
}, |
||||
rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); |
||||
|
||||
this.add(content, BorderLayout.NORTH); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(BorderPacker style) { |
||||
if (this.borderStyleCombo != null) { |
||||
this.borderStyleCombo.setSelectedIndex(style.getBorderStyle()); |
||||
} |
||||
if (cornerSpinner != null) { |
||||
this.cornerSpinner.setValue(style.getBorderRadius()); |
||||
} |
||||
if (this.borderPane != null) { |
||||
this.borderPane.populateBean(style); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void updateBean(BorderPacker style) { |
||||
if (borderStyleCombo != null) { |
||||
style.setBorderStyle(borderStyleCombo.getSelectedIndex()); |
||||
} |
||||
if (cornerSpinner != null) { |
||||
style.setBorderRadius((int) cornerSpinner.getValue()); |
||||
} |
||||
if (borderPane != null) { |
||||
borderPane.updateBean(style); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,351 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.base.Utils; |
||||
import com.fr.base.svg.IconUtils; |
||||
import com.fr.design.designer.IntervalConstants; |
||||
import com.fr.design.formula.TinyFormulaPane; |
||||
import com.fr.design.gui.ibutton.UIButtonGroup; |
||||
import com.fr.design.gui.ibutton.UIColorButton; |
||||
import com.fr.design.gui.ibutton.UIToggleButton; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.design.widget.FRWidgetFactory; |
||||
import com.fr.form.ui.LayoutBorderStyle; |
||||
import com.fr.form.ui.WidgetTitle; |
||||
import com.fr.general.FRFont; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.general.act.BorderPacker; |
||||
import com.fr.general.act.TitlePacker; |
||||
import com.fr.stable.Constants; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.Icon; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.event.ChangeEvent; |
||||
import javax.swing.event.ChangeListener; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Dimension; |
||||
import java.awt.Font; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/11 |
||||
*/ |
||||
public class ComponentTitleStylePane extends AbstractBorderPackerPane { |
||||
private static final Dimension BUTTON_SIZE = new Dimension(20, 20); |
||||
public static final TitlePacker DEFAULT_TITLE_PACKER = new WidgetTitle(); |
||||
|
||||
// 标题可见
|
||||
protected UICheckBox visibleCheckbox; |
||||
//标题文字内容
|
||||
protected TinyFormulaPane textContentPane; |
||||
//标题字体格式
|
||||
protected UIComboBox fontFamilyComboBox; |
||||
//标题字体大小
|
||||
protected UIComboBox fontSizeComboBox; |
||||
//标题字体颜色
|
||||
protected UIColorButton fontColorSelectPane; |
||||
//标题字体特殊效果:粗体、斜体、下划线
|
||||
private UIToggleButton fontBoldButton; |
||||
private UIToggleButton fontItalicButton; |
||||
private UIToggleButton fontUnderlineButton; |
||||
// 标题图文混排
|
||||
protected TextInsetImageBackgroundSpecialPane insetImagePane; |
||||
//对齐方式
|
||||
protected UIButtonGroup alignPane; |
||||
//标题整体背景
|
||||
protected TitleTranslucentBackgroundSpecialPane backgroundPane; |
||||
|
||||
// 是否支持用户编辑这些属性(不支持时: 设置面板总是不可见)
|
||||
private boolean isSupportTitleVisible = true; |
||||
private boolean isSupportTitleContent = true; |
||||
private boolean isSupportTitleOtherSetting = true; |
||||
|
||||
// 用于控制各部分设置的可见性
|
||||
private JPanel titleVisiblePane; |
||||
private JPanel titleContentPane; |
||||
private JPanel titleOtherSettingPane; |
||||
|
||||
private final int uiLabelWidth; |
||||
private final int uiSettingWidth; |
||||
|
||||
public ComponentTitleStylePane(int uiLabelWidth) { |
||||
this(uiLabelWidth, -1); |
||||
} |
||||
|
||||
public ComponentTitleStylePane( |
||||
int uiLabelWidth, int uiSettingWidth) { |
||||
this.uiLabelWidth = uiLabelWidth; |
||||
this.uiSettingWidth = uiSettingWidth; |
||||
this.initializePane(); |
||||
} |
||||
|
||||
private void initializeComponents() { |
||||
visibleCheckbox = new UICheckBox(); |
||||
|
||||
textContentPane = new TinyFormulaPane(); |
||||
|
||||
fontFamilyComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); |
||||
FRFont frFont = DEFAULT_TITLE_PACKER.getFrFont(); |
||||
if (frFont != null) { |
||||
String fontFamily = frFont.getFamily(); |
||||
// 使用style中默认的字体初始化titleFontFamilyComboBox,保证UI和数据的一致性
|
||||
this.fontFamilyComboBox.setSelectedItem(fontFamily); |
||||
} |
||||
fontFamilyComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Family")); |
||||
|
||||
fontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES); |
||||
fontSizeComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Size")); |
||||
|
||||
fontColorSelectPane = new UIColorButton(); |
||||
fontColorSelectPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground")); |
||||
fontColorSelectPane.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground")); |
||||
|
||||
fontBoldButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png")); |
||||
fontBoldButton.setPreferredSize(BUTTON_SIZE); |
||||
fontBoldButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold")); |
||||
fontBoldButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold")); |
||||
|
||||
fontItalicButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png")); |
||||
fontItalicButton.setPreferredSize(BUTTON_SIZE); |
||||
fontItalicButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic")); |
||||
fontItalicButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic")); |
||||
|
||||
fontUnderlineButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/underline.png")); |
||||
fontUnderlineButton.setPreferredSize(BUTTON_SIZE); |
||||
fontUnderlineButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline")); |
||||
fontUnderlineButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline")); |
||||
|
||||
insetImagePane = new TextInsetImageBackgroundSpecialPane(); |
||||
|
||||
alignPane = new UIButtonGroup<>( |
||||
new Icon[]{ |
||||
IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"), |
||||
IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"), |
||||
IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png") |
||||
}, |
||||
new Integer[]{Constants.LEFT, Constants.CENTER, Constants.RIGHT}); |
||||
alignPane.setAllToolTips( |
||||
new String[] { |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Left"), |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Center"), |
||||
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Right") |
||||
}); |
||||
alignPane.setSelectedItem(DEFAULT_TITLE_PACKER.getPosition()); |
||||
|
||||
backgroundPane = new TitleTranslucentBackgroundSpecialPane(this.uiLabelWidth, this.uiSettingWidth); |
||||
} |
||||
|
||||
private void initializePane() { |
||||
this.setLayout(new BorderLayout(0, 0)); |
||||
this.initializeComponents(); |
||||
|
||||
titleVisiblePane = this.createTitleVisiblePane(); |
||||
titleContentPane = this.createTitleContentPane(); |
||||
titleOtherSettingPane = this.createTitleOtherSettingPane(); |
||||
|
||||
if (isSupportTitleVisible) { |
||||
titleVisiblePane.setVisible(true); |
||||
} |
||||
if (isSupportTitleVisible) { |
||||
titleContentPane.setVisible(false); |
||||
} |
||||
if (isSupportTitleVisible) { |
||||
titleOtherSettingPane.setVisible(false); |
||||
} |
||||
|
||||
addComponents(titleVisiblePane, titleContentPane, titleOtherSettingPane); |
||||
} |
||||
|
||||
private JPanel createTitleVisiblePane() { |
||||
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
|
||||
visibleCheckbox.setSelected(false); |
||||
|
||||
container.add(visibleCheckbox, BorderLayout.WEST); |
||||
container.add(FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Visible")), BorderLayout.CENTER); |
||||
|
||||
visibleCheckbox.addChangeListener(new ChangeListener() { |
||||
@Override |
||||
public void stateChanged(ChangeEvent e) { |
||||
boolean visible = visibleCheckbox.isSelected(); |
||||
if (titleContentPane != null) { |
||||
titleContentPane.setVisible(visible && isSupportTitleContent); |
||||
} |
||||
if (titleOtherSettingPane != null) { |
||||
titleOtherSettingPane.setVisible(visible && isSupportTitleOtherSetting); |
||||
} |
||||
} |
||||
}); |
||||
return container; |
||||
} |
||||
|
||||
private JPanel createTitleContentPane() { |
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
double[] rowSize = {p}; |
||||
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; |
||||
|
||||
return TableLayoutHelper.createCommonTableLayoutPane( |
||||
new JComponent[][]{{FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), textContentPane}}, |
||||
rowSize, columnSize, IntervalConstants.INTERVAL_L1); |
||||
} |
||||
|
||||
private JPanel createTitleOtherSettingPane() { |
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
double[] rowSize = {p, p, p, p, p}; |
||||
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; |
||||
|
||||
JComponent[][] components = new JComponent[][]{ |
||||
{FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Format")), FRGUIPaneFactory.createBorderLayoutNorthPaneWithComponent(fontFamilyComboBox)}, |
||||
{null, createTitleFontButtonPane()}, |
||||
{insetImagePane, null}, |
||||
{FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Text_Align")), alignPane}, |
||||
{backgroundPane, null} |
||||
}; |
||||
|
||||
return TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, IntervalConstants.INTERVAL_L1); |
||||
} |
||||
|
||||
protected JPanel createTitleFontButtonPane(){ |
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
double[] rowSize = {p}; |
||||
double[] columnSize = {f, p, p, p, p}; |
||||
|
||||
JPanel buttonPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][] { |
||||
{fontSizeComboBox, fontColorSelectPane, fontItalicButton, fontBoldButton, fontUnderlineButton}, |
||||
}, rowSize, columnSize, IntervalConstants.INTERVAL_W0); |
||||
|
||||
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
containerPane.add(buttonPane, BorderLayout.NORTH); |
||||
|
||||
return containerPane; |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(BorderPacker style) { |
||||
TitlePacker widgetTitle = style == null ? new WidgetTitle() : style.getTitle(); |
||||
widgetTitle = widgetTitle == null ? new WidgetTitle() : widgetTitle; |
||||
boolean titleVisible = style != null && style.getType() != LayoutBorderStyle.STANDARD; |
||||
visibleCheckbox.setSelected(isSupportTitleVisible && titleVisible); |
||||
titleContentPane.setVisible(isSupportTitleContent && titleVisible); |
||||
titleOtherSettingPane.setVisible(isSupportTitleOtherSetting && titleVisible); |
||||
|
||||
this.textContentPane.populateBean(widgetTitle.getTextObject().toString()); |
||||
|
||||
FRFont frFont = widgetTitle.getFrFont(); |
||||
this.fontSizeComboBox.setSelectedItem(frFont.getSize()); |
||||
this.fontFamilyComboBox.setSelectedItem(frFont.getFamily()); |
||||
this.fontColorSelectPane.setColor(frFont.getForeground()); |
||||
this.fontColorSelectPane.repaint(); |
||||
fontBoldButton.setSelected(frFont.isBold()); |
||||
fontItalicButton.setSelected(frFont.isItalic()); |
||||
|
||||
int line = frFont.getUnderline(); |
||||
if (line == Constants.LINE_NONE) { |
||||
fontUnderlineButton.setSelected(false); |
||||
} else { |
||||
fontUnderlineButton.setSelected(true); |
||||
} |
||||
|
||||
alignPane.setSelectedItem(widgetTitle.getPosition()); |
||||
insetImagePane.populateBean(widgetTitle); |
||||
backgroundPane.populateBean(widgetTitle); |
||||
} |
||||
|
||||
@Override |
||||
public void updateBean(BorderPacker style) { |
||||
style.setType(visibleCheckbox != null && visibleCheckbox.isSelected() ? LayoutBorderStyle.TITLE : LayoutBorderStyle.STANDARD); |
||||
TitlePacker title = style.getTitle() == null ? new WidgetTitle() : style.getTitle(); |
||||
title.setTextObject(textContentPane.updateBean()); |
||||
FRFont frFont = title.getFrFont(); |
||||
frFont = frFont.applySize((Integer) fontSizeComboBox.getSelectedItem()); |
||||
frFont = frFont.applyName(fontFamilyComboBox.getSelectedItem().toString()); |
||||
frFont = frFont.applyForeground(fontColorSelectPane.getColor()); |
||||
frFont = updateTitleFontItalicBold(frFont); |
||||
int line = fontUnderlineButton.isSelected() ? Constants.LINE_THIN : Constants.LINE_NONE; |
||||
frFont = frFont.applyUnderline(line); |
||||
title.setFrFont(frFont); |
||||
title.setPosition((Integer) alignPane.getSelectedItem()); |
||||
insetImagePane.updateBean(title); |
||||
backgroundPane.updateBean(title); |
||||
style.setTitle(title); |
||||
} |
||||
|
||||
private FRFont updateTitleFontItalicBold(FRFont frFont) { |
||||
int italic_bold = frFont.getStyle(); |
||||
boolean isItalic = italic_bold == Font.ITALIC || italic_bold == (Font.BOLD + Font.ITALIC); |
||||
boolean isBold = italic_bold == Font.BOLD || italic_bold == (Font.BOLD + Font.ITALIC); |
||||
if (fontItalicButton.isSelected() && !isItalic) { |
||||
italic_bold += Font.ITALIC; |
||||
} else if (!fontItalicButton.isSelected() && isItalic) { |
||||
italic_bold -= Font.ITALIC; |
||||
} |
||||
frFont = frFont.applyStyle(italic_bold); |
||||
if (fontBoldButton.isSelected() && !isBold) { |
||||
italic_bold += Font.BOLD; |
||||
} else if (!fontBoldButton.isSelected() && isBold) { |
||||
italic_bold -= Font.BOLD; |
||||
} |
||||
frFont = frFont.applyStyle(italic_bold); |
||||
return frFont; |
||||
} |
||||
|
||||
private void addComponents(JComponent... components) { |
||||
if (components == null) { |
||||
return; |
||||
} |
||||
JPanel container = this; |
||||
for (int i = 0; i < components.length; i++) { |
||||
JComponent component = components[i]; |
||||
if (component != null) { |
||||
container.add(component, BorderLayout.NORTH); |
||||
component.setBorder(BorderFactory.createEmptyBorder(i == 0 ? 0 : IntervalConstants.INTERVAL_L1, 0, 0, 0)); |
||||
if (i < components.length - 1) { |
||||
JPanel nextContainer = new JPanel(FRGUIPaneFactory.createBorderLayout()); |
||||
container.add(nextContainer, BorderLayout.CENTER); |
||||
container = nextContainer; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
public void setSupportTitleVisible(boolean supporting) { |
||||
isSupportTitleVisible = supporting; |
||||
if (titleVisiblePane != null) { |
||||
titleVisiblePane.setVisible(supporting); |
||||
} |
||||
} |
||||
|
||||
public void setSupportTitleContent(boolean supporting) { |
||||
isSupportTitleContent = supporting; |
||||
if (titleContentPane != null) { |
||||
boolean titleVisible = visibleCheckbox.isSelected(); |
||||
if (isSupportTitleContent) { |
||||
titleContentPane.setVisible(titleVisible); |
||||
} else { |
||||
titleContentPane.setVisible(false); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void setSupportOtherSetting(boolean supporting) { |
||||
isSupportTitleOtherSetting = supporting; |
||||
if (titleOtherSettingPane != null) { |
||||
boolean titleVisible = visibleCheckbox.isSelected(); |
||||
if (isSupportTitleOtherSetting) { |
||||
titleOtherSettingPane.setVisible(titleVisible); |
||||
} else { |
||||
titleOtherSettingPane.setVisible(false); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,140 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.base.theme.TemplateTheme; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.event.UIObserver; |
||||
import com.fr.design.event.UIObserverListener; |
||||
import com.fr.design.file.HistoryTemplateListCache; |
||||
import com.fr.design.gui.frpane.AttributeChangeUtils; |
||||
import com.fr.design.gui.ibutton.UIButtonGroup; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.design.widget.FRWidgetFactory; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Component; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/19 |
||||
*/ |
||||
public class FollowingThemePane extends BasicPane implements UIObserver { |
||||
public static final int SETTING_LABEL_WIDTH = 60; |
||||
|
||||
public static final String[] FOLLOWING_THEME_STRING_ARRAYS = new String[]{ |
||||
Toolkit.i18nText("Fine-Design_Style_Follow_Theme"), |
||||
Toolkit.i18nText("Fine-Design_Style_Not_Follow_Theme"), |
||||
}; |
||||
|
||||
private final UIButtonGroup<String> followingThemeButtonGroup; |
||||
private final List<FollowingThemeActionChangeListener> changeListeners = new ArrayList<>(); |
||||
private UIObserverListener uiObserverListener; |
||||
|
||||
private JPanel container; |
||||
|
||||
public FollowingThemePane(String name) { |
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); |
||||
|
||||
followingThemeButtonGroup = new UIButtonGroup<>(FOLLOWING_THEME_STRING_ARRAYS); |
||||
followingThemeButtonGroup.setAutoFireStateChanged(false); |
||||
followingThemeButtonGroup.setSelectedIndex(1); |
||||
followingThemeButtonGroup.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
AttributeChangeUtils.changeComposedUI(FollowingThemePane.this, false, new AttributeChangeUtils.UIChangeAction() { |
||||
@Override |
||||
public void changeComposedUI() { |
||||
for (FollowingThemeActionChangeListener changeListener : changeListeners) { |
||||
changeListener.onFollowingTheme(isFollowingTheme()); |
||||
} |
||||
invalidate(); |
||||
} |
||||
}); |
||||
if (uiObserverListener != null) { |
||||
uiObserverListener.doChange(); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
UILabel followingThemeLabel = FRWidgetFactory.createLineWrapLabel(name); |
||||
|
||||
double p = TableLayout.PREFERRED; |
||||
double f = TableLayout.FILL; |
||||
JPanel followingThemePane = |
||||
TableLayoutHelper.createGapTableLayoutPane( new Component[][]{new Component[] { followingThemeLabel, FRGUIPaneFactory.createBorderLayoutNorthPaneWithComponent(followingThemeButtonGroup)}}, |
||||
new double[] { p }, new double[] { SETTING_LABEL_WIDTH, f }, 10, 0); |
||||
followingThemePane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||
followingThemePane.setVisible(false); |
||||
|
||||
add(followingThemePane, BorderLayout.NORTH); |
||||
container = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
add(container, BorderLayout.CENTER); |
||||
} |
||||
|
||||
public void addFollowThemePane(JPanel content, FollowingThemeActionChangeListener changeListener) { |
||||
if (content != null) { |
||||
container.add(content, BorderLayout.NORTH); |
||||
changeListeners.add(changeListener); |
||||
|
||||
JPanel nextContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
container.add(nextContainer, BorderLayout.CENTER); |
||||
container = nextContainer; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public void registerChangeListener(UIObserverListener uiObserverListener) { |
||||
this.uiObserverListener = uiObserverListener; |
||||
} |
||||
|
||||
@Override |
||||
public boolean shouldResponseChangeListener() { |
||||
return true; |
||||
} |
||||
|
||||
public interface FollowingThemeActionChangeListener { |
||||
void onFollowingTheme(boolean following); |
||||
} |
||||
|
||||
public TemplateTheme getUsingTheme() { |
||||
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||
if (template != null) { |
||||
return template.getTemplateTheme(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public void supportFollowingTheme(boolean supporting) { |
||||
getComponent(0).setVisible(supporting); |
||||
if (!supporting) { |
||||
setFollowingTheme(false); |
||||
} |
||||
} |
||||
|
||||
public void setFollowingTheme(boolean following) { |
||||
followingThemeButtonGroup.setSelectedIndex(following ? 0 : 1); |
||||
for (FollowingThemeActionChangeListener changeListener : changeListeners) { |
||||
changeListener.onFollowingTheme(isFollowingTheme()); |
||||
} |
||||
} |
||||
public boolean isFollowingTheme() { |
||||
return followingThemeButtonGroup.getSelectedIndex() == 0; |
||||
} |
||||
} |
@ -0,0 +1,102 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.design.ExtraDesignClassManager; |
||||
import com.fr.design.event.UIObserverListener; |
||||
import com.fr.design.fun.BackgroundQuickUIProvider; |
||||
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.ColorBackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.GradientBackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.ImageBackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.NullBackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.PatternBackgroundQuickPane; |
||||
import com.fr.design.mainframe.backgroundpane.TextureBackgroundQuickPane; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/19 |
||||
*/ |
||||
public class ReportBackgroundSpecialPane extends BackgroundPane { |
||||
public ReportBackgroundSpecialPane(){ |
||||
super(); |
||||
} |
||||
|
||||
@Override |
||||
protected BackgroundQuickPane[] supportKindsOfBackgroundUI() { |
||||
NullBackgroundQuickPane nullBackgroundPane = new NullBackgroundQuickPane(); |
||||
|
||||
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane(); |
||||
colorBackgroundPane.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
fireStateChanged(); |
||||
} |
||||
}); |
||||
|
||||
ImageBackgroundQuickPane imageBackgroundPane = new ImageBackgroundQuickPane(); |
||||
imageBackgroundPane.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
fireStateChanged(); |
||||
} |
||||
}); |
||||
|
||||
GradientBackgroundQuickPane gradientBackgroundPane = createGradientBackgroundQuickPane(); |
||||
gradientBackgroundPane.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
fireStateChanged(); |
||||
} |
||||
}); |
||||
|
||||
TextureBackgroundQuickPane textureBackgroundPane = new TextureBackgroundQuickPane(); |
||||
textureBackgroundPane.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
fireStateChanged(); |
||||
} |
||||
}); |
||||
|
||||
PatternBackgroundQuickPane patternBackgroundPane = new PatternBackgroundQuickPane(); |
||||
patternBackgroundPane.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
fireStateChanged(); |
||||
} |
||||
}); |
||||
|
||||
|
||||
|
||||
List<BackgroundQuickPane> kinds = new ArrayList<BackgroundQuickPane>(); |
||||
|
||||
kinds.add(nullBackgroundPane); |
||||
kinds.add(colorBackgroundPane); |
||||
kinds.add(imageBackgroundPane); |
||||
kinds.add(gradientBackgroundPane); |
||||
kinds.add(textureBackgroundPane); |
||||
kinds.add(patternBackgroundPane); |
||||
|
||||
Set<BackgroundQuickUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(BackgroundQuickUIProvider.MARK_STRING); |
||||
for (BackgroundQuickUIProvider provider : providers) { |
||||
BackgroundQuickPane newTypePane = provider.appearanceForBackground(); |
||||
newTypePane.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
fireStateChanged(); |
||||
} |
||||
}); |
||||
kinds.add(newTypePane); |
||||
} |
||||
|
||||
return kinds.toArray(new BackgroundQuickPane[kinds.size()]); |
||||
} |
||||
|
||||
protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() { |
||||
// 使用默认的150宽度构建渐变条
|
||||
return new GradientBackgroundQuickPane(); |
||||
} |
||||
} |
@ -0,0 +1,86 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.base.Style; |
||||
import com.fr.design.constants.LayoutConstants; |
||||
import com.fr.design.designer.IntervalConstants; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.design.mainframe.theme.edit.ui.LabelUtils; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.JTextArea; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
|
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/29 |
||||
*/ |
||||
public class TextFontTippedPane extends AbstractBasicStylePane { |
||||
|
||||
private FRFontPane fontPane; |
||||
|
||||
public TextFontTippedPane(boolean showFormatTip) { |
||||
this.initializePane(showFormatTip); |
||||
} |
||||
|
||||
private void initializePane(boolean showFormatTip) { |
||||
setLayout(new BorderLayout()); |
||||
setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); |
||||
|
||||
fontPane = new FRFontPane(); |
||||
this.add(createLabeledPane(Toolkit.i18nText("Fine-Design_Form_FR_Font"), fontPane), BorderLayout.NORTH); |
||||
|
||||
if (showFormatTip) { |
||||
JPanel formatTipPane = createFormatTipPane(); |
||||
this.add(formatTipPane, BorderLayout.CENTER); |
||||
} |
||||
} |
||||
|
||||
private JPanel createLabeledPane(String text, JPanel panel) { |
||||
double f = TableLayout.FILL; |
||||
double p = TableLayout.PREFERRED; |
||||
double[] rowSize = { p }; |
||||
double[] columnSize = {p, f}; |
||||
|
||||
UILabel uiLabel = new UILabel(text); |
||||
JPanel uiLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
uiLabelPane.add(uiLabel, BorderLayout.NORTH); |
||||
|
||||
return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ |
||||
new Component[] { uiLabelPane, panel }, |
||||
}, rowSize, columnSize, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); |
||||
} |
||||
|
||||
private JPanel createFormatTipPane() { |
||||
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
container.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); |
||||
JTextArea formatMigratedTip = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Report_Format_Style_Migrated_Tip"), new Color(153, 153, 153)); |
||||
|
||||
container.add(formatMigratedTip, BorderLayout.NORTH); |
||||
return container; |
||||
} |
||||
|
||||
@Override |
||||
public String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Report_Text"); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(Style style) { |
||||
this.fontPane.populateBean(style); |
||||
} |
||||
|
||||
@Override |
||||
public Style update(Style style) { |
||||
return this.fontPane.update(style); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,485 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.base.CoreDecimalFormat; |
||||
import com.fr.base.GraphHelper; |
||||
import com.fr.base.Style; |
||||
import com.fr.base.TextFormat; |
||||
import com.fr.data.core.FormatField; |
||||
import com.fr.data.core.FormatField.FormatContents; |
||||
import com.fr.design.border.UIRoundedBorder; |
||||
import com.fr.design.constants.LayoutConstants; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.event.GlobalNameListener; |
||||
import com.fr.design.event.GlobalNameObserver; |
||||
import com.fr.design.event.UIObserverListener; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.icombobox.TextFontComboBox; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.gui.icombobox.UIComboBoxRenderer; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JLabel; |
||||
import javax.swing.JList; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingConstants; |
||||
import javax.swing.UIManager; |
||||
import javax.swing.border.Border; |
||||
import javax.swing.border.TitledBorder; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.CardLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Dimension; |
||||
import java.awt.FontMetrics; |
||||
import java.awt.Graphics; |
||||
import java.awt.event.ItemEvent; |
||||
import java.awt.event.ItemListener; |
||||
import java.math.RoundingMode; |
||||
import java.text.Format; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Arrays; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/9/29 |
||||
* 包含格式相关的设置 |
||||
*/ |
||||
public class TextFormatPane extends AbstractBasicStylePane implements GlobalNameObserver { |
||||
private static final long serialVersionUID = 724330854437726751L; |
||||
|
||||
private static final int LABEL_X = 4; |
||||
private static final int LABEL_Y = 18; |
||||
private static final int LABEL_DELTA_WIDTH = 8; |
||||
private static final int LABEL_HEIGHT = 15; //标签背景的范围
|
||||
private static final int CURRENCY_FLAG_POINT = 6; |
||||
|
||||
private static final Integer[] TYPES = new Integer[]{ |
||||
FormatContents.NULL, FormatContents.NUMBER, |
||||
FormatContents.CURRENCY, FormatContents.PERCENT, |
||||
FormatContents.SCIENTIFIC, FormatContents.DATE, |
||||
FormatContents.TIME, FormatContents.TEXT}; |
||||
|
||||
private static final Integer[] DATE_TYPES = new Integer[]{FormatContents.NULL, FormatContents.DATE, FormatContents.TIME}; |
||||
|
||||
private Format format; |
||||
|
||||
private UIComboBox typeComboBox; |
||||
private TextFontComboBox textField; |
||||
private UILabel sampleLabel; |
||||
private JPanel contentPane; |
||||
private JPanel txtCenterPane; |
||||
private JPanel centerPane; |
||||
private JPanel optionPane; |
||||
private UICheckBox roundingBox; |
||||
private JPanel formatFontPane; |
||||
private boolean isRightFormat; |
||||
private boolean isDate = false; |
||||
private GlobalNameListener globalNameListener = null; |
||||
|
||||
/** |
||||
* Constructor. |
||||
*/ |
||||
public TextFormatPane() { |
||||
this.initComponents(TYPES); |
||||
} |
||||
|
||||
protected UIComboBox getTypeComboBox() { |
||||
return typeComboBox; |
||||
} |
||||
|
||||
protected void initComponents(Integer[] types) { |
||||
this.setLayout(new BorderLayout(0, 4)); |
||||
initSampleLabel(); |
||||
contentPane = new JPanel(new BorderLayout(0, 4)) { |
||||
@Override |
||||
public Dimension getPreferredSize() { |
||||
return new Dimension(super.getPreferredSize().width, 65); |
||||
} |
||||
}; |
||||
typeComboBox = new UIComboBox(types); |
||||
UIComboBoxRenderer render = createComBoxRender(); |
||||
typeComboBox.setRenderer(render); |
||||
typeComboBox.addItemListener(itemListener); |
||||
typeComboBox.setGlobalName("typeComboBox"); |
||||
contentPane.add(sampleLabel, BorderLayout.NORTH); |
||||
|
||||
txtCenterPane = new JPanel(new BorderLayout()); |
||||
textField = new TextFontComboBox(); |
||||
textField.addItemListener(textFieldItemListener); |
||||
textField.setEditable(true); |
||||
textField.setGlobalName("textField"); |
||||
txtCenterPane.add(textField, BorderLayout.NORTH); |
||||
|
||||
contentPane.add(txtCenterPane, BorderLayout.CENTER); |
||||
|
||||
centerPane = new JPanel(new CardLayout()); |
||||
centerPane.add(new JPanel(), "hide"); |
||||
centerPane.setPreferredSize(new Dimension(0, 0)); |
||||
centerPane.add(contentPane, "show"); |
||||
|
||||
typeComboBox.setPreferredSize(new Dimension(155,20)); |
||||
JPanel typePane = new JPanel(new BorderLayout()); |
||||
typePane.add(typeComboBox, BorderLayout.CENTER); |
||||
typePane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); |
||||
|
||||
JPanel option = new JPanel(new BorderLayout()); |
||||
option.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Option"), SwingConstants.LEFT), BorderLayout.WEST); |
||||
roundingBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Base_Option_Half_Up")); |
||||
roundingBox.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0)); |
||||
roundingBox.addItemListener(new ItemListener() { |
||||
@Override |
||||
public void itemStateChanged(ItemEvent e) { |
||||
} |
||||
}); |
||||
roundingBox.setGlobalName("roundingBox"); |
||||
option.add(roundingBox, BorderLayout.CENTER); |
||||
optionPane = new JPanel(new CardLayout()); |
||||
optionPane.add(new JPanel(), "hide"); |
||||
optionPane.setPreferredSize(new Dimension(0, 0)); |
||||
optionPane.add(option, "show"); |
||||
|
||||
Component[][] components = getComponent(centerPane, typePane); |
||||
this.add(createContentPane(components), BorderLayout.CENTER); |
||||
} |
||||
|
||||
protected JPanel createContentPane (Component[][] components) { |
||||
double f = TableLayout.FILL; |
||||
double p = TableLayout.PREFERRED; |
||||
double[] rowSize = new double[components.length]; |
||||
Arrays.fill(rowSize, p); |
||||
double[] columnSize = {p, f}; |
||||
int[][] rowCount = new int[components.length][2]; |
||||
Arrays.fill(rowCount, new int[] {1, 1}); |
||||
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); |
||||
} |
||||
|
||||
|
||||
protected Component[][] getComponent (JPanel centerPane, JPanel typePane) { |
||||
return new Component[][]{ |
||||
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Format"), SwingConstants.LEFT), typePane}, |
||||
new Component[]{centerPane, null}, |
||||
new Component[]{optionPane, null}, |
||||
}; |
||||
} |
||||
|
||||
protected UIComboBoxRenderer createComBoxRender() { |
||||
return new UIComboBoxRenderer() { |
||||
@Override |
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
||||
if (value instanceof Integer) { |
||||
label.setText(" " + FormatField.getInstance().getName((Integer) value)); |
||||
} |
||||
return label; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
private void initSampleLabel() { |
||||
Border interBorder = new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 4); |
||||
String title = Toolkit.i18nText("Fine-Design_Report_Base_StyleFormat_Sample"); |
||||
Border border = BorderFactory.createTitledBorder(interBorder, title, TitledBorder.LEFT, 0, null, UIConstants.LINE_COLOR); |
||||
sampleLabel = new UILabel(FormatField.getInstance().getFormatValue()) { |
||||
|
||||
@Override |
||||
public void paint(Graphics g) { |
||||
super.paint(g); |
||||
int width = getWidth(); |
||||
Color original = g.getColor(); |
||||
g.setColor(getBackground()); |
||||
g.fillRect(LABEL_X, LABEL_Y, width - LABEL_DELTA_WIDTH, LABEL_HEIGHT); |
||||
g.setColor(UIConstants.LINE_COLOR); |
||||
FontMetrics cellFM = g.getFontMetrics(); |
||||
int textWidth = cellFM.stringWidth(getText()); |
||||
GraphHelper.drawString(g, getText(), (width - textWidth) / 2, 26); |
||||
g.setColor(original); |
||||
} |
||||
}; |
||||
sampleLabel.setHorizontalAlignment(UILabel.CENTER); |
||||
sampleLabel.setBorder(border); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
/** |
||||
* 得到合适的大小 |
||||
*/ |
||||
public Dimension getPreferredSize() { |
||||
if (this.typeComboBox.getSelectedIndex() == FormatContents.NULL) { |
||||
return typeComboBox.getPreferredSize(); |
||||
} |
||||
return super.getPreferredSize(); |
||||
} |
||||
|
||||
/** |
||||
* 弹出框标题 |
||||
* |
||||
* @return 标题 |
||||
*/ |
||||
public String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Report_Text"); |
||||
} |
||||
|
||||
/** |
||||
* Populate |
||||
*/ |
||||
public void populateBean(Format format) { |
||||
this.format = format; |
||||
|
||||
if (format == null) { |
||||
this.typeComboBox.setSelectedIndex(FormatContents.NULL); |
||||
} else { |
||||
if (format instanceof CoreDecimalFormat) { |
||||
// check all value
|
||||
String pattern = ((CoreDecimalFormat) format).toPattern(); |
||||
if (isCurrencyFormatStyle(pattern)) { |
||||
setPatternComboBoxAndList(FormatContents.CURRENCY, pattern); |
||||
} else if (pattern.indexOf("%") > 0) { |
||||
setPatternComboBoxAndList(FormatContents.PERCENT, pattern); |
||||
this.roundingBox.setSelected(((CoreDecimalFormat) format).getRoundingMode().equals(RoundingMode.HALF_UP)); |
||||
} else if (pattern.indexOf("E") > 0) { |
||||
setPatternComboBoxAndList(FormatContents.SCIENTIFIC, pattern); |
||||
} else { |
||||
setPatternComboBoxAndList(FormatContents.NUMBER, pattern); |
||||
} |
||||
} else if (format instanceof SimpleDateFormat) { // date and time
|
||||
String pattern = ((SimpleDateFormat) format).toPattern(); |
||||
if (!isTimeType(pattern)) { |
||||
setPatternComboBoxAndList(FormatContents.DATE, pattern); |
||||
} else { |
||||
setPatternComboBoxAndList(FormatContents.TIME, pattern); |
||||
} |
||||
} else if (format instanceof TextFormat) { // Text
|
||||
this.typeComboBox.setSelectedItem(FormatContents.TEXT); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private boolean isCurrencyFormatStyle(String pattern) { |
||||
if (pattern.length() == 0) { |
||||
return false; |
||||
} |
||||
|
||||
if (pattern.charAt(0) == '¤' || pattern.charAt(0) == '$') { |
||||
return true; |
||||
} |
||||
|
||||
return pattern.length() > CURRENCY_FLAG_POINT && pattern.startsWith("#,##0;"); |
||||
} |
||||
|
||||
/** |
||||
* 判断是否是数组有模式 |
||||
* |
||||
* @param stringArray 字符串数组 |
||||
* @param pattern 格式 |
||||
* @return 是否是数组有模式 |
||||
*/ |
||||
public static int isArrayContainPattern(String[] stringArray, String pattern) { |
||||
for (int i = 0; i < stringArray.length; i++) { |
||||
if (ComparatorUtils.equals(stringArray[i], pattern)) { |
||||
return i; |
||||
} |
||||
} |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
private void setPatternComboBoxAndList(int formatStyle, String pattern) { |
||||
this.typeComboBox.setSelectedItem(formatStyle); |
||||
this.textField.setSelectedItem(pattern); |
||||
} |
||||
|
||||
private boolean isTimeType(String pattern) { |
||||
return pattern.matches(".*[Hhmsa].*"); |
||||
} |
||||
|
||||
/** |
||||
* update |
||||
*/ |
||||
public Format update() { |
||||
String patternString = String.valueOf(textField.getSelectedItem()); |
||||
if (getFormatContents() == FormatContents.TEXT) { |
||||
return FormatField.getInstance().getFormat(getFormatContents(), patternString); |
||||
} |
||||
if (isRightFormat) { |
||||
if (StringUtils.isNotEmpty(patternString)) { |
||||
RoundingMode roundingMode = roundingBox.isSelected() ? RoundingMode.HALF_UP : RoundingMode.HALF_EVEN; |
||||
return FormatField.getInstance().getFormat(getFormatContents(), patternString, roundingMode); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private int getFormatContents() { |
||||
return (Integer) typeComboBox.getSelectedItem(); |
||||
} |
||||
|
||||
/** |
||||
* Refresh preview label. |
||||
*/ |
||||
private void refreshPreviewLabel() { |
||||
this.sampleLabel.setText(FormatField.getInstance().getFormatValue()); |
||||
this.sampleLabel.setForeground(UIManager.getColor("Label.foreground")); |
||||
try { |
||||
isRightFormat = true; |
||||
if (StringUtils.isEmpty(String.valueOf(textField.getSelectedItem()))) { |
||||
return; |
||||
} |
||||
this.sampleLabel.setText(FormatField.getInstance().getFormatValue(getFormatContents(), String.valueOf(textField.getSelectedItem()))); |
||||
} catch (Exception e) { |
||||
this.sampleLabel.setForeground(Color.red); |
||||
this.sampleLabel.setText(e.getMessage()); |
||||
isRightFormat = false; |
||||
} |
||||
} |
||||
|
||||
private boolean isTextOrNull() { |
||||
int contents = getFormatContents(); |
||||
return contents == FormatContents.TEXT || contents == FormatContents.NULL; |
||||
} |
||||
|
||||
/** |
||||
* Radio selection listener. |
||||
*/ |
||||
ItemListener itemListener = new ItemListener() { |
||||
|
||||
@Override |
||||
public void itemStateChanged(ItemEvent e) { |
||||
if (e.getStateChange() == ItemEvent.SELECTED) { |
||||
int contents = getFormatContents(); |
||||
String[] items = FormatField.getInstance().getFormatArray(contents, false); |
||||
CardLayout cardLayout = (CardLayout) centerPane.getLayout(); |
||||
|
||||
if (isTextOrNull()) { |
||||
centerPane.setPreferredSize(new Dimension(0, 0)); |
||||
cardLayout.show(centerPane, "hide"); |
||||
} else { |
||||
textField.removeAllItems(); |
||||
textField.setItemArray(items); |
||||
textField.setSelectedIndex(0); |
||||
centerPane.setPreferredSize(new Dimension(270, 65)); |
||||
cardLayout.show(centerPane, "show"); |
||||
} |
||||
CardLayout optionLayout = ((CardLayout) optionPane.getLayout()); |
||||
if (getFormatContents() == FormatContents.PERCENT) { |
||||
optionPane.setPreferredSize(new Dimension(100, 20)); |
||||
optionLayout.show(optionPane, "show"); |
||||
} else { |
||||
optionPane.setPreferredSize(new Dimension(0, 0)); |
||||
optionLayout.show(optionPane, "hide"); |
||||
roundingBox.setSelected(false); |
||||
} |
||||
} |
||||
|
||||
} |
||||
}; |
||||
|
||||
ItemListener textFieldItemListener = new ItemListener() { |
||||
@Override |
||||
public void itemStateChanged(ItemEvent e) { |
||||
if (e.getStateChange() == ItemEvent.SELECTED) { |
||||
refreshPreviewLabel(); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
@Override |
||||
/** |
||||
* populate |
||||
*/ |
||||
public void populateBean(Style style) { |
||||
this.populateBean(style.getFormat()); |
||||
} |
||||
|
||||
@Override |
||||
/** |
||||
* update |
||||
*/ |
||||
public Style update(Style style) { |
||||
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), "textField") |
||||
|| ComparatorUtils.equals(globalNameListener.getGlobalName(), "typeComboBox") |
||||
|| ComparatorUtils.equals(globalNameListener.getGlobalName(), "roundingBox")) { |
||||
return style.deriveFormat(this.update()); |
||||
} |
||||
return style; |
||||
} |
||||
|
||||
/** |
||||
* 默认只显示百分比的编辑下拉. |
||||
*/ |
||||
public void justUsePercentFormat() { |
||||
typeComboBox.setEnabled(false); |
||||
this.typeComboBox.setSelectedItem(FormatContents.PERCENT); |
||||
} |
||||
|
||||
public void setForDataSheet() { |
||||
Integer[] otherTypes = new Integer[]{FormatContents.NULL, FormatContents.NUMBER, FormatContents.CURRENCY, FormatContents.PERCENT, FormatContents.SCIENTIFIC,}; |
||||
this.typeComboBox = new UIComboBox(otherTypes); |
||||
UIComboBoxRenderer render = new UIComboBoxRenderer() { |
||||
@Override |
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
||||
if (value instanceof Integer) { |
||||
label.setText(" " + FormatField.getInstance().getName((Integer) value)); |
||||
} |
||||
return label; |
||||
} |
||||
}; |
||||
typeComboBox.setRenderer(render); |
||||
typeComboBox.addItemListener(itemListener); |
||||
setTypeComboBoxPane(typeComboBox); |
||||
} |
||||
|
||||
protected void setTypeComboBoxPane (UIComboBox typeComboBox) { |
||||
this.add(typeComboBox, BorderLayout.NORTH); |
||||
} |
||||
|
||||
public void setComboBoxModel(boolean isDate) { |
||||
if (this.isDate != isDate) { |
||||
this.isDate = isDate; |
||||
this.typeComboBox.setSelectedIndex(0); |
||||
if (isDate) { |
||||
for (int i = 0; i < DATE_TYPES.length; i++) { |
||||
this.typeComboBox.addItem(DATE_TYPES[i]); |
||||
} |
||||
for (int i = 0; i < TYPES.length; i++) { |
||||
this.typeComboBox.removeItemAt(1); |
||||
} |
||||
} else { |
||||
for (int i = 0; i < TYPES.length; i++) { |
||||
this.typeComboBox.addItem(TYPES[i]); |
||||
} |
||||
for (int i = 0; i < DATE_TYPES.length; i++) { |
||||
this.typeComboBox.removeItemAt(1); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void registerNameListener(GlobalNameListener listener) { |
||||
globalNameListener = listener; |
||||
} |
||||
|
||||
public void registerChangeListener(UIObserverListener listener) { |
||||
typeComboBox.registerChangeListener(listener); |
||||
textField.registerChangeListener(listener); |
||||
} |
||||
|
||||
@Override |
||||
public boolean shouldResponseNameListener() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public void setGlobalName(String name) { |
||||
|
||||
} |
||||
} |
@ -0,0 +1,27 @@
|
||||
package com.fr.design.gui.style; |
||||
|
||||
import com.fr.general.act.TitlePacker; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/8/11 |
||||
*/ |
||||
public class TitleTranslucentBackgroundSpecialPane extends AbstractTranslucentBackgroundSpecialPane<TitlePacker> { |
||||
|
||||
public TitleTranslucentBackgroundSpecialPane(int uiLabelWidth, int uiSettingWidth) { |
||||
super(uiLabelWidth, uiSettingWidth, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Background")); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(TitlePacker style) { |
||||
backgroundPane.populateBean(style.getBackground()); |
||||
opacityPane.populateBean(style.getBackgroundOpacity()); |
||||
} |
||||
|
||||
@Override |
||||
public void updateBean(TitlePacker style) { |
||||
style.setBackground(backgroundPane.update()); |
||||
style.setBackgroundOpacity((float)opacityPane.updateBean()); |
||||
} |
||||
} |
@ -0,0 +1,328 @@
|
||||
package com.fr.design.hyperlink.popup; |
||||
|
||||
import com.fr.base.BaseFormula; |
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.base.Parameter; |
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.formula.TinyFormulaPane; |
||||
import com.fr.design.gui.frpane.ReportletParameterViewPane; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.ibutton.UIRadioButton; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditAction; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.gui.itree.filetree.ReportletPane; |
||||
import com.fr.design.hyperlink.AbstractHyperLinkPane; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.module.DesignModuleFactory; |
||||
import com.fr.design.parameter.ParameterReader; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.js.MobilePopupHyperlink; |
||||
import com.fr.stable.CommonUtils; |
||||
import com.fr.stable.FormulaProvider; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.util.List; |
||||
|
||||
public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperlink> { |
||||
private JPanel popupTargetPane; |
||||
private UIRadioButton templatePopupButton; |
||||
private UIRadioButton textPopupButton; |
||||
private ButtonGroup popupTargetButtons; |
||||
|
||||
private JPanel templateContentPane; |
||||
private UITextField templatePathTextField; |
||||
private UICheckBox extendParametersCheckBox; |
||||
|
||||
private JPanel textSettingPanel; |
||||
private TinyFormulaPane textContentPane; |
||||
private CustomFontPane fontPane; |
||||
|
||||
public ContentSettingPane() { |
||||
super(); |
||||
this.initCompoennt(); |
||||
} |
||||
|
||||
public void addTargetRadioActionListener(ActionListener listener) { |
||||
templatePopupButton.addActionListener(listener); |
||||
textPopupButton.addActionListener(listener); |
||||
} |
||||
|
||||
public String getTargetType() { |
||||
if (templatePopupButton.isSelected()) { |
||||
return MobilePopupConstants.Target_Template; |
||||
} else { |
||||
return MobilePopupConstants.Target_Text; |
||||
} |
||||
|
||||
} |
||||
|
||||
private void initCompoennt() { |
||||
this.setLayout(FRGUIPaneFactory.createM_BorderLayout()); |
||||
this.setBorder(GUICoreUtils.createTitledBorder(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Content"))); |
||||
|
||||
popupTargetPane = this.createPopupTargetPane(); |
||||
this.add(popupTargetPane, BorderLayout.NORTH); |
||||
|
||||
templateContentPane= this.createTemplateContentPane(); |
||||
textSettingPanel = this.createTextSettingPane(); |
||||
} |
||||
|
||||
private JPanel createPopupTargetPane() { |
||||
templatePopupButton = new UIRadioButton(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Template")); |
||||
templatePopupButton.addActionListener(radioActionListener); |
||||
|
||||
textPopupButton = new UIRadioButton(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Text")); |
||||
textPopupButton.addActionListener(radioActionListener); |
||||
|
||||
popupTargetButtons = new ButtonGroup(); |
||||
popupTargetButtons.add(templatePopupButton); |
||||
popupTargetButtons.add(textPopupButton); |
||||
|
||||
JPanel popupButtonsPanel = new JPanel(); |
||||
popupButtonsPanel.setLayout( new FlowLayout(FlowLayout.LEFT, 10, 0)); |
||||
popupButtonsPanel.add(templatePopupButton); |
||||
popupButtonsPanel.add(textPopupButton); |
||||
return MobilePopupUIUtils.createLeftTileRightContentPanel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Target"), popupButtonsPanel); |
||||
} |
||||
|
||||
private ActionListener radioActionListener = new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
if(templatePopupButton.isSelected()) { |
||||
ContentSettingPane.this.add(templateContentPane); |
||||
ContentSettingPane.this.remove(textSettingPanel); |
||||
} else if (textPopupButton.isSelected()) { |
||||
ContentSettingPane.this.add(textSettingPanel); |
||||
ContentSettingPane.this.remove(templateContentPane); |
||||
} |
||||
ContentSettingPane.this.revalidate(); |
||||
ContentSettingPane.this.repaint(); |
||||
} |
||||
}; |
||||
|
||||
private JPanel createTemplateContentPane() { |
||||
JPanel templateContentPane = new JPanel(); |
||||
templateContentPane.setLayout(new BorderLayout(0,8)); |
||||
|
||||
templateContentPane.add(this.createTemplateSelectPanel(), BorderLayout.NORTH); |
||||
|
||||
parameterViewPane = this.createReportletParameterViewPane(); |
||||
templateContentPane.add(parameterViewPane, BorderLayout.CENTER); |
||||
|
||||
extendParametersCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Extends_Report_Parameters")); |
||||
templateContentPane.add(GUICoreUtils.createFlowPane(extendParametersCheckBox, FlowLayout.LEFT), BorderLayout.SOUTH); |
||||
|
||||
return templateContentPane; |
||||
} |
||||
|
||||
private JPanel createTemplateSelectPanel() { |
||||
JPanel templatePanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
// 路径输入框
|
||||
templatePathTextField = new UITextField(20); |
||||
templatePanel.add(templatePathTextField, BorderLayout.CENTER); |
||||
|
||||
// 选择路径按钮
|
||||
UIButton templateSelectButton = new UIButton(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Select")); |
||||
templateSelectButton.setPreferredSize(new Dimension(templateSelectButton.getPreferredSize().width, 20)); |
||||
templatePanel.add(templateSelectButton, BorderLayout.EAST); |
||||
templateSelectButton.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent evt) { |
||||
final ReportletPane reportletPane = new ReportletPane(); |
||||
reportletPane.setSelectedReportletPath(templatePathTextField.getText()); |
||||
BasicDialog reportletDialog = reportletPane.showWindow(SwingUtilities.getWindowAncestor(ContentSettingPane.this)); |
||||
|
||||
reportletDialog.addDialogActionListener(new DialogActionAdapter() { |
||||
@Override |
||||
public void doOk() { |
||||
templatePathTextField.setText(reportletPane.getSelectedReportletPath()); |
||||
} |
||||
}); |
||||
reportletDialog.setVisible(true); |
||||
} |
||||
}); |
||||
return MobilePopupUIUtils.createLeftTileRightContentPanel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Template"), templatePanel); |
||||
} |
||||
|
||||
private ReportletParameterViewPane createReportletParameterViewPane() { |
||||
ReportletParameterViewPane templateParameterViewPane = new ReportletParameterViewPane( |
||||
new UITableEditAction[]{ |
||||
new HyperlinkParametersAction() |
||||
}, |
||||
getChartParaType(), |
||||
getValueEditorPane(), |
||||
getValueEditorPane() |
||||
); |
||||
templateParameterViewPane.setBorder(GUICoreUtils.createTitledBorder(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Parameter"), null)); |
||||
templateParameterViewPane.setPreferredSize(new Dimension(this.getWidth(), 200)); |
||||
return templateParameterViewPane; |
||||
} |
||||
|
||||
private JPanel createTextSettingPane() { |
||||
JPanel textSettingPanel = new JPanel(); |
||||
textSettingPanel.setLayout(new BorderLayout(0,8)); |
||||
|
||||
textContentPane = new TinyFormulaPane(); |
||||
textContentPane.getUITextField().setColumns(20); |
||||
textSettingPanel.add( |
||||
MobilePopupUIUtils.createLeftTileRightContentPanel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Text"), textContentPane), |
||||
BorderLayout.CENTER); |
||||
|
||||
fontPane = new CustomFontPane(); |
||||
textSettingPanel.add( |
||||
MobilePopupUIUtils.createLeftTileRightContentPanel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Style"), fontPane), |
||||
BorderLayout.SOUTH); |
||||
return MobilePopupUIUtils.createTitleSplitLineContentPane("", textSettingPanel); |
||||
} |
||||
|
||||
private String getReportletName() { |
||||
String text = this.templatePathTextField.getText(); |
||||
return StringUtils.isBlank(text) ? StringUtils.EMPTY : text.substring(1); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(MobilePopupHyperlink link) { |
||||
this.populatePopupTargetBean(link.getPopupTarget()); |
||||
this.populateTemplateContentBean(link); |
||||
this.populateTextContentBean(link); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public MobilePopupHyperlink updateBean() { |
||||
return null; |
||||
} |
||||
|
||||
@Override |
||||
public void updateBean(MobilePopupHyperlink link) { |
||||
this.updatePopupTargetBean(link); |
||||
this.updateTemplateContentBean(link); |
||||
this.updateTextContentBean(link); |
||||
} |
||||
|
||||
@Override |
||||
public String title4PopupWindow() { |
||||
return StringUtils.EMPTY; |
||||
} |
||||
|
||||
/** |
||||
* 自动添加模板参数的按钮操作 |
||||
*/ |
||||
private class HyperlinkParametersAction extends UITableEditAction { |
||||
public HyperlinkParametersAction() { |
||||
this.setName(Toolkit.i18nText("Fine-Design_Basic_Template_Parameter")); |
||||
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_report/p.gif")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
String tpl = getReportletName(); |
||||
if (StringUtils.isBlank(tpl)) { |
||||
JOptionPane.showMessageDialog( |
||||
ContentSettingPane.this, |
||||
Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Please_Select_Reportlet") + ".", |
||||
Toolkit.i18nText("Fine-Design_Basic_Message"), |
||||
JOptionPane.WARNING_MESSAGE); |
||||
return; |
||||
} |
||||
|
||||
//根据模板路径返回参数
|
||||
//与当前模块、当前文件无关
|
||||
Parameter[] parameters = new Parameter[0]; |
||||
|
||||
ParameterReader[] readers = DesignModuleFactory.getParameterReaders(); |
||||
for (ParameterReader reader : readers) { |
||||
Parameter[] ps = reader.readParameterFromPath(tpl); |
||||
if (ps != null) { |
||||
parameters = ps; |
||||
} |
||||
} |
||||
parameterViewPane.populate(parameters); |
||||
} |
||||
|
||||
@Override |
||||
public void checkEnabled() { |
||||
//do nothing
|
||||
} |
||||
} |
||||
|
||||
private void populatePopupTargetBean(String target) { |
||||
if (StringUtils.equals(target, MobilePopupConstants.Target_Text)) { |
||||
popupTargetButtons.setSelected(textPopupButton.getModel(), true); |
||||
this.remove(templateContentPane); |
||||
this.add(textSettingPanel, BorderLayout.CENTER); |
||||
} else { |
||||
popupTargetButtons.setSelected(templatePopupButton.getModel(), true); |
||||
this.remove(textSettingPanel); |
||||
this.add(templateContentPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
} |
||||
|
||||
private void updatePopupTargetBean(MobilePopupHyperlink mobilePopupHyperlink) { |
||||
if (templatePopupButton.isSelected()) { |
||||
mobilePopupHyperlink.setPopupTarget(MobilePopupConstants.Target_Template); |
||||
} else if (textPopupButton.isSelected()) { |
||||
mobilePopupHyperlink.setPopupTarget(MobilePopupConstants.Target_Text); |
||||
} |
||||
} |
||||
|
||||
private void populateTemplateContentBean(MobilePopupHyperlink link) { |
||||
// 模板路径
|
||||
templatePathTextField.setText(link.getReportletPath()); |
||||
|
||||
// 参数面板
|
||||
List<ParameterProvider> parameterList = this.parameterViewPane.update(); |
||||
parameterList.clear(); |
||||
ParameterProvider[] parameters =link.getParameters(); |
||||
parameterViewPane.populate(parameters); |
||||
|
||||
// 继承参数
|
||||
extendParametersCheckBox.setSelected(link.isExtendParameters()); |
||||
} |
||||
|
||||
private void updateTemplateContentBean(MobilePopupHyperlink link) { |
||||
link.setReportletPath(templatePathTextField.getText()); |
||||
|
||||
List<ParameterProvider> parameterList = this.parameterViewPane.update(); |
||||
if (!parameterList.isEmpty()) { |
||||
Parameter[] parameters = new Parameter[parameterList.size()]; |
||||
parameterList.toArray(parameters); |
||||
link.setParameters(parameters); |
||||
} else { |
||||
link.setParameters(null); |
||||
} |
||||
|
||||
link.setExtendParameters(extendParametersCheckBox.isSelected()); |
||||
|
||||
} |
||||
|
||||
private void populateTextContentBean(MobilePopupHyperlink link) { |
||||
Object text = link.getPopupText(); |
||||
if (text instanceof FormulaProvider) { |
||||
textContentPane.populateBean(((FormulaProvider) text).getContent()); |
||||
} else { |
||||
textContentPane.populateBean(text == null ? StringUtils.EMPTY : text.toString()); |
||||
} |
||||
fontPane.populateBean(link.getFRFont()); |
||||
} |
||||
private void updateTextContentBean(MobilePopupHyperlink link) { |
||||
link.setPopupText(textContentPane.getUITextField().getText()); |
||||
String text = textContentPane.updateBean(); |
||||
if (CommonUtils.maybeFormula(text)) { |
||||
link.setPopupText(BaseFormula.createFormulaBuilder().build(textContentPane.updateBean())); |
||||
} else { |
||||
link.setPopupText(text); |
||||
} |
||||
|
||||
link.setFRFont(fontPane.updateBean()); |
||||
} |
||||
} |
@ -0,0 +1,100 @@
|
||||
package com.fr.design.hyperlink.popup; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.constants.LayoutConstants; |
||||
import com.fr.design.gui.ibutton.UIColorButton; |
||||
import com.fr.design.gui.ibutton.UIToggleButton; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.utils.gui.GUICoreUtils; |
||||
import com.fr.general.FRFont; |
||||
import com.fr.stable.Constants; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.util.Vector; |
||||
|
||||
public class CustomFontPane extends JPanel { |
||||
private static final int MAX_FONT_SIZE = 100; |
||||
private static final Dimension BUTTON_SIZE = new Dimension(20, 18); |
||||
|
||||
public static Vector<Integer> getFontSizes() { |
||||
Vector<Integer> FONT_SIZES = new Vector<Integer>(); |
||||
for (int i = 1; i < MAX_FONT_SIZE; i++) { |
||||
FONT_SIZES.add(i); |
||||
} |
||||
return FONT_SIZES; |
||||
} |
||||
|
||||
private UIComboBox fontSizeComboBox; |
||||
private UIToggleButton bold; |
||||
private UIToggleButton italic; |
||||
private UIToggleButton underline; |
||||
private UIColorButton colorSelectPane; |
||||
|
||||
public CustomFontPane() { |
||||
this.initComponent(); |
||||
} |
||||
|
||||
private void initComponent() { |
||||
|
||||
fontSizeComboBox = new UIComboBox(getFontSizes()); |
||||
fontSizeComboBox.setPreferredSize(new Dimension(60, 20)); |
||||
fontSizeComboBox.setEditable(true); |
||||
|
||||
colorSelectPane = new UIColorButton(); |
||||
bold = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png")); |
||||
italic = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png")); |
||||
underline = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/underline.png")); |
||||
|
||||
this.setButtonsTips(); |
||||
this.setButtonsSize(BUTTON_SIZE); |
||||
|
||||
Component[] components_font = new Component[]{ |
||||
fontSizeComboBox, colorSelectPane, bold, underline, italic |
||||
}; |
||||
|
||||
JPanel buttonPane = new JPanel(new BorderLayout()); |
||||
buttonPane.add(GUICoreUtils.createFlowPane(components_font, FlowLayout.LEFT, LayoutConstants.HGAP_SMALL)); |
||||
|
||||
this.setLayout(new BorderLayout(0,0)); |
||||
this.add(buttonPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
private void setButtonsTips() { |
||||
colorSelectPane.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Foreground")); |
||||
italic.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Italic")); |
||||
bold.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Bold")); |
||||
underline.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Underline")); |
||||
} |
||||
|
||||
private void setButtonsSize(Dimension size) { |
||||
colorSelectPane.setPreferredSize(size); |
||||
bold.setPreferredSize(size); |
||||
italic.setPreferredSize(size); |
||||
underline.setPreferredSize(size); |
||||
} |
||||
|
||||
|
||||
public void populateBean(FRFont frFont) { |
||||
fontSizeComboBox.setSelectedItem(frFont.getSize()); |
||||
colorSelectPane.setColor(frFont.getForeground()); |
||||
bold.setSelected(frFont.isBold()); |
||||
italic.setSelected(frFont.isItalic()); |
||||
underline.setSelected(frFont.getUnderline() != Constants.LINE_NONE); |
||||
} |
||||
|
||||
public FRFont updateBean() { |
||||
int style = Font.PLAIN; |
||||
style += this.bold.isSelected() ? Font.BOLD : Font.PLAIN; |
||||
style += this.italic.isSelected() ? Font.ITALIC : Font.PLAIN; |
||||
return FRFont.getInstance( |
||||
FRFont.DEFAULT_FONTNAME, |
||||
style, |
||||
Float.parseFloat(fontSizeComboBox.getSelectedItem().toString()), |
||||
colorSelectPane.getColor(), |
||||
underline.isSelected() ? Constants.LINE_THIN : Constants.LINE_NONE |
||||
); |
||||
} |
||||
|
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue