Browse Source
* commit '3e62e8ec333d8b929d550d4efd0d61cf85aa3596': (97 commits) REPORT-71563 FVS报表块不需要支持插入悬浮元素 REPORT-70681 超长文本搜索问题 REPORT-70888 【设计器】大屏编辑器-设计器启动时默认打开的fvs模板会报错 REPORT-71213 关闭alphafine 默认不展示悬浮弹窗 REPORT-71544 M1-MAC 设计器启动后会卡住 主要是转译时,Instrumentation 的性能问题。 马上发布了屏蔽一下,暂时 windows, intel-mac 都未发现这个问题 如果还是有,那就下个版本优化一下,做一个智能判断 REPORT-71158 打开fvs,从远程切换到本地,设计器模板展示空白 REPORT-71449 【冒烟】不复制新的数据集,“剪贴版”的数据集会变化 【问题原因】粘贴的时候没有做clone处理,假如修改粘贴后的数据集,会同步修改掉剪切板里存的Tableda 【改动思路】添加粘贴时TableData的clone逻辑 【review建议】 REPORT-71449 【冒烟】不复制新的数据集,“剪贴版”的数据集会变化 【问题原因】复制到剪切板中的数据集,在粘贴的时候,TableData没做clone处理,当修改粘贴出来的数据集时,会同步影响剪切板里的TableData 【改动思路】粘贴时增加clone处理 【review建议】无 REPORT-71309 fix 可能的npe REPORT-71213 拆分下大方法 && 处理空值 REPORT-71309 && REPORT-71298 搜索展示异常 REPORT-71213 交互点补充:关闭了产品动态时,悬浮按钮不显示有新消息推送 REPORT-71213 设计器关闭失败 REPORT-70446 mac下悬浮弹窗隐藏重新展示时偶现白点 REPORT-70857 数据集复制后独立 【问题原因】匹配TableData时,用的equals比较,但是同一个对象equals为false,目前已知的是存储过程TableData,已经跟rinoux沟通 【改动思路】直接换成对象比较 【review建议】无 REPORT-70857 数据集复制后独立 【问题原因】处理重复代码问题 【改动思路】处理重复代码问题 【review建议】无 REPORT-70857 数据集复制后独立 删去多余import REPORT-70857 数据集复制后独立 【问题原因】跟随复制的时候需要处理存储过程名称问题,其中有匹配TableData的操作,而复制本身还需要处理TableData的clone,如果先clone,再去匹配TableData,对象就不相等了 【改动思路】将匹配TableData的操作放在clone处理之前 【review建议】无 REPORT-70857 数据集复制后独立 【问题原因】数据集在做复制粘贴的时候,没有clone数据源,导致许多变量都共用了,于是会改一个=改一片 【改动方案】添加clone处理 【review建议】无 REPORT-69285 数据连接安全关键字检查拦截,设计器 ...fix-lag
superman
3 years ago
124 changed files with 5297 additions and 348 deletions
@ -0,0 +1,44 @@ |
|||||||
|
package com.fr.design.actions.help.alphafine; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/26 |
||||||
|
*/ |
||||||
|
public class AlphaFineShortCutUtil { |
||||||
|
|
||||||
|
private static final String TYPE = "pressed"; |
||||||
|
private static final String DISPLAY_TYPE = "+"; |
||||||
|
private static final String BACK_SLASH = "BACK_SLASH"; |
||||||
|
private static final String DISPLAY_BACK_SLASH = "\\"; |
||||||
|
private static final String SLASH = "SLASH"; |
||||||
|
private static final String DISPLAY_SLASH = "/"; |
||||||
|
private static final String CONTROL = "CONTROL"; |
||||||
|
private static final String DISPLAY_CONTROL = "ctrl"; |
||||||
|
private static final String OPEN_BRACKET = "OPEN_BRACKET"; |
||||||
|
private static final String DISPLAY_OPEN_BRACKET = "{"; |
||||||
|
private static final String CLOSE_BRACKET = "CLOSE_BRACKET"; |
||||||
|
private static final String DISPLAY_CLOSE_BRACKET = "}"; |
||||||
|
private static final String COMMA = "COMMA"; |
||||||
|
private static final String DISPLAY_COMMA = ","; |
||||||
|
private static final String PERIOD = "PERIOD"; |
||||||
|
private static final String DISPLAY_PERIOD = "."; |
||||||
|
private static final String SEMICOLON = "SEMICOLON"; |
||||||
|
private static final String DISPLAY_SEMICOLON = ";"; |
||||||
|
private static final String QUOTE = "QUOTE"; |
||||||
|
private static final String DISPLAY_QUOTE = "'"; |
||||||
|
private static final String EQUALS = "EQUALS"; |
||||||
|
private static final String DISPLAY_EQUALS = "+"; |
||||||
|
private static final String MINUS = "MINUS"; |
||||||
|
private static final String DISPLAY_MINUS = "-"; |
||||||
|
private static final String COMMAND = "META"; |
||||||
|
private static final String SMALL_COMMAND = "meta"; |
||||||
|
private static final String DISPLAY_COMMAND = "\u2318"; |
||||||
|
|
||||||
|
public static String getDisplayShortCut(String shortCut) { |
||||||
|
return shortCut.replace(TYPE, DISPLAY_TYPE).replace(BACK_SLASH, DISPLAY_BACK_SLASH).replace(SLASH, DISPLAY_SLASH) |
||||||
|
.replace(CONTROL, DISPLAY_CONTROL).replace(OPEN_BRACKET, DISPLAY_OPEN_BRACKET).replace(CLOSE_BRACKET, DISPLAY_CLOSE_BRACKET) |
||||||
|
.replace(COMMA, DISPLAY_COMMA).replace(PERIOD, DISPLAY_PERIOD).replace(SEMICOLON, DISPLAY_SEMICOLON).replace(QUOTE, DISPLAY_QUOTE) |
||||||
|
.replace(EQUALS, DISPLAY_EQUALS).replace(MINUS, DISPLAY_MINUS).replace(COMMAND, DISPLAY_COMMAND).replace(SMALL_COMMAND, DISPLAY_COMMAND); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.fr.design.actions.help.alphafine; |
||||||
|
|
||||||
|
import java.util.Stack; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/23 |
||||||
|
*/ |
||||||
|
public class SizedStack<T> extends Stack<T> { |
||||||
|
|
||||||
|
private final int maxSize; |
||||||
|
|
||||||
|
public SizedStack(int size) { |
||||||
|
super(); |
||||||
|
this.maxSize = size; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public T push(T object) { |
||||||
|
while (this.size() >= maxSize) { |
||||||
|
this.remove(0); |
||||||
|
} |
||||||
|
// 不重复
|
||||||
|
if (this.contains(object)) { |
||||||
|
return object; |
||||||
|
} |
||||||
|
return super.push(object); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.fr.design.data.datapane; |
||||||
|
|
||||||
|
import com.fr.data.util.function.AbstractDataFunction; |
||||||
|
import com.fr.data.util.function.AverageFunction; |
||||||
|
import com.fr.data.util.function.CountFunction; |
||||||
|
import com.fr.data.util.function.MaxFunction; |
||||||
|
import com.fr.data.util.function.MinFunction; |
||||||
|
import com.fr.data.util.function.NoneFunction; |
||||||
|
import com.fr.data.util.function.SumFunction; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.plugin.chart.base.FirstFunction; |
||||||
|
|
||||||
|
/** |
||||||
|
* 图表数据汇总方式下拉框 |
||||||
|
* |
||||||
|
* 支持首个,最后一个,求和,平均,最大值,最小值,个数 |
||||||
|
* |
||||||
|
*/ |
||||||
|
public class SummaryMethodComboBox extends UIComboBox { |
||||||
|
public static final String[] CALCULATE_ARRAY = {Toolkit.i18nText("Fine-Design_Chart_Data_Function_First"), Toolkit.i18nText("Fine-Design_Chart_Data_Function_Last"), |
||||||
|
Toolkit.i18nText("Fine-Design_Chart_Data_Function_Sum"), Toolkit.i18nText("Fine-Design_Chart_Data_Function_Average"), |
||||||
|
Toolkit.i18nText("Fine-Design_Chart_Data_Function_Max"), Toolkit.i18nText("Fine-Design_Chart_Data_Function_Min"), |
||||||
|
Toolkit.i18nText("Fine-Design_Chart_Data_Function_Count")}; |
||||||
|
public static final Class[] CLASS_ARRAY = {FirstFunction.class, NoneFunction.class, SumFunction.class, AverageFunction.class, |
||||||
|
MaxFunction.class, MinFunction.class, CountFunction.class}; |
||||||
|
|
||||||
|
public SummaryMethodComboBox() { |
||||||
|
super(CALCULATE_ARRAY); |
||||||
|
setSelectedIndex(2); |
||||||
|
} |
||||||
|
|
||||||
|
public void reset() { |
||||||
|
this.setSelectedItem(Toolkit.i18nText("Fine-Design_Chart_Data_Function_Sum")); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 更新公式选择. |
||||||
|
*/ |
||||||
|
public void populateBean(AbstractDataFunction function) { |
||||||
|
for (int i = 0; i < CLASS_ARRAY.length; i++) { |
||||||
|
if (function != null && ComparatorUtils.equals(function.getClass(), CLASS_ARRAY[i])) { |
||||||
|
setSelectedIndex(i); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回当前选择的公式 |
||||||
|
*/ |
||||||
|
public AbstractDataFunction updateBean() { |
||||||
|
try { |
||||||
|
int selectIndex = getSelectedIndex(); |
||||||
|
if (selectIndex >= 0 && selectIndex < CLASS_ARRAY.length) { |
||||||
|
return (AbstractDataFunction) CLASS_ARRAY[selectIndex].newInstance(); |
||||||
|
} |
||||||
|
} catch (InstantiationException e) { |
||||||
|
FineLoggerFactory.getLogger().error("Function Error"); |
||||||
|
return null; |
||||||
|
} catch (IllegalAccessException e) { |
||||||
|
FineLoggerFactory.getLogger().error("Function Error"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package com.fr.design.gui.frpane; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
public abstract class ClosableBubbleFloatPane<T> extends UIBubbleFloatPane<T> { |
||||||
|
public ClosableBubbleFloatPane(int arrowPosition, Point arrowPoint, BasicBeanPane<T> contentPane) { |
||||||
|
super(arrowPosition, arrowPoint, contentPane); |
||||||
|
} |
||||||
|
|
||||||
|
public ClosableBubbleFloatPane(int arrowPosition, Point arrowPoint, BasicBeanPane<T> contentPane, int width, int height) { |
||||||
|
super(arrowPosition, arrowPoint, contentPane, width, height); |
||||||
|
} |
||||||
|
|
||||||
|
protected void initAWTEventListener() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public boolean forceLockFocus() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
protected JPanel initTopOptionMenu() { |
||||||
|
JPanel menu = new JPanel(new BorderLayout()); |
||||||
|
Icon icon = BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png"); |
||||||
|
UILabel label = new UILabel(icon); |
||||||
|
label.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
showDialog.setVisible(false); |
||||||
|
updateContentPane(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
menu.add(label, BorderLayout.EAST); |
||||||
|
return menu; |
||||||
|
} |
||||||
|
} |
@ -1,77 +0,0 @@ |
|||||||
package com.fr.design.ui.util; |
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull; |
|
||||||
|
|
||||||
import java.awt.*; |
|
||||||
import java.util.Map; |
|
||||||
|
|
||||||
/** |
|
||||||
* 图形渲染配置 |
|
||||||
* |
|
||||||
* @author vito |
|
||||||
* @version 10.0 |
|
||||||
* Created by vito on 2019/9/18 |
|
||||||
*/ |
|
||||||
public class GraphicsConfig { |
|
||||||
private final Graphics2D myG; |
|
||||||
private final Map myHints; |
|
||||||
private final Composite myComposite; |
|
||||||
private final Stroke myStroke; |
|
||||||
|
|
||||||
public GraphicsConfig(@NotNull Graphics g) { |
|
||||||
myG = (Graphics2D) g; |
|
||||||
myHints = (Map) myG.getRenderingHints().clone(); |
|
||||||
myComposite = myG.getComposite(); |
|
||||||
myStroke = myG.getStroke(); |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig setAntialiasing(boolean on) { |
|
||||||
myG.setRenderingHint(RenderingHints.KEY_ANTIALIASING, on ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig setAlpha(float alpha) { |
|
||||||
myG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { |
|
||||||
myG.setRenderingHint(hintKey, hintValue); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public Graphics2D getG() { |
|
||||||
return myG; |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig setComposite(Composite composite) { |
|
||||||
myG.setComposite(composite); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig setStroke(Stroke stroke) { |
|
||||||
myG.setStroke(stroke); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig setupAAPainting() { |
|
||||||
return setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) |
|
||||||
.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig disableAAPainting() { |
|
||||||
return setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF) |
|
||||||
.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); |
|
||||||
} |
|
||||||
|
|
||||||
public GraphicsConfig paintWithAlpha(float alpha) { |
|
||||||
assert 0.0f <= alpha && alpha <= 1.0f : "alpha should be in range 0.0f .. 1.0f"; |
|
||||||
return setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); |
|
||||||
} |
|
||||||
|
|
||||||
public void restore() { |
|
||||||
myG.setRenderingHints(myHints); |
|
||||||
myG.setComposite(myComposite); |
|
||||||
myG.setStroke(myStroke); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,28 @@ |
|||||||
|
package com.fr.design.utils; |
||||||
|
|
||||||
|
import com.fr.base.svg.SVGLoader; |
||||||
|
import com.fr.base.svg.SystemScaleUtils; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
|
||||||
|
/** |
||||||
|
* 用于绘制svg图片缩放(高分屏下) |
||||||
|
* |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/5/6 |
||||||
|
*/ |
||||||
|
public class SvgPaintUtils { |
||||||
|
|
||||||
|
public static void beforePaint(Graphics2D g2) { |
||||||
|
if (SystemScaleUtils.isJreHiDPIEnabled()) { |
||||||
|
g2.scale(1 / SVGLoader.SYSTEM_SCALE, 1 / SVGLoader.SYSTEM_SCALE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void afterPaint(Graphics2D g2) { |
||||||
|
if (SystemScaleUtils.isJreHiDPIEnabled()) { |
||||||
|
g2.scale(SVGLoader.SYSTEM_SCALE, SVGLoader.SYSTEM_SCALE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
After Width: | Height: | Size: 356 B |
@ -0,0 +1,69 @@ |
|||||||
|
package com.fr.design.chart; |
||||||
|
|
||||||
|
import com.fr.base.TableData; |
||||||
|
import com.fr.base.chart.chartdata.TopDefinitionProvider; |
||||||
|
import com.fr.chart.chartattr.Chart; |
||||||
|
import com.fr.chart.chartattr.Plot; |
||||||
|
import com.fr.chart.chartdata.MoreNameCDDefinition; |
||||||
|
import com.fr.chart.chartdata.OneValueCDDefinition; |
||||||
|
import com.fr.data.TableDataSource; |
||||||
|
import com.fr.design.DesignModelAdapter; |
||||||
|
import com.fr.design.data.DesignTableDataManager; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.plugin.chart.custom.CustomDefinition; |
||||||
|
import com.fr.plugin.chart.custom.type.CustomPlotType; |
||||||
|
import com.fr.van.chart.designer.PlotFactory; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class ChartDataHelper { |
||||||
|
public static String[] getCommonChartFieldNames(Chart chart) { |
||||||
|
if (chart == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Plot plot = chart.getPlot(); |
||||||
|
if (plot == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
if (!PlotFactory.plotSupportAddTableField(plot)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
TopDefinitionProvider definition = chart.getFilterDefinition(); |
||||||
|
return getFieldNames(definition); |
||||||
|
} |
||||||
|
|
||||||
|
public static String[] getCustomChartTableFieldNames(Chart chart, CustomPlotType plotType) { |
||||||
|
if (chart == null || plotType == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
TopDefinitionProvider filterDefinition = chart.getFilterDefinition(); |
||||||
|
if (filterDefinition instanceof CustomDefinition) { |
||||||
|
CustomDefinition customDefinition = (CustomDefinition) filterDefinition; |
||||||
|
Map<CustomPlotType, TopDefinitionProvider> definitionProviderMap = customDefinition.getDefinitionProviderMap(); |
||||||
|
return getFieldNames(definitionProviderMap.get(plotType)); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private static String[] getFieldNames(TopDefinitionProvider definition) { |
||||||
|
if (definition == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
DesignModelAdapter adapter = DesignModelAdapter.getCurrentModelAdapter(); |
||||||
|
TableDataSource tableDataSource = adapter == null ? null : adapter.getBook(); |
||||||
|
TableData tableData = null; |
||||||
|
if (ComparatorUtils.equals(definition.getDataDefinitionType(), OneValueCDDefinition.DEFINITION_TYPE)) { |
||||||
|
OneValueCDDefinition oneValueCDDefinition = (OneValueCDDefinition) definition; |
||||||
|
tableData = oneValueCDDefinition.getTableData(); |
||||||
|
} else if (ComparatorUtils.equals(definition.getDataDefinitionType(), MoreNameCDDefinition.DEFINITION_TYPE)) { |
||||||
|
MoreNameCDDefinition moreNameCDDefinition = (MoreNameCDDefinition) definition; |
||||||
|
tableData = moreNameCDDefinition.getTableData(); |
||||||
|
} |
||||||
|
if (tableData == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return DesignTableDataManager.getSelectedColumnNames(tableDataSource, tableData.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
package com.fr.design.chart.series.SeriesCondition; |
||||||
|
|
||||||
|
import com.fr.chart.chartattr.Chart; |
||||||
|
import com.fr.data.DSColumnWithSummaryMethod; |
||||||
|
import com.fr.data.util.function.AbstractDataFunction; |
||||||
|
import com.fr.design.chart.ChartDataHelper; |
||||||
|
import com.fr.design.data.datapane.SummaryMethodComboBox; |
||||||
|
import com.fr.design.editor.editor.Editor; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.plugin.chart.custom.type.CustomPlotType; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.DefaultComboBoxModel; |
||||||
|
|
||||||
|
public class ColSelectedWithSummaryMethodEditor extends Editor<DSColumnWithSummaryMethod> { |
||||||
|
private UIComboBox columnNameComboBox = new UIComboBox(); |
||||||
|
private SummaryMethodComboBox summaryMethodComboBox; |
||||||
|
private static DefaultComboBoxModel<String> columnNameComboBoxModel = new DefaultComboBoxModel<>(); |
||||||
|
private static DefaultComboBoxModel<String> summaryMethodComboBoxModel = new DefaultComboBoxModel<>(SummaryMethodComboBox.CALCULATE_ARRAY); |
||||||
|
|
||||||
|
public ColSelectedWithSummaryMethodEditor() { |
||||||
|
this.setName(Toolkit.i18nText("Fine-Design_Chart_Summary_Field_Value")); |
||||||
|
this.setLayout(FRGUIPaneFactory.createLeftZeroLayout()); |
||||||
|
if (columnNameComboBox == null) { |
||||||
|
columnNameComboBox = new UIComboBox(); |
||||||
|
} |
||||||
|
columnNameComboBox.setPreferredSize(new Dimension(82, 20)); |
||||||
|
summaryMethodComboBox = new SummaryMethodComboBox(); |
||||||
|
summaryMethodComboBox.setModel(summaryMethodComboBoxModel); |
||||||
|
summaryMethodComboBox.setPreferredSize(new Dimension(82, 20)); |
||||||
|
this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout()); |
||||||
|
this.add(columnNameComboBox); |
||||||
|
this.add(summaryMethodComboBox); |
||||||
|
columnNameComboBox.setModel(columnNameComboBoxModel); |
||||||
|
columnNameComboBox.setSelectedItem(null); |
||||||
|
summaryMethodComboBox.setSelectedItem(null); |
||||||
|
} |
||||||
|
|
||||||
|
public static void refreshCommonChartFieldNames(Chart chart) { |
||||||
|
String[] columnNames = ChartDataHelper.getCommonChartFieldNames(chart); |
||||||
|
refreshComboBoxModel(columnNames); |
||||||
|
} |
||||||
|
|
||||||
|
public static void refreshCustomChartTableFieldNames(Chart chart, CustomPlotType plotType) { |
||||||
|
String[] columnNames = ChartDataHelper.getCustomChartTableFieldNames(chart, plotType); |
||||||
|
refreshComboBoxModel(columnNames); |
||||||
|
} |
||||||
|
|
||||||
|
private static void refreshComboBoxModel(String[] columnNames) { |
||||||
|
if (columnNames != null) { |
||||||
|
columnNameComboBoxModel.removeAllElements(); |
||||||
|
for (String columnName : columnNames) { |
||||||
|
columnNameComboBoxModel.addElement(columnName); |
||||||
|
} |
||||||
|
for (String method : SummaryMethodComboBox.CALCULATE_ARRAY) { |
||||||
|
summaryMethodComboBoxModel.addElement(method); |
||||||
|
} |
||||||
|
columnNameComboBoxModel.setSelectedItem(null); |
||||||
|
summaryMethodComboBoxModel.setSelectedItem(null); |
||||||
|
} else { |
||||||
|
columnNameComboBoxModel.removeAllElements(); |
||||||
|
summaryMethodComboBoxModel.removeAllElements(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public String getIconName() { |
||||||
|
return "ds_column_summary"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DSColumnWithSummaryMethod getValue() { |
||||||
|
if (columnNameComboBox.getSelectedItem() == null || summaryMethodComboBox.getSelectedItem() == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
DSColumnWithSummaryMethod dsColumnWithSummaryMethod = new DSColumnWithSummaryMethod(); |
||||||
|
dsColumnWithSummaryMethod.setFieldName(columnNameComboBox.getSelectedItem().toString()); |
||||||
|
dsColumnWithSummaryMethod.setDataFunction(summaryMethodComboBox.updateBean()); |
||||||
|
return dsColumnWithSummaryMethod; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setValue(DSColumnWithSummaryMethod value) { |
||||||
|
if (value != null) { |
||||||
|
columnNameComboBox.setSelectedItem(value.getFieldName()); |
||||||
|
summaryMethodComboBox.populateBean((AbstractDataFunction)value.getDataFunction()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean accept(Object object) { |
||||||
|
return object instanceof DSColumnWithSummaryMethod; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.fr.design.actions; |
||||||
|
|
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.JForm; |
||||||
|
import com.fr.design.menu.MenuKeySet; |
||||||
|
import com.fr.design.widget.ui.designer.FormECParallelCalSettingPane; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.main.parallel.FormECParallelCalAttr; |
||||||
|
|
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fly.li |
||||||
|
* @version 10.0 |
||||||
|
* Created on 2022/03/18 |
||||||
|
*/ |
||||||
|
public class FormECParallelCalAction extends JTemplateAction<JForm> { |
||||||
|
|
||||||
|
private static final MenuKeySet FORM_PARALLEL_SETTING = new MenuKeySet() { |
||||||
|
@Override |
||||||
|
public char getMnemonic() { |
||||||
|
return 'P'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMenuName() { |
||||||
|
return Toolkit.i18nText("Fine-Design_Form_Calculate_Setting"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyStroke getKeyStroke() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
private void initMenuStyle() { |
||||||
|
this.setMenuKeySet(FORM_PARALLEL_SETTING); |
||||||
|
this.setName(getMenuKeySet().getMenuKeySetName() + "..."); |
||||||
|
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||||
|
this.setSmallIcon("com/fr/design/form/images/parallel.png"); |
||||||
|
} |
||||||
|
|
||||||
|
public FormECParallelCalAction(JForm jForm) { |
||||||
|
super(jForm); |
||||||
|
initMenuStyle(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
final JForm jf = getEditingComponent(); |
||||||
|
if (jf == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
showParallelSettingDialog(jf); |
||||||
|
} |
||||||
|
|
||||||
|
private void showParallelSettingDialog(JForm jf) { |
||||||
|
FormECParallelCalSettingPane attrPane = new FormECParallelCalSettingPane(); |
||||||
|
Form form = jf.getTarget(); |
||||||
|
FormECParallelCalAttr parallelAttr = form.getParallelAttr(); |
||||||
|
attrPane.populateBean(parallelAttr); |
||||||
|
UIDialog dialog = attrPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
fireEditingOk(jf, form, attrPane.updateBean()); |
||||||
|
} |
||||||
|
}, new Dimension(600, 600)); |
||||||
|
dialog.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void fireEditingOk(JForm jForm, Form form, FormECParallelCalAttr parallelAttr){ |
||||||
|
form.setParallelAttr(parallelAttr); |
||||||
|
jForm.fireTargetModified(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,131 @@ |
|||||||
|
package com.fr.design.widget.ui.designer; |
||||||
|
|
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.gui.icheckbox.UICheckBox; |
||||||
|
import com.fr.design.gui.icombobox.UIComboBox; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
|
import com.fr.form.main.parallel.FormECParallelCalAttr; |
||||||
|
import com.fr.report.core.config.FormParallelCalConfig; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.FlowLayout; |
||||||
|
import java.awt.event.ItemEvent; |
||||||
|
import java.awt.event.ItemListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fly.li |
||||||
|
* @version 10.0 |
||||||
|
* Created on 2022/03/18 |
||||||
|
*/ |
||||||
|
public class FormECParallelCalSettingPane extends BasicBeanPane<FormECParallelCalAttr> { |
||||||
|
private static final String[] CHOOSE_ITEM = new String[] { |
||||||
|
Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single"), |
||||||
|
Toolkit.i18nText("Fine-Design_Form_Using_Server_Report_View_Settings") |
||||||
|
}; |
||||||
|
protected static final int SINGLE_SET = 0; |
||||||
|
protected static final int SERVER_SET = 1; |
||||||
|
//并行设置范围的下拉框(服务器设置还是模板设置)
|
||||||
|
UIComboBox parallelSettingScope; |
||||||
|
//并行计算开关
|
||||||
|
UICheckBox parallelSwitch; |
||||||
|
|
||||||
|
public FormECParallelCalSettingPane(){ |
||||||
|
initPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initPane(){ |
||||||
|
JPanel calSettingOutPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Form_Block_Calculate_Setting")); |
||||||
|
calSettingOutPane.setPreferredSize(new Dimension(550,110)); |
||||||
|
calSettingOutPane.add(getCalSettingPane()); |
||||||
|
this.add(calSettingOutPane); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel getCalSettingPane() { |
||||||
|
JPanel calSettingPane = new JPanel(); |
||||||
|
calSettingPane.setLayout(new BorderLayout()); |
||||||
|
UILabel belowSetLabel = new UILabel(Toolkit.i18nText("Fine-Design_Setting_Mode")); |
||||||
|
belowSetLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 20)); |
||||||
|
JPanel parallelSettingScopePane = GUICoreUtils.createFlowPane(new Component[] { |
||||||
|
belowSetLabel, getParallelSettingScope()}, FlowLayout.LEFT, 0, 0); |
||||||
|
calSettingPane.add(parallelSettingScopePane, BorderLayout.NORTH); |
||||||
|
calSettingPane.add(getSwitchPane(Toolkit.i18nText("Fine-Design_Enable_Form_Block_Parallel_Calculate")), BorderLayout.CENTER); |
||||||
|
return calSettingPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return Toolkit.i18nText("Fine-Design_Form_Calculate_Setting"); |
||||||
|
} |
||||||
|
|
||||||
|
private UIComboBox getParallelSettingScope() { |
||||||
|
if (this.parallelSettingScope == null){ |
||||||
|
parallelSettingScope = new UIComboBox(CHOOSE_ITEM); |
||||||
|
parallelSettingScope.addItemListener(new ItemListener() { |
||||||
|
@Override |
||||||
|
public void itemStateChanged(ItemEvent e) { |
||||||
|
if (e.getStateChange() == ItemEvent.SELECTED) { |
||||||
|
if (isUsingServerSettings()) { |
||||||
|
populateServerSettings(); |
||||||
|
parallelSwitch.setEnabled(false); |
||||||
|
} else { |
||||||
|
parallelSwitch.setEnabled(true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
return this.parallelSettingScope; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel getSwitchPane(String tip){ |
||||||
|
JPanel innerPane = new JPanel(); |
||||||
|
innerPane.setLayout(new BorderLayout()); |
||||||
|
innerPane.setPreferredSize(new Dimension(500, 30)); |
||||||
|
innerPane.setBorder(BorderFactory.createEmptyBorder(10, 70, 5, 10)); |
||||||
|
innerPane.add(getParallelSwitch(tip)); |
||||||
|
return innerPane; |
||||||
|
} |
||||||
|
|
||||||
|
private UICheckBox getParallelSwitch(String tip){ |
||||||
|
if (parallelSwitch == null){ |
||||||
|
parallelSwitch = new UICheckBox(tip); |
||||||
|
} |
||||||
|
return parallelSwitch; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isUsingServerSettings(){ |
||||||
|
return parallelSettingScope.getSelectedIndex() == SERVER_SET; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(FormECParallelCalAttr formParallelAttr){ |
||||||
|
if (formParallelAttr == null){ |
||||||
|
formParallelAttr = FormECParallelCalAttr.getDefaultParallelAttr(); |
||||||
|
} |
||||||
|
parallelSettingScope.setSelectedIndex(formParallelAttr.isUseServerSetting() ? SERVER_SET : SINGLE_SET); |
||||||
|
if (formParallelAttr.isUseServerSetting()){ |
||||||
|
populateServerSettings(); |
||||||
|
} else { |
||||||
|
populateSingleTemplateSetting(formParallelAttr); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void populateServerSettings(){ |
||||||
|
parallelSwitch.setSelected(FormParallelCalConfig.getInstance().isParallelCal()); |
||||||
|
} |
||||||
|
|
||||||
|
private void populateSingleTemplateSetting(FormECParallelCalAttr parallelAttr){ |
||||||
|
parallelSwitch.setSelected(parallelAttr.isParallelCal()); |
||||||
|
} |
||||||
|
|
||||||
|
public FormECParallelCalAttr updateBean(){ |
||||||
|
return new FormECParallelCalAttr(isUsingServerSettings(), parallelSwitch.isSelected()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.date; |
||||||
|
|
||||||
|
/** |
||||||
|
* 日期控件格式检测接口 |
||||||
|
* |
||||||
|
* @author Lucian.Chen |
||||||
|
* @version 11.0 |
||||||
|
* Created by Lucian.Chen on 2022/4/8 |
||||||
|
*/ |
||||||
|
public interface DateFormatCheck { |
||||||
|
|
||||||
|
/** |
||||||
|
* 校验日期格式 |
||||||
|
* @param date 日期 |
||||||
|
* @param format 格式 |
||||||
|
* @return 是否通过 |
||||||
|
*/ |
||||||
|
boolean accept(String date, String format); |
||||||
|
|
||||||
|
/** |
||||||
|
* 校验结果 |
||||||
|
* @param sample 提示 |
||||||
|
* @return 校验结果 |
||||||
|
*/ |
||||||
|
DateFormatCheckResult result(String sample); |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.date; |
||||||
|
|
||||||
|
import com.fr.design.widget.ui.designer.date.check.DateFormatCustomCheck; |
||||||
|
import com.fr.design.widget.ui.designer.date.check.DateFormatFrontCheck; |
||||||
|
import org.jetbrains.annotations.NotNull; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Lucian.Chen |
||||||
|
* @version 11.0 |
||||||
|
* Created by Lucian.Chen on 2022/4/8 |
||||||
|
*/ |
||||||
|
public class DateFormatCheckManager { |
||||||
|
|
||||||
|
private static final List<DateFormatCheck> CHECKS = new ArrayList<>(); |
||||||
|
|
||||||
|
static { |
||||||
|
// 顺序执行
|
||||||
|
CHECKS.add(DateFormatFrontCheck.KEY); |
||||||
|
CHECKS.add(DateFormatCustomCheck.KEY); |
||||||
|
} |
||||||
|
|
||||||
|
@NotNull |
||||||
|
public static DateFormatCheckResult check(String date, String format) { |
||||||
|
for (DateFormatCheck check : CHECKS) { |
||||||
|
if (!check.accept(date, format)) { |
||||||
|
return check.result(date); |
||||||
|
} |
||||||
|
} |
||||||
|
return DateFormatCheckResult.create(date); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.date; |
||||||
|
|
||||||
|
import java.awt.Color; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Lucian.Chen |
||||||
|
* @version 11.0 |
||||||
|
* Created by Lucian.Chen on 2022/4/8 |
||||||
|
*/ |
||||||
|
public class DateFormatCheckResult { |
||||||
|
|
||||||
|
private String sample; |
||||||
|
private Color color; |
||||||
|
|
||||||
|
public static DateFormatCheckResult create(String sample) { |
||||||
|
return create(sample, Color.BLACK); |
||||||
|
} |
||||||
|
|
||||||
|
public static DateFormatCheckResult create(String sample, Color color) { |
||||||
|
return new DateFormatCheckResult(sample, color); |
||||||
|
} |
||||||
|
|
||||||
|
DateFormatCheckResult(String sample, Color color) { |
||||||
|
this.sample = sample; |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSample() { |
||||||
|
return sample; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSample(String sample) { |
||||||
|
this.sample = sample; |
||||||
|
} |
||||||
|
|
||||||
|
public Color getColor() { |
||||||
|
return color; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColor(Color color) { |
||||||
|
this.color = color; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.date.check; |
||||||
|
|
||||||
|
import com.fr.data.core.FormatField; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.widget.ui.designer.date.DateFormatCheck; |
||||||
|
import com.fr.design.widget.ui.designer.date.DateFormatCheckResult; |
||||||
|
import com.fr.stable.ArrayUtils; |
||||||
|
|
||||||
|
import java.awt.Color; |
||||||
|
|
||||||
|
/** |
||||||
|
* 自定义格式校验 |
||||||
|
* @author Lucian.Chen |
||||||
|
* @version 11.0 |
||||||
|
* Created by Lucian.Chen on 2022/4/8 |
||||||
|
*/ |
||||||
|
public class DateFormatCustomCheck implements DateFormatCheck { |
||||||
|
|
||||||
|
public static final DateFormatCustomCheck KEY = new DateFormatCustomCheck(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 不是自定义格式 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean accept(String date, String format) { |
||||||
|
return ArrayUtils.contains(FormatField.getInstance().getDateFormatArray(), format); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DateFormatCheckResult result(String sample) { |
||||||
|
sample += " " + Toolkit.i18nText("Fine-Design_Basic_DateFormat_Custom_Warning"); |
||||||
|
return DateFormatCheckResult.create(sample, Color.red); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.date.check; |
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.widget.ui.designer.date.DateFormatCheck; |
||||||
|
import com.fr.design.widget.ui.designer.date.DateFormatCheckResult; |
||||||
|
import com.fr.stable.AssistUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.awt.Color; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* 前端的解析方案检测 |
||||||
|
* FR.str2Date |
||||||
|
* @author Lucian.Chen |
||||||
|
* @version 11.0 |
||||||
|
* Created by Lucian.Chen on 2022/4/7 |
||||||
|
*/ |
||||||
|
public class DateFormatFrontCheck implements DateFormatCheck { |
||||||
|
|
||||||
|
private static final Pattern YEAR_PATTERN_1 = Pattern.compile("y{4,}"); //yyyy
|
||||||
|
private static final Pattern YEAR_PATTERN_2 = Pattern.compile("y{2,}"); //yy
|
||||||
|
private static final Pattern MONTH_PATTERN_1 = Pattern.compile("M{4,}"); //MMMM
|
||||||
|
private static final Pattern MONTH_PATTERN_2 = Pattern.compile("M{3}"); //MMM
|
||||||
|
private static final Pattern MONTH_PATTERN_3 = Pattern.compile("M{2}"); //MM
|
||||||
|
private static final Pattern MONTH_PATTERN_4 = Pattern.compile("M"); //M
|
||||||
|
private static final Pattern MONTH_PATTERN_5 = Pattern.compile("a"); |
||||||
|
private static final Pattern DAY_PATTERN_1 = Pattern.compile("d{2,}"); //dd
|
||||||
|
private static final Pattern DAY_PATTERN_2 = Pattern.compile("d"); //d
|
||||||
|
private static final Pattern HOUR_PATTERN_1 = Pattern.compile("h+"); //hh、h
|
||||||
|
private static final Pattern HOUR_PATTERN_2 = Pattern.compile("H+"); //HH、H
|
||||||
|
private static final Pattern MINUTE_PATTERN = Pattern.compile("m{2,}"); //mm
|
||||||
|
private static final Pattern SECOND_PATTERN = Pattern.compile("s{2,}"); //ss
|
||||||
|
private static final Pattern FMT_PATTERN = Pattern.compile("%."); |
||||||
|
|
||||||
|
public static final DateFormatFrontCheck KEY = new DateFormatFrontCheck(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 前端支持的格式 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean accept(String date, String format) { |
||||||
|
if (StringUtils.isBlank(date) || StringUtils.isBlank(format)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
String fmt = parseFmt(format); |
||||||
|
int fmtCount = 0; |
||||||
|
Matcher matcher = FMT_PATTERN.matcher(fmt); |
||||||
|
while (matcher.find()) { |
||||||
|
fmtCount ++; |
||||||
|
} |
||||||
|
String[] dates = date.split("\\W+"); |
||||||
|
|
||||||
|
return dates.length == fmtCount || isSpecialFmt(fmt); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DateFormatCheckResult result(String sample) { |
||||||
|
return DateFormatCheckResult.create(Toolkit.i18nText("Fine-Design_Basic_DateFormat_Not_Support"), Color.red); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isSpecialFmt(String fmt) { |
||||||
|
return AssistUtils.equals(fmt, "%Y%X") || AssistUtils.equals(fmt, "%Y%X%d"); |
||||||
|
} |
||||||
|
|
||||||
|
private String parseFmt(String fmt) { |
||||||
|
//年
|
||||||
|
fmt = YEAR_PATTERN_1.matcher(fmt).replaceAll("%Y"); |
||||||
|
fmt = YEAR_PATTERN_2.matcher(fmt).replaceAll("%y"); |
||||||
|
//月
|
||||||
|
fmt = MONTH_PATTERN_1.matcher(fmt).replaceAll("%b"); |
||||||
|
fmt = MONTH_PATTERN_2.matcher(fmt).replaceAll("%B"); |
||||||
|
fmt = MONTH_PATTERN_3.matcher(fmt).replaceAll("%X"); |
||||||
|
fmt = MONTH_PATTERN_4.matcher(fmt).replaceAll("%x"); |
||||||
|
fmt = MONTH_PATTERN_5.matcher(fmt).replaceAll("%p"); |
||||||
|
//天
|
||||||
|
Matcher dayMatcher = DAY_PATTERN_1.matcher(fmt); |
||||||
|
if (dayMatcher.find()) { |
||||||
|
fmt = dayMatcher.replaceAll("%d"); |
||||||
|
} else { |
||||||
|
fmt = DAY_PATTERN_2.matcher(fmt).replaceAll("%e"); |
||||||
|
} |
||||||
|
//时
|
||||||
|
fmt = HOUR_PATTERN_1.matcher(fmt).replaceAll("%I"); |
||||||
|
fmt = HOUR_PATTERN_2.matcher(fmt).replaceAll("%H"); |
||||||
|
//分
|
||||||
|
fmt = MINUTE_PATTERN.matcher(fmt).replaceAll("%M"); |
||||||
|
//秒
|
||||||
|
fmt = SECOND_PATTERN.matcher(fmt).replaceAll("%S"); |
||||||
|
return fmt; |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 158 B |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.design.widget.ui.designer.date.check; |
||||||
|
|
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Lucian.Chen |
||||||
|
* @version 10.0 |
||||||
|
* Created by Lucian.Chen on 2022/4/18 |
||||||
|
*/ |
||||||
|
public class DateFormatFrontCheckTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testAccept() { |
||||||
|
Assert.assertTrue(DateFormatFrontCheck.KEY.accept("20220101", "yyyyMMdd")); |
||||||
|
Assert.assertTrue(DateFormatFrontCheck.KEY.accept("202201", "yyyyMM")); |
||||||
|
Assert.assertTrue(DateFormatFrontCheck.KEY.accept("2022-01-01", "yyyy-MM-dd")); |
||||||
|
Assert.assertTrue(DateFormatFrontCheck.KEY.accept("22/01/01", "yy/MM/dd")); |
||||||
|
Assert.assertTrue(DateFormatFrontCheck.KEY.accept("2022年01月01日", "yyyy年MM月dd日")); |
||||||
|
Assert.assertTrue(DateFormatFrontCheck.KEY.accept("2022/01/01 12:30:00", "yyyy/MM/dd HH:mm:ss")); |
||||||
|
|
||||||
|
Assert.assertFalse(DateFormatFrontCheck.KEY.accept("220101", "yyMMdd")); |
||||||
|
Assert.assertFalse(DateFormatFrontCheck.KEY.accept("20221", "yyyyM")); |
||||||
|
Assert.assertFalse(DateFormatFrontCheck.KEY.accept("20220101123000", "yyyyMMddHHmmss")); |
||||||
|
Assert.assertFalse(DateFormatFrontCheck.KEY.accept("2022-01-01", "YYYY-MM-dd")); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine; |
||||||
|
|
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/20 |
||||||
|
*/ |
||||||
|
public class AlphaFineUtil { |
||||||
|
|
||||||
|
public static String highLightModelName(String modelName, String[] strings) { |
||||||
|
if (strings == null) { |
||||||
|
return modelName; |
||||||
|
} |
||||||
|
for (String string : strings) { |
||||||
|
String primaryStr = getReplacedString(modelName, string); |
||||||
|
if (StringUtils.isNotEmpty(primaryStr)) { |
||||||
|
modelName = modelName.replaceAll("(?i)" + primaryStr, "|<font color=" + AlphaFineConstants.HIGH_LIGHT_COLOR + ">" + primaryStr + "</font>|"); |
||||||
|
} |
||||||
|
} |
||||||
|
modelName = "<html><head><style> .style{" + |
||||||
|
"overflow: hidden;" + |
||||||
|
"text-overflow: ellipsis;" + |
||||||
|
"white-space: nowrap;}" + |
||||||
|
"</style></head><body class=\"style\">" + modelName.replaceAll("\\|", StringUtils.EMPTY) + "</body></HTML>"; |
||||||
|
return modelName; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static String getReplacedString(String modelName, String string) { |
||||||
|
// 如果是直接包含了高亮字符 返回
|
||||||
|
if (StringUtils.contains(modelName, string)) { |
||||||
|
return string; |
||||||
|
} |
||||||
|
//需要考虑modelName有空格的情况
|
||||||
|
//比如现在是work boo k 搜索词是workb,应该要替换的部分是work b
|
||||||
|
//先去掉已经匹配替换过的部分,因为考虑到分词的情况,可能会进行多次替换
|
||||||
|
final String regex = "\\|<font.*?</font>\\|"; |
||||||
|
modelName = modelName.replaceAll(regex, StringUtils.EMPTY); |
||||||
|
//再去掉空格进行匹配
|
||||||
|
String noBlackName = modelName.replaceAll(StringUtils.BLANK, StringUtils.EMPTY).toLowerCase(); |
||||||
|
int index = noBlackName.indexOf(string.toLowerCase()); |
||||||
|
if (index == -1) { |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
StringBuilder result = new StringBuilder(); |
||||||
|
int count = 0; |
||||||
|
while (count < string.length()) { |
||||||
|
char pos = modelName.charAt(index++); |
||||||
|
result.append(pos); |
||||||
|
count += pos == ' ' ? 0 : 1; |
||||||
|
} |
||||||
|
return result.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
public static String escapeExprSpecialWord(String keyword) { |
||||||
|
if (StringUtils.isNotBlank(keyword)) { |
||||||
|
String[] fbsArr = { "\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|" }; |
||||||
|
for (String key : fbsArr) { |
||||||
|
if (keyword.contains(key)) { |
||||||
|
keyword = keyword.replace(key, "\\" + key); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return keyword; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean unread() { |
||||||
|
Set<Long> readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); |
||||||
|
Set<Long> idSet = ProductNewsSearchManager.getInstance().getIdSet(); |
||||||
|
return !idSet.isEmpty() && !readSet.containsAll(idSet); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,865 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.base.svg.SVGLoader; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager; |
||||||
|
import com.fr.design.actions.help.alphafine.AlphaFineShortCutUtil; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.borders.UITextFieldBorder; |
||||||
|
import com.fr.design.gui.ibutton.UIButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.CellType; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import com.fr.design.mainframe.alphafine.model.ProductNews; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.DefaultProductNewsPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.HelpDocumentNoResultPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.LoadingRightSearchResultPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.NetWorkFailedPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.NoResultPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.NoResultWithLinkPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.SearchLoadingPane; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.SimpleRightSearchResultPane; |
||||||
|
import com.fr.design.mainframe.alphafine.question.QuestionWindow; |
||||||
|
import com.fr.design.mainframe.alphafine.search.ProductNewsSearchWorkerManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.SearchTextBean; |
||||||
|
import com.fr.design.mainframe.alphafine.search.SearchWorkerManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.ActionSearchManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.DocumentSearchManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.FileSearchManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.PluginSearchManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager; |
||||||
|
import com.fr.design.utils.DesignUtils; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.CardLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.FlowLayout; |
||||||
|
import java.awt.Font; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.Insets; |
||||||
|
import java.awt.RenderingHints; |
||||||
|
import java.awt.Toolkit; |
||||||
|
import java.awt.Window; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.FocusEvent; |
||||||
|
import java.awt.event.FocusListener; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JButton; |
||||||
|
import javax.swing.JFrame; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import javax.swing.Timer; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/04/06 |
||||||
|
*/ |
||||||
|
public class AlphaFineFrame extends JFrame { |
||||||
|
|
||||||
|
private static final String ADVANCED_SEARCH_MARK = "k:"; |
||||||
|
private static final String ACTION_MARK_SHORT = "k:1 "; |
||||||
|
private static final String ACTION_MARK = "k:setting "; |
||||||
|
private static final String DOCUMENT_MARK_SHORT = "k:2 "; |
||||||
|
private static final String DOCUMENT_MARK = "k:help "; |
||||||
|
private static final String FILE_MARK_SHORT = "k:3 "; |
||||||
|
private static final String FILE_MARK = "k:reportlets "; |
||||||
|
private static final String CPT_MARK = "k:cpt "; |
||||||
|
private static final String FRM_MARK = "k:frm "; |
||||||
|
private static final String DS_MARK = "k:ds "; |
||||||
|
private static final String DS_NAME = "dsname=\""; |
||||||
|
private static final String PLUGIN_MARK_SHORT = "k:4 "; |
||||||
|
private static final String PLUGIN_MARK = "k:shop "; |
||||||
|
|
||||||
|
private static final int TIMER_DELAY = 300; |
||||||
|
|
||||||
|
private static final String PLACE_HOLDER = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine"); |
||||||
|
|
||||||
|
private static final String SETTING = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set"); |
||||||
|
|
||||||
|
private static final String NO_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"); |
||||||
|
|
||||||
|
private static final String SKILLS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Skills"); |
||||||
|
|
||||||
|
private static final String SEARCH_TERM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Search_Term"); |
||||||
|
|
||||||
|
private static final String SEARCH = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Search"); |
||||||
|
|
||||||
|
private static final String GO_FORUM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Go_Forum"); |
||||||
|
|
||||||
|
private static final String TEMPLATES = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Templates"); |
||||||
|
|
||||||
|
public static final String PRODUCT_NEWS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_News"); |
||||||
|
|
||||||
|
private static final String HELP = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help"); |
||||||
|
|
||||||
|
private static final String PLUGIN = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon"); |
||||||
|
|
||||||
|
private static final String ONE_CLICK_READ = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_One_Click_Read"); |
||||||
|
|
||||||
|
private static final String NO_SEARCH_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"); |
||||||
|
|
||||||
|
private static final String PRODUCT_DYNAMICS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics"); |
||||||
|
|
||||||
|
private static final Image SEARCH_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/search.svg"); |
||||||
|
|
||||||
|
private static final Color BORDER_COLOR = new Color(232, 232, 233); |
||||||
|
|
||||||
|
private final CardLayout cardLayout = new CardLayout(); |
||||||
|
|
||||||
|
private final JPanel resultPane = new JPanel(cardLayout); |
||||||
|
|
||||||
|
private String storeText; |
||||||
|
|
||||||
|
private String[] segmentationResult; |
||||||
|
|
||||||
|
private UILabel useTipLabel; |
||||||
|
|
||||||
|
private UILabel tipIconLabel; |
||||||
|
|
||||||
|
private AlphaFineTextField searchTextField; |
||||||
|
|
||||||
|
private AlphaFineList searchResultList; |
||||||
|
|
||||||
|
private SearchLoadingPane searchLoadingPane; |
||||||
|
|
||||||
|
private JPanel searchTextFieldWrapperPane; |
||||||
|
|
||||||
|
private UILabel clearLabel; |
||||||
|
|
||||||
|
private JPanel tabPane; |
||||||
|
|
||||||
|
private CellType selectedType; |
||||||
|
|
||||||
|
private String beforeSearchStr = StringUtils.EMPTY; |
||||||
|
|
||||||
|
private SearchWorkerManager settingSearchWorkerManager; |
||||||
|
|
||||||
|
private SearchWorkerManager fileSearchWorkerManager; |
||||||
|
|
||||||
|
private SearchWorkerManager documentWorkerManager; |
||||||
|
|
||||||
|
private SearchWorkerManager pluginSearchWorkerManager; |
||||||
|
|
||||||
|
private SearchWorkerManager currentSearchWorkerManager; |
||||||
|
|
||||||
|
private ProductNewsSearchWorkerManager productNewsSearchWorkerManager; |
||||||
|
|
||||||
|
public AlphaFineFrame() { |
||||||
|
this.setTitle(AlphaFineConstants.TITLE); |
||||||
|
setUndecorated(true); |
||||||
|
setSize(AlphaFineConstants.FIELD_SIZE); |
||||||
|
initComponents(); |
||||||
|
centerWindow(this); |
||||||
|
initSearchManager(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initSearchManager() { |
||||||
|
|
||||||
|
this.productNewsSearchWorkerManager = new ProductNewsSearchWorkerManager( |
||||||
|
CellType.PRODUCT_NEWS, |
||||||
|
searchTextBean -> { |
||||||
|
return ProductNewsSearchManager.getInstance().getSearchResult(searchTextBean.getSegmentation()); |
||||||
|
}, |
||||||
|
this |
||||||
|
); |
||||||
|
|
||||||
|
this.settingSearchWorkerManager = new SearchWorkerManager( |
||||||
|
CellType.ACTION, |
||||||
|
searchTextBean -> ActionSearchManager.getInstance().getSearchResult(searchTextBean), |
||||||
|
this, |
||||||
|
new SimpleRightSearchResultPane(new NoResultPane(NO_RESULT, AlphaFineConstants.NO_RESULT_ICON)) |
||||||
|
); |
||||||
|
fileSearchWorkerManager = new SearchWorkerManager( |
||||||
|
CellType.FILE, |
||||||
|
searchTextBean -> FileSearchManager.getInstance().getSearchResult(searchTextBean), |
||||||
|
this, |
||||||
|
new LoadingRightSearchResultPane() |
||||||
|
); |
||||||
|
documentWorkerManager = new SearchWorkerManager( |
||||||
|
CellType.DOCUMENT, |
||||||
|
searchTextBean -> DocumentSearchManager.getInstance().getSearchResult(searchTextBean), |
||||||
|
this, |
||||||
|
new SimpleRightSearchResultPane(new JPanel()) |
||||||
|
); |
||||||
|
|
||||||
|
pluginSearchWorkerManager = new SearchWorkerManager( |
||||||
|
CellType.PLUGIN, |
||||||
|
searchTextBean -> PluginSearchManager.getInstance().getSearchResult(searchTextBean), |
||||||
|
this, |
||||||
|
new LoadingRightSearchResultPane() |
||||||
|
); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化全部组件 |
||||||
|
*/ |
||||||
|
private void initComponents() { |
||||||
|
|
||||||
|
add(createTopPane(), BorderLayout.NORTH); |
||||||
|
initSearchTextField(); |
||||||
|
add(createSearchPane(), BorderLayout.CENTER); |
||||||
|
add(createShowPane(), BorderLayout.SOUTH); |
||||||
|
this.getContentPane().setBackground(Color.WHITE); |
||||||
|
this.setIconImage(SEARCH_IMAGE); |
||||||
|
this.setSize(AlphaFineConstants.FULL_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createTopPane() { |
||||||
|
JPanel topPane = new JPanel(new BorderLayout()); |
||||||
|
topPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); |
||||||
|
topPane.setBackground(Color.WHITE); |
||||||
|
JPanel topLeftPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
||||||
|
topLeftPane.setBackground(Color.WHITE); |
||||||
|
UILabel alphaFineLabel = new UILabel(AlphaFineConstants.TITLE); |
||||||
|
alphaFineLabel.setFont(new Font("Arial Black", Font.PLAIN, 20)); |
||||||
|
alphaFineLabel.setForeground(UIConstants.FLESH_BLUE); |
||||||
|
topLeftPane.add(alphaFineLabel); |
||||||
|
topPane.add(topLeftPane, BorderLayout.WEST); |
||||||
|
|
||||||
|
JPanel topRightPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10)); |
||||||
|
topRightPane.setBackground(Color.WHITE); |
||||||
|
JPanel tipPane = new JPanel(new BorderLayout()); |
||||||
|
tipPane.setBackground(Color.WHITE); |
||||||
|
String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts())); |
||||||
|
tipIconLabel = new UILabel(AlphaFineConstants.BULB_ICON); |
||||||
|
tipIconLabel.addMouseListener(tipMouseListener); |
||||||
|
tipIconLabel.setToolTipText(toolTip); |
||||||
|
useTipLabel = new UILabel(SKILLS); |
||||||
|
useTipLabel.addMouseListener(tipMouseListener); |
||||||
|
useTipLabel.setToolTipText(toolTip); |
||||||
|
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); |
||||||
|
tipPane.add(tipIconLabel, BorderLayout.WEST); |
||||||
|
tipPane.add(useTipLabel, BorderLayout.CENTER); |
||||||
|
topRightPane.add(tipPane); |
||||||
|
UIButton minimizeButton = createButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/minimize.svg")); |
||||||
|
minimizeButton.addActionListener(e -> AlphaFineFrame.this.setExtendedState(JFrame.ICONIFIED)); |
||||||
|
topRightPane.add(minimizeButton); |
||||||
|
UIButton closeButton = createButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/close.svg")); |
||||||
|
closeButton.addActionListener(e -> AlphaFineFrame.this.dispose()); |
||||||
|
topRightPane.add(closeButton); |
||||||
|
topPane.add(topRightPane, BorderLayout.EAST); |
||||||
|
return topPane; |
||||||
|
} |
||||||
|
|
||||||
|
private MouseAdapter tipMouseListener = new MouseAdapter() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
useTipLabel.setForeground(UIConstants.FLESH_BLUE); |
||||||
|
tipIconLabel.setIcon(AlphaFineConstants.BLUE_BULB_ICON); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); |
||||||
|
tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private JPanel createSearchPane() { |
||||||
|
JPanel searchPane = new JPanel(new BorderLayout()); |
||||||
|
searchPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); |
||||||
|
searchTextFieldWrapperPane = new JPanel(new BorderLayout()) { |
||||||
|
@Override |
||||||
|
protected void paintBorder(Graphics g) { |
||||||
|
g.setColor(BORDER_COLOR); |
||||||
|
g.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 5, 5); |
||||||
|
} |
||||||
|
}; |
||||||
|
searchTextFieldWrapperPane.setBorder(new UITextFieldBorder(new Insets(2, 3, 2, 3))); |
||||||
|
searchTextFieldWrapperPane.setBackground(Color.WHITE); |
||||||
|
searchTextFieldWrapperPane.add(searchTextField, BorderLayout.CENTER); |
||||||
|
clearLabel = new UILabel(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/clear.svg")); |
||||||
|
clearLabel.setVisible(false); |
||||||
|
clearLabel.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
searchTextField.setText(StringUtils.EMPTY); |
||||||
|
beforeSearchStr = StringUtils.EMPTY; |
||||||
|
clearLabel.setVisible(false); |
||||||
|
} |
||||||
|
}); |
||||||
|
searchTextFieldWrapperPane.add(clearLabel, BorderLayout.EAST); |
||||||
|
searchPane.add(searchTextFieldWrapperPane, BorderLayout.CENTER); |
||||||
|
JButton searchButton = new JButton(SEARCH) { |
||||||
|
@Override |
||||||
|
public void paintComponent(Graphics g) { |
||||||
|
Graphics2D g2d = (Graphics2D) g; |
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||||
|
g2d.setColor(UIConstants.FLESH_BLUE); |
||||||
|
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 4, 4); |
||||||
|
super.paintComponent(g2d); |
||||||
|
} |
||||||
|
}; |
||||||
|
searchButton.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
fireSearch(); |
||||||
|
} |
||||||
|
}); |
||||||
|
searchButton.setPreferredSize(new Dimension(70, 60)); |
||||||
|
searchButton.setForeground(Color.WHITE); |
||||||
|
searchButton.setBorderPainted(false); |
||||||
|
searchButton.setContentAreaFilled(false); |
||||||
|
searchPane.add(searchButton, BorderLayout.EAST); |
||||||
|
searchPane.setBackground(Color.WHITE); |
||||||
|
return searchPane; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createShowPane() { |
||||||
|
JPanel showPane = new JPanel(new BorderLayout()); |
||||||
|
resultPane.add(new DefaultProductNewsPane(), CellType.PRODUCT_NEWS.getFlagStr4None()); |
||||||
|
resultPane.add(new NoResultWithLinkPane(GO_FORUM, AlphaFineConstants.NO_RESULT_ICON), CellType.NO_RESULT.getFlagStr4None()); |
||||||
|
resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.ACTION.getFlagStr4None()); |
||||||
|
resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.FILE.getFlagStr4None()); |
||||||
|
resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.PLUGIN.getFlagStr4None()); |
||||||
|
resultPane.add(new HelpDocumentNoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.DOCUMENT.getFlagStr4None()); |
||||||
|
resultPane.add(new NetWorkFailedPane(this::reSearch), AlphaFineConstants.NETWORK_ERROR); |
||||||
|
|
||||||
|
JPanel labelPane = new JPanel(new BorderLayout()); |
||||||
|
labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); |
||||||
|
labelPane.setBackground(Color.WHITE); |
||||||
|
JPanel labelContentPane = new JPanel(new BorderLayout()); |
||||||
|
UILabel tabLabel = new UILabel(PRODUCT_DYNAMICS); |
||||||
|
tabLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); |
||||||
|
tabLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); |
||||||
|
tabLabel.setPreferredSize(new Dimension(100, 30)); |
||||||
|
JPanel westPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||||
|
westPane.add(tabLabel); |
||||||
|
labelContentPane.add(westPane, BorderLayout.WEST); |
||||||
|
JPanel eastPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); |
||||||
|
UILabel readLabel = new UILabel(ONE_CLICK_READ); |
||||||
|
readLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
||||||
|
readLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));; |
||||||
|
readLabel.setPreferredSize(new Dimension(100, 30)); |
||||||
|
readLabel.setForeground(UIConstants.FLESH_BLUE); |
||||||
|
readLabel.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
fireOneClickRead(); |
||||||
|
showPane.repaint(); |
||||||
|
} |
||||||
|
}); |
||||||
|
eastPane.add(readLabel); |
||||||
|
labelContentPane.add(eastPane, BorderLayout.EAST); |
||||||
|
labelContentPane.setBackground(new Color(245, 245, 247)); |
||||||
|
labelPane.add(labelContentPane); |
||||||
|
labelPane.setPreferredSize(new Dimension(AlphaFineConstants.FULL_SIZE.width, 30)); |
||||||
|
|
||||||
|
tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); |
||||||
|
tabPane.setBackground(Color.WHITE); |
||||||
|
List<SelectedLabel> selectedLabelList = createSelectedLabelList(); |
||||||
|
selectedType = selectedLabelList.get(0).getCellType(); |
||||||
|
// 第一个tab 非产品动态
|
||||||
|
if (selectedType != CellType.PRODUCT_NEWS) { |
||||||
|
tabLabel.setText(selectedLabelList.get(0).getText()); |
||||||
|
readLabel.setVisible(false); |
||||||
|
} |
||||||
|
for (SelectedLabel selectedLabel : selectedLabelList) { |
||||||
|
selectedLabel.addMouseListener(createMouseListener(selectedLabelList, selectedLabel, tabPane, tabLabel, readLabel)); |
||||||
|
tabPane.add(selectedLabel); |
||||||
|
} |
||||||
|
showPane.add(tabPane, BorderLayout.NORTH); |
||||||
|
showPane.add(labelPane, BorderLayout.CENTER); |
||||||
|
showPane.add(resultPane, BorderLayout.SOUTH); |
||||||
|
return showPane; |
||||||
|
} |
||||||
|
|
||||||
|
private MouseAdapter createMouseListener(List<SelectedLabel> selectedLabelList, SelectedLabel selectedLabel, |
||||||
|
JPanel tabPane, UILabel tabLabel, UILabel readLabel) { |
||||||
|
return new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
for (SelectedLabel label : selectedLabelList) { |
||||||
|
label.setSelected(false); |
||||||
|
label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); |
||||||
|
} |
||||||
|
selectedLabel.setSelected(true); |
||||||
|
// 处理产品动态 tab与下方文字展示不一致
|
||||||
|
if (ComparatorUtils.equals(selectedLabel.getText().trim(), PRODUCT_NEWS)) { |
||||||
|
tabLabel.setText(PRODUCT_DYNAMICS); |
||||||
|
} else { |
||||||
|
tabLabel.setText(selectedLabel.getText()); |
||||||
|
} |
||||||
|
readLabel.setVisible(false); |
||||||
|
tabPane.repaint(); |
||||||
|
switch (selectedLabel.getCellType()) { |
||||||
|
case PRODUCT_NEWS: |
||||||
|
readLabel.setVisible(true); |
||||||
|
switchType(CellType.PRODUCT_NEWS); |
||||||
|
break; |
||||||
|
case ACTION: |
||||||
|
currentSearchWorkerManager = settingSearchWorkerManager; |
||||||
|
switchType(CellType.ACTION); |
||||||
|
break; |
||||||
|
case FILE: |
||||||
|
currentSearchWorkerManager = fileSearchWorkerManager; |
||||||
|
switchType(CellType.FILE); |
||||||
|
break; |
||||||
|
case DOCUMENT: |
||||||
|
currentSearchWorkerManager = documentWorkerManager; |
||||||
|
switchType(CellType.DOCUMENT); |
||||||
|
break; |
||||||
|
case PLUGIN: |
||||||
|
currentSearchWorkerManager = pluginSearchWorkerManager; |
||||||
|
switchType(CellType.PLUGIN); |
||||||
|
break; |
||||||
|
} |
||||||
|
if (currentSearchWorkerManager != null) { |
||||||
|
AlphaFineList alphaFineList = currentSearchWorkerManager.getSearchResultList(); |
||||||
|
if (alphaFineList != null) { |
||||||
|
alphaFineList.setSelectedIndex(0); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Color defaultColor; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
defaultColor = selectedLabel.getForeground(); |
||||||
|
selectedLabel.setForeground(AlphaFineConstants.SUSPENDED_COLOR); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
selectedLabel.setForeground(defaultColor); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
private List<SelectedLabel> createSelectedLabelList() { |
||||||
|
List<SelectedLabel> selectedLabelList = new ArrayList<>(); |
||||||
|
AlphaFineConfigManager alphaFineConfigManager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager(); |
||||||
|
if (alphaFineConfigManager.isProductDynamics()) { |
||||||
|
selectedLabelList.add(new SelectedLabel(PRODUCT_NEWS, CellType.PRODUCT_NEWS, true)); |
||||||
|
} |
||||||
|
if (alphaFineConfigManager.isContainAction()) { |
||||||
|
selectedLabelList.add(new SelectedLabel(SETTING, CellType.ACTION)); |
||||||
|
} |
||||||
|
if (alphaFineConfigManager.isContainFileContent() || alphaFineConfigManager.isContainTemplate()) { |
||||||
|
selectedLabelList.add(new SelectedLabel(TEMPLATES, CellType.FILE)); |
||||||
|
} |
||||||
|
if (alphaFineConfigManager.isContainDocument()) { |
||||||
|
selectedLabelList.add(new SelectedLabel(HELP, CellType.DOCUMENT)); |
||||||
|
} |
||||||
|
if (alphaFineConfigManager.isContainPlugin()) { |
||||||
|
selectedLabelList.add(new SelectedLabel(PLUGIN, CellType.PLUGIN)); |
||||||
|
} |
||||||
|
return selectedLabelList; |
||||||
|
} |
||||||
|
|
||||||
|
private void fireOneClickRead() { |
||||||
|
List<ProductNews> productNewsList = ProductNewsSearchManager.getInstance().getCachedProductNewsList(); |
||||||
|
Set<Long> readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); |
||||||
|
for (ProductNews productNews : productNewsList) { |
||||||
|
readSet.add(productNews.getId()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void switchType(CellType cellType) { |
||||||
|
this.selectedType = cellType; |
||||||
|
if (StringUtils.isEmpty(searchTextField.getText())) { |
||||||
|
cardLayout.show(resultPane, cellType.getFlagStr4None()); |
||||||
|
} else { |
||||||
|
// 当前搜索未结束 不切换loading
|
||||||
|
if (!checkSearchLoading()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
// 所有都搜索都结束 移除loading
|
||||||
|
if (isAllSearchOver()) { |
||||||
|
resultPane.remove(searchLoadingPane); |
||||||
|
} |
||||||
|
|
||||||
|
// 网络异常
|
||||||
|
if (checkNetworkError()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
cardLayout.show(resultPane, cellType.getFlagStr4Result()); |
||||||
|
checkSearchResult(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private boolean checkNetworkError() { |
||||||
|
boolean networkError; |
||||||
|
if (selectedType == CellType.PRODUCT_NEWS) { |
||||||
|
networkError = productNewsSearchWorkerManager.isNetWorkError(); |
||||||
|
} else { |
||||||
|
networkError = currentSearchWorkerManager.isNetWorkError(); |
||||||
|
} |
||||||
|
cardLayout.show(resultPane, AlphaFineConstants.NETWORK_ERROR); |
||||||
|
return networkError; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean checkSearchLoading() { |
||||||
|
boolean searchOver; |
||||||
|
if (selectedType == CellType.PRODUCT_NEWS) { |
||||||
|
searchOver = productNewsSearchWorkerManager.isSearchOver(); |
||||||
|
} else { |
||||||
|
searchOver = currentSearchWorkerManager.isSearchOver(); |
||||||
|
} |
||||||
|
cardLayout.show(resultPane, AlphaFineConstants.LOADING); |
||||||
|
return searchOver; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isAllSearchOver() { |
||||||
|
return productNewsSearchWorkerManager.isSearchOver() |
||||||
|
&& pluginSearchWorkerManager.isSearchOver() |
||||||
|
&& fileSearchWorkerManager.isSearchOver() |
||||||
|
&& settingSearchWorkerManager.isSearchOver() |
||||||
|
&& documentWorkerManager.isSearchOver(); |
||||||
|
} |
||||||
|
|
||||||
|
private void checkSearchResult() { |
||||||
|
if (currentSearchWorkerManager == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
searchResultList = currentSearchWorkerManager.getSearchResultList(); |
||||||
|
if (searchResultList != null) { |
||||||
|
searchResultList.requestFocus(); |
||||||
|
} |
||||||
|
boolean hasSearchResult = true; |
||||||
|
if (selectedType == CellType.PRODUCT_NEWS) { |
||||||
|
hasSearchResult = productNewsSearchWorkerManager.hasSearchResult(); |
||||||
|
} else { |
||||||
|
hasSearchResult = currentSearchWorkerManager.hasSearchResult(); |
||||||
|
} |
||||||
|
|
||||||
|
if (!hasSearchResult) { |
||||||
|
cardLayout.show(resultPane, CellType.NO_RESULT.getFlagStr4None()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void initSearchTextField() { |
||||||
|
searchTextField = new AlphaFineTextField(PLACE_HOLDER); |
||||||
|
initTextFieldListener(); |
||||||
|
searchTextField.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); |
||||||
|
searchTextField.setBackground(Color.WHITE); |
||||||
|
searchTextField.setPreferredSize(new Dimension(300, 60)); |
||||||
|
searchTextField.setBorder(null); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void initTextFieldListener() { |
||||||
|
searchTextField.addKeyListener(new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
// 搜索提示框
|
||||||
|
if (StringUtils.isNotEmpty(searchTextField.getText())) { |
||||||
|
clearLabel.setVisible(true); |
||||||
|
SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); |
||||||
|
} else { |
||||||
|
beforeSearchStr = StringUtils.EMPTY; |
||||||
|
} |
||||||
|
AlphaFineToolTipList alphaFineToolTipList = SearchTooltipPopup.getInstance().getAlphaFineToolTipList(); |
||||||
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
||||||
|
if (!alphaFineToolTipList.isSelectionEmpty()) { |
||||||
|
fireSearch(alphaFineToolTipList.getSelectedValue()); |
||||||
|
return; |
||||||
|
} |
||||||
|
fireSearch(); |
||||||
|
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) { |
||||||
|
if (alphaFineToolTipList.getSelectedIndex() == alphaFineToolTipList.getModel().getSize() - 1) { |
||||||
|
alphaFineToolTipList.setSelectedIndex(0); |
||||||
|
} |
||||||
|
alphaFineToolTipList.setSelectedIndex(alphaFineToolTipList.getSelectedIndex() + 1); |
||||||
|
} else if (e.getKeyCode() == KeyEvent.VK_UP) { |
||||||
|
alphaFineToolTipList.setSelectedIndex(alphaFineToolTipList.getSelectedIndex() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
searchTextField.addFocusListener(new FocusListener() { |
||||||
|
@Override |
||||||
|
public void focusGained(FocusEvent e) { |
||||||
|
if (StringUtils.isNotEmpty(searchTextField.getText())) { |
||||||
|
SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void focusLost(FocusEvent e) { |
||||||
|
if (e.getOppositeComponent() != SearchTooltipPopup.getInstance().getAlphaFineToolTipList()) { |
||||||
|
SearchTooltipPopup.getInstance().hide(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
startSearchTextFieldTimer(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void startSearchTextFieldTimer() { |
||||||
|
Timer timer = new Timer(TIMER_DELAY, e -> { |
||||||
|
// 坑 isShowing返回false 即使textField有内容 getText返回的也是空
|
||||||
|
if (searchTextField.isShowing() && StringUtils.isEmpty(searchTextField.getText())) { |
||||||
|
SearchTooltipPopup.getInstance().hide(); |
||||||
|
clearLabel.setVisible(false); |
||||||
|
switchType(selectedType); |
||||||
|
beforeSearchStr = StringUtils.EMPTY; |
||||||
|
} else if (searchTextField.hasFocus()) { |
||||||
|
clearLabel.setVisible(true); |
||||||
|
SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); |
||||||
|
} |
||||||
|
tabPane.repaint(); |
||||||
|
|
||||||
|
}); |
||||||
|
timer.start(); |
||||||
|
} |
||||||
|
|
||||||
|
public void fireSearch(String text) { |
||||||
|
searchTextField.setText(text); |
||||||
|
fireSearch(); |
||||||
|
} |
||||||
|
|
||||||
|
private void fireSearch() { |
||||||
|
// 焦点转移
|
||||||
|
AlphaFineFrame.this.requestFocus(); |
||||||
|
if (ComparatorUtils.equals(beforeSearchStr, searchTextField.getText())) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (StringUtils.isEmpty(searchTextField.getText())) { |
||||||
|
beforeSearchStr = StringUtils.EMPTY; |
||||||
|
return; |
||||||
|
} |
||||||
|
String lowerCaseSearchText = preProcessSearchText(searchTextField.getText().toLowerCase()); |
||||||
|
if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isNeedSegmentationCheckbox()) { |
||||||
|
dealSegmentationSearch(lowerCaseSearchText); |
||||||
|
} else { |
||||||
|
dealNormalSearch(); |
||||||
|
} |
||||||
|
DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch().push(searchTextField.getText()); |
||||||
|
doSearch(lowerCaseSearchText); |
||||||
|
beforeSearchStr = searchTextField.getText(); |
||||||
|
SearchTooltipPopup.getInstance().hide(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 普通搜索 |
||||||
|
*/ |
||||||
|
private void dealNormalSearch() { |
||||||
|
String searchText = preProcessSearchText(searchTextField.getText()); |
||||||
|
if (StringUtils.isEmpty(getRealSearchText(searchText))) { |
||||||
|
segmentationResult = null; |
||||||
|
} else { |
||||||
|
segmentationResult = new String[]{getRealSearchText(searchText)}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 分词搜索 |
||||||
|
*/ |
||||||
|
private void dealSegmentationSearch(String lowerCaseSearchText) { |
||||||
|
//是高级搜索
|
||||||
|
if (searchTextField.getText().toLowerCase().startsWith(ADVANCED_SEARCH_MARK)) { |
||||||
|
segmentationResult = SegmentationManager.getInstance().startSegmentation(getStoreText(lowerCaseSearchText)); |
||||||
|
} |
||||||
|
//是普通搜索
|
||||||
|
else { |
||||||
|
segmentationResult = SegmentationManager.getInstance().startSegmentation(lowerCaseSearchText); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 文本预处理 限制长度 |
||||||
|
* |
||||||
|
* @param text |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private String preProcessSearchText(String text) { |
||||||
|
if (text.length() > AlphaFineConstants.LEN_LIMIT) { |
||||||
|
return text.substring(0, AlphaFineConstants.LEN_LIMIT); |
||||||
|
} else { |
||||||
|
return text; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void dealWithSearchResult() { |
||||||
|
final AlphaCellModel model = searchResultList.getSelectedValue(); |
||||||
|
if (model != null) { |
||||||
|
model.doAction(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void showResult(String flag) { |
||||||
|
cardLayout.show(resultPane, flag); |
||||||
|
} |
||||||
|
|
||||||
|
public void addResult(JPanel panel, String flag) { |
||||||
|
resultPane.add(panel, flag); |
||||||
|
} |
||||||
|
|
||||||
|
public void removeSearchResultPane(JPanel panel) { |
||||||
|
resultPane.remove(panel); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void doSearch(String text) { |
||||||
|
initSearchLoadingPane(); |
||||||
|
SearchTextBean searchTextBean = generateSearchTextBean(text); |
||||||
|
this.productNewsSearchWorkerManager.doSearch(searchTextBean); |
||||||
|
this.settingSearchWorkerManager.doSearch(searchTextBean); |
||||||
|
this.fileSearchWorkerManager.doSearch(searchTextBean); |
||||||
|
this.documentWorkerManager.doSearch(searchTextBean); |
||||||
|
this.pluginSearchWorkerManager.doSearch(searchTextBean); |
||||||
|
} |
||||||
|
|
||||||
|
private SearchTextBean generateSearchTextBean(String searchText) { |
||||||
|
if (searchText.startsWith(ACTION_MARK_SHORT) || searchText.startsWith(ACTION_MARK) |
||||||
|
|| searchText.startsWith(DOCUMENT_MARK_SHORT) || searchText.startsWith(DOCUMENT_MARK)) { |
||||||
|
return new SearchTextBean(StringUtils.EMPTY, new String[]{getStoreText(searchText)}); |
||||||
|
} else if (searchText.startsWith(FILE_MARK_SHORT) || searchText.startsWith(FILE_MARK) |
||||||
|
|| searchText.startsWith(CPT_MARK) || searchText.startsWith(FRM_MARK) |
||||||
|
|| searchText.startsWith(PLUGIN_MARK_SHORT) || searchText.startsWith(PLUGIN_MARK)) { |
||||||
|
return new SearchTextBean(getStoreText(searchText), new String[]{getStoreText(searchText)}); |
||||||
|
} else if (searchText.startsWith(DS_MARK)) { |
||||||
|
return new SearchTextBean(getStoreText(searchText), new String[]{DS_NAME + getStoreText(searchText)}); |
||||||
|
} else { |
||||||
|
return new SearchTextBean(searchText, segmentationResult == null ? new String[]{} : segmentationResult); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 仅搜索依赖网络的搜索项 |
||||||
|
* |
||||||
|
*/ |
||||||
|
private void reSearch() { |
||||||
|
String text = preProcessSearchText(this.searchTextField.getText().toLowerCase()); |
||||||
|
if (StringUtils.isEmpty(text)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
searchLoadingPane = new SearchLoadingPane(); |
||||||
|
SearchTextBean searchTextBean = new SearchTextBean(text, segmentationResult); |
||||||
|
this.productNewsSearchWorkerManager.doSearch(searchTextBean); |
||||||
|
this.documentWorkerManager.doSearch(searchTextBean); |
||||||
|
this.pluginSearchWorkerManager.doSearch(searchTextBean); |
||||||
|
} |
||||||
|
|
||||||
|
private void initSearchLoadingPane() { |
||||||
|
if (searchLoadingPane == null) { |
||||||
|
searchLoadingPane = new SearchLoadingPane(); |
||||||
|
} |
||||||
|
resultPane.add(searchLoadingPane, AlphaFineConstants.LOADING); |
||||||
|
cardLayout.show(resultPane, AlphaFineConstants.LOADING); |
||||||
|
} |
||||||
|
|
||||||
|
public String getSearchText() { |
||||||
|
return searchTextField.getText(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public CellType getSelectedType() { |
||||||
|
return selectedType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setStoreText(String storeText) { |
||||||
|
this.storeText = storeText; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 截取字符串中关键词 |
||||||
|
* |
||||||
|
* @param searchText |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private String getStoreText(String searchText) { |
||||||
|
//这里也需要先做一个去除不需要空格的处理
|
||||||
|
setStoreText((searchText.substring(searchText.indexOf(StringUtils.BLANK) + 1)).replaceAll(StringUtils.BLANK, StringUtils.EMPTY)); |
||||||
|
return storeText; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 去除特殊字符,空格等 |
||||||
|
*/ |
||||||
|
private String getRealSearchText(String searchText) { |
||||||
|
searchText = searchText.toLowerCase(); |
||||||
|
Pattern p = Pattern.compile(AlphaFineConstants.SPECIAL_CHARACTER_REGEX); |
||||||
|
Matcher m = p.matcher(searchText); |
||||||
|
searchText = m.replaceAll(StringUtils.EMPTY).trim().replaceAll(StringUtils.BLANK, StringUtils.EMPTY); |
||||||
|
if (searchText.length() == 0) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return searchText; |
||||||
|
} |
||||||
|
|
||||||
|
private UIButton createButton(Icon icon) { |
||||||
|
UIButton button = new UIButton() { |
||||||
|
@Override |
||||||
|
public void paintComponent(Graphics g) { |
||||||
|
g.setColor(Color.WHITE); |
||||||
|
g.fillRect(0, 0, getSize().width, getSize().height); |
||||||
|
super.paintComponent(g); |
||||||
|
} |
||||||
|
}; |
||||||
|
button.setPreferredSize(new Dimension(20, 20)); |
||||||
|
button.setIcon(icon); |
||||||
|
button.set4ToolbarButton(); |
||||||
|
button.setBorderPainted(false); |
||||||
|
button.setRolloverEnabled(false); |
||||||
|
return button; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置面板位置 |
||||||
|
* |
||||||
|
* @param win |
||||||
|
*/ |
||||||
|
private void centerWindow(Window win) { |
||||||
|
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
||||||
|
|
||||||
|
Dimension winSize = win.getSize(); |
||||||
|
|
||||||
|
if (winSize.height > screenSize.height) { |
||||||
|
winSize.height = screenSize.height; |
||||||
|
} |
||||||
|
if (winSize.width > screenSize.width) { |
||||||
|
winSize.width = screenSize.width; |
||||||
|
} |
||||||
|
//这里设置位置:水平居中,竖直偏上
|
||||||
|
win.setLocation((screenSize.width - winSize.width) / 2, (screenSize.height - winSize.height) / AlphaFineConstants.SHOW_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setVisible(boolean b) { |
||||||
|
super.setVisible(b); |
||||||
|
QuestionWindow.getInstance().setVisible(!b); |
||||||
|
if (!b) { |
||||||
|
AlphaFineHelper.resetAlphaFineDialog(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void dispose() { |
||||||
|
super.dispose(); |
||||||
|
AlphaFineHelper.resetAlphaFineDialog(); |
||||||
|
QuestionWindow.getInstance().setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.DocumentModel; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.ResultShowPane; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import javax.swing.JList; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/18 |
||||||
|
*/ |
||||||
|
public class AlphaFineList extends JList<AlphaCellModel> { |
||||||
|
|
||||||
|
private ResultShowPane resultShowPane; |
||||||
|
|
||||||
|
public AlphaFineList() { |
||||||
|
addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
AlphaCellModel selectedValue = getSelectedValue(); |
||||||
|
if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT && selectedValue.hasAction()) { |
||||||
|
// 点击搜索结果 主页面移动到后面
|
||||||
|
if (!(selectedValue instanceof DocumentModel)) { |
||||||
|
// 帮助文档不跳转
|
||||||
|
AlphaFineHelper.getAlphaFineDialog().toBack(); |
||||||
|
} |
||||||
|
dealWithSearchResult(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
addListSelectionListener(e -> { |
||||||
|
if (!e.getValueIsAdjusting() && getSelectedValue() != null) { |
||||||
|
if (resultShowPane != null) { |
||||||
|
resultShowPane.showResult(getSelectedValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
addKeyListener(new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
||||||
|
AlphaCellModel selectedValue = getSelectedValue(); |
||||||
|
if (selectedValue.hasAction() && !(selectedValue instanceof DocumentModel)) { |
||||||
|
AlphaFineHelper.getAlphaFineDialog().toBack(); |
||||||
|
} |
||||||
|
dealWithSearchResult(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void setResultShowPane(ResultShowPane resultShowPane) { |
||||||
|
this.resultShowPane = resultShowPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setSelectedIndex(int index) { |
||||||
|
super.setSelectedIndex(index); |
||||||
|
AlphaCellModel alphaCellModel = getSelectedValue(); |
||||||
|
if (resultShowPane != null && alphaCellModel != null) { |
||||||
|
resultShowPane.showResult(getSelectedValue()); |
||||||
|
} |
||||||
|
ensureIndexIsVisible(getSelectedIndex()); |
||||||
|
} |
||||||
|
|
||||||
|
private void dealWithSearchResult() { |
||||||
|
final AlphaCellModel model = this.getSelectedValue(); |
||||||
|
if (model != null) { |
||||||
|
model.doAction(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineUtil; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class AlphaFineToolTipContentCellRender implements ListCellRenderer<String> { |
||||||
|
|
||||||
|
private static final Color SELECTED_COLOR = new Color(65, 155, 249, 26); |
||||||
|
|
||||||
|
private static final Icon HOT_SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/hot_search.svg"); |
||||||
|
|
||||||
|
private static final Icon SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/search.svg"); |
||||||
|
|
||||||
|
private static final Icon HISTORY_SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/history_search.svg"); |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, |
||||||
|
boolean isSelected, boolean cellHasFocus) { |
||||||
|
|
||||||
|
if (StringUtils.isEmpty(value)) { |
||||||
|
return new LineCellRender().getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
||||||
|
} |
||||||
|
|
||||||
|
JPanel panel = new JPanel(new BorderLayout()); |
||||||
|
panel.setBackground(null); |
||||||
|
|
||||||
|
UILabel iconLabel = new UILabel(); |
||||||
|
iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0)); |
||||||
|
iconLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); |
||||||
|
iconLabel.setText(value); |
||||||
|
if (ComparatorUtils.equals(value, AlphaFineConstants.HOT_SEARCH)) { |
||||||
|
iconLabel.setIcon(HOT_SEARCH_ICON); |
||||||
|
} else if (AlphaFineConstants.HOT_SEARCH_SET.contains(value)) { |
||||||
|
iconLabel.setIcon(SEARCH_ICON); |
||||||
|
} else { |
||||||
|
iconLabel.setIcon(HISTORY_SEARCH_ICON); |
||||||
|
} |
||||||
|
|
||||||
|
if (isSelected && !ComparatorUtils.equals(value, AlphaFineConstants.HOT_SEARCH)) { |
||||||
|
iconLabel.setText(AlphaFineUtil.highLightModelName(value, new String[]{value})); |
||||||
|
panel.setBackground(SELECTED_COLOR); |
||||||
|
} |
||||||
|
panel.add(iconLabel, BorderLayout.WEST); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); |
||||||
|
panel.setPreferredSize(new Dimension(640, 32)); |
||||||
|
|
||||||
|
return panel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import javax.swing.JList; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class AlphaFineToolTipList extends JList<String> { |
||||||
|
|
||||||
|
public AlphaFineToolTipList() { |
||||||
|
addKeyListener(new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
||||||
|
AlphaFineHelper.getAlphaFineDialog().fireSearch(getSelectedValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (e.getClickCount() == 2) { |
||||||
|
if (ComparatorUtils.equals(getSelectedValue(), AlphaFineConstants.HOT_SEARCH)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
AlphaFineHelper.getAlphaFineDialog().fireSearch(getSelectedValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.util.Stack; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class AlphaSearchTooltipPane extends JPanel { |
||||||
|
|
||||||
|
private AlphaFineToolTipList alphaFineToolTipList; |
||||||
|
|
||||||
|
public AlphaSearchTooltipPane() { |
||||||
|
alphaFineToolTipList = new AlphaFineToolTipList(); |
||||||
|
alphaFineToolTipList.setCellRenderer(new AlphaFineToolTipContentCellRender()); |
||||||
|
alphaFineToolTipList.setModel(getDefaultListModel()); |
||||||
|
UIScrollPane scrollPane = new UIScrollPane(alphaFineToolTipList); |
||||||
|
scrollPane.setBorder(null); |
||||||
|
scrollPane.setBackground(Color.WHITE); |
||||||
|
this.add(scrollPane); |
||||||
|
this.setPreferredSize(new Dimension(640, 250)); |
||||||
|
this.setBackground(Color.WHITE); |
||||||
|
} |
||||||
|
|
||||||
|
public AlphaFineToolTipList getAlphaFineToolTipList() { |
||||||
|
return alphaFineToolTipList; |
||||||
|
} |
||||||
|
|
||||||
|
private DefaultListModel<String> getDefaultListModel() { |
||||||
|
DefaultListModel<String> defaultListModel = new DefaultListModel<>(); |
||||||
|
defaultListModel.addElement(AlphaFineConstants.HOT_SEARCH); |
||||||
|
for (String content : AlphaFineConstants.HOT_SEARCH_SET) { |
||||||
|
defaultListModel.addElement(content); |
||||||
|
} |
||||||
|
return defaultListModel; |
||||||
|
} |
||||||
|
|
||||||
|
public void refreshHistory() { |
||||||
|
Stack<String> stack = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch(); |
||||||
|
if (stack.isEmpty()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
DefaultListModel<String> defaultListModel = new DefaultListModel<>(); |
||||||
|
for (int i = stack.size() - 1; i >= 0; i--) { |
||||||
|
defaultListModel.addElement(stack.get(i)); |
||||||
|
} |
||||||
|
// defaultListModel.addElement(StringUtils.EMPTY);
|
||||||
|
defaultListModel.addElement(AlphaFineConstants.HOT_SEARCH); |
||||||
|
for (String content : AlphaFineConstants.HOT_SEARCH_SET) { |
||||||
|
defaultListModel.addElement(content); |
||||||
|
} |
||||||
|
alphaFineToolTipList.setModel(defaultListModel); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class LineCellRender implements ListCellRenderer<String> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, |
||||||
|
boolean isSelected, boolean cellHasFocus) { |
||||||
|
JPanel panel = new JPanel(new BorderLayout()); |
||||||
|
UILabel splitLabel = new UILabel(); |
||||||
|
panel.setBackground(null); |
||||||
|
splitLabel.setBackground(UIConstants.BARNOMAL); |
||||||
|
splitLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5,0)); |
||||||
|
panel.setPreferredSize(new Dimension(640, 1)); |
||||||
|
panel.add(splitLabel); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineUtil; |
||||||
|
import com.fr.design.mainframe.alphafine.model.ProductNews; |
||||||
|
import com.fr.design.utils.DesignUtils; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/19 |
||||||
|
*/ |
||||||
|
public class ProductNewsContentCellRender implements ListCellRenderer<Object> { |
||||||
|
|
||||||
|
private static final String FINE_REPORT = "FineReport"; |
||||||
|
|
||||||
|
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd"); |
||||||
|
|
||||||
|
/** |
||||||
|
* 透明灰色背景 Y方向偏移 |
||||||
|
*/ |
||||||
|
private static final int GRAY_BACKGROUND_Y_GAP = 39; |
||||||
|
|
||||||
|
/** |
||||||
|
* 透明灰色背景 高度 |
||||||
|
*/ |
||||||
|
private static final int GRAY_BACKGROUND_HEIGHT = 23; |
||||||
|
|
||||||
|
/** |
||||||
|
* 单行产品动态的高度与宽度尺寸 |
||||||
|
*/ |
||||||
|
private static final Dimension DEFAULT_DIMENSION = new Dimension(500, 100); |
||||||
|
|
||||||
|
private String[] segmentationResult; |
||||||
|
|
||||||
|
private ProductNewsList productNewsList; |
||||||
|
|
||||||
|
public ProductNewsContentCellRender(String[] segmentationResult, ProductNewsList productNewsList) { |
||||||
|
this.segmentationResult = segmentationResult; |
||||||
|
this.productNewsList = productNewsList; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNewsContentCellRender(ProductNewsList productNewsList) { |
||||||
|
this(null, productNewsList); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, |
||||||
|
boolean cellHasFocus) { |
||||||
|
ProductNews productNews = (ProductNews) value; |
||||||
|
JPanel panel = new JPanel(new BorderLayout()); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); |
||||||
|
panel.setBackground(Color.WHITE); |
||||||
|
|
||||||
|
panel.add(new ProductNewsImagePanel(productNews), BorderLayout.WEST); |
||||||
|
JPanel textPane = new JPanel(new BorderLayout()); |
||||||
|
textPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 0)); |
||||||
|
UILabel titleLabel = new UILabel(AlphaFineUtil.highLightModelName(productNews.getTitle(), segmentationResult)); |
||||||
|
titleLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(20)); |
||||||
|
if (productNewsList.getHoverIndex() == index) { |
||||||
|
titleLabel.setForeground(UIConstants.FLESH_BLUE); |
||||||
|
} |
||||||
|
|
||||||
|
textPane.add(titleLabel, BorderLayout.NORTH); |
||||||
|
JPanel infoPane = new JPanel(new BorderLayout()); |
||||||
|
UILabel productLabel = new UILabel(FINE_REPORT) { |
||||||
|
@Override |
||||||
|
protected void paintComponent(Graphics g) { |
||||||
|
g.setColor(AlphaFineConstants.BACKGROUND_COLOR); |
||||||
|
g.fillRect(0, getHeight() - GRAY_BACKGROUND_Y_GAP, getWidth(), GRAY_BACKGROUND_HEIGHT); |
||||||
|
super.paintComponent(g); |
||||||
|
} |
||||||
|
}; |
||||||
|
productLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); |
||||||
|
infoPane.add(productLabel, BorderLayout.WEST); |
||||||
|
|
||||||
|
UILabel dateLabel = new UILabel(DATE_FORMAT.format(productNews.getPushDate())); |
||||||
|
dateLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); |
||||||
|
dateLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); |
||||||
|
infoPane.setBackground(Color.WHITE); |
||||||
|
infoPane.add(dateLabel, BorderLayout.CENTER); |
||||||
|
textPane.setBackground(Color.WHITE); |
||||||
|
textPane.add(infoPane, BorderLayout.CENTER); |
||||||
|
panel.add(textPane, BorderLayout.CENTER); |
||||||
|
panel.setPreferredSize(DEFAULT_DIMENSION); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.base.GraphHelper; |
||||||
|
import com.fr.base.svg.SVGLoader; |
||||||
|
import com.fr.base.svg.SystemScaleUtils; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.mainframe.alphafine.model.ProductNews; |
||||||
|
import com.fr.design.utils.SvgPaintUtils; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
|
||||||
|
import java.awt.RenderingHints; |
||||||
|
import java.util.Set; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/15 |
||||||
|
*/ |
||||||
|
public class ProductNewsImagePanel extends JPanel { |
||||||
|
|
||||||
|
private static final Image NEW_TIP_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/new_tip.svg"); |
||||||
|
|
||||||
|
private static final int BACKGROUND_HEIGHT = 20; |
||||||
|
|
||||||
|
private static final Color BACKGROUND_COLOR = new Color(116, 181, 249); |
||||||
|
|
||||||
|
private static final Color COVER_COLOR = new Color(116, 181, 249, 26); |
||||||
|
|
||||||
|
private ProductNews productNews; |
||||||
|
|
||||||
|
private int width = 200; |
||||||
|
private int height = 150; |
||||||
|
|
||||||
|
public ProductNewsImagePanel(ProductNews productNews) { |
||||||
|
this.productNews = productNews; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintComponent(Graphics g) { |
||||||
|
super.paintComponent(g); |
||||||
|
Graphics2D g2 = (Graphics2D) g; |
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||||
|
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
||||||
|
Color defaultColor = g2.getColor(); |
||||||
|
|
||||||
|
Image image = productNews.getImage(); |
||||||
|
if (image != null) { |
||||||
|
g2.drawImage(productNews.getImage(), 0, 0, getWidth(), getHeight(), this); |
||||||
|
} else { |
||||||
|
g2.setColor(COVER_COLOR); |
||||||
|
g2.fillRect(0, 0, getWidth(), getHeight()); |
||||||
|
} |
||||||
|
Set<Long> readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); |
||||||
|
if (!readSet.contains(productNews.getId())) { |
||||||
|
SvgPaintUtils.beforePaint(g2); |
||||||
|
g2.drawImage(NEW_TIP_IMAGE, 0, 0, this); |
||||||
|
SvgPaintUtils.afterPaint(g2); |
||||||
|
} |
||||||
|
|
||||||
|
g2.setColor(BACKGROUND_COLOR); |
||||||
|
g2.fillRect(0, getHeight() - BACKGROUND_HEIGHT, getWidth(), BACKGROUND_HEIGHT); |
||||||
|
g2.setColor(Color.WHITE); |
||||||
|
int x = (getWidth() - GraphHelper.getWidth(productNews.getTag().getDesc(), g2.getFont())) / 2; |
||||||
|
g2.drawString(productNews.getTag().getDesc(), x, getHeight() - 5); |
||||||
|
g2.setColor(defaultColor); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize() { |
||||||
|
return new Dimension(width, height); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.model.ProductNews; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.Desktop; |
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseMotionAdapter; |
||||||
|
import java.net.URI; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.ListModel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/21 |
||||||
|
*/ |
||||||
|
public class ProductNewsList extends JList<ProductNews> { |
||||||
|
|
||||||
|
private int hoverIndex = -1; |
||||||
|
|
||||||
|
public ProductNewsList(ListModel<ProductNews> dataModel) { |
||||||
|
super(dataModel); |
||||||
|
addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT) { |
||||||
|
dealWithClick(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
hoverIndex = -1; |
||||||
|
ProductNewsList.this.repaint(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
addMouseMotionListener(new MouseMotionAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseMoved(MouseEvent e) { |
||||||
|
Point p = new Point(e.getX(), e.getY()); |
||||||
|
int index = ProductNewsList.this.locationToIndex(p); |
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
||||||
|
if (index != hoverIndex) { |
||||||
|
hoverIndex = index; |
||||||
|
ProductNewsList.this.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNewsList() { |
||||||
|
this(new DefaultListModel<>()); |
||||||
|
} |
||||||
|
|
||||||
|
private void dealWithClick() { |
||||||
|
ProductNews productNews = getSelectedValue(); |
||||||
|
try { |
||||||
|
Desktop.getDesktop().browse(new URI(productNews.getUrl())); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet().add(productNews.getId()); |
||||||
|
AlphaFineHelper.getAlphaFineDialog().repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getHoverIndex() { |
||||||
|
return hoverIndex; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
|
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/21 |
||||||
|
*/ |
||||||
|
public class ProductNewsSearchResultPane extends JPanel { |
||||||
|
|
||||||
|
private ProductNewsList productNewsList; |
||||||
|
|
||||||
|
public ProductNewsSearchResultPane(String[] segmentationResult) { |
||||||
|
|
||||||
|
productNewsList = new ProductNewsList(); |
||||||
|
UIScrollPane scrollPane = new UIScrollPane(productNewsList); |
||||||
|
scrollPane.setBackground(Color.WHITE); |
||||||
|
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20)); |
||||||
|
productNewsList.setCellRenderer(new ProductNewsContentCellRender(segmentationResult, productNewsList)); |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
this.setBackground(Color.WHITE); |
||||||
|
this.add(scrollPane); |
||||||
|
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNewsList getProductNewsList() { |
||||||
|
return productNewsList; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,126 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import com.fr.design.mainframe.alphafine.model.SearchResult; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/18 |
||||||
|
*/ |
||||||
|
public class SearchListModel extends DefaultListModel<AlphaCellModel> { |
||||||
|
|
||||||
|
private static final int MAX_SHOW_SIZE = 12; |
||||||
|
private static final long serialVersionUID = 7230585307439551228L; |
||||||
|
|
||||||
|
|
||||||
|
private SearchResult myDelegate; |
||||||
|
|
||||||
|
/** |
||||||
|
* 第一有效的项是否被选中 |
||||||
|
*/ |
||||||
|
private boolean isValidSelected; |
||||||
|
|
||||||
|
private UIScrollPane leftSearchResultPane; |
||||||
|
|
||||||
|
private AlphaFineList searchResultList; |
||||||
|
|
||||||
|
public SearchListModel(SearchResult searchResult, AlphaFineList searchResultList, UIScrollPane leftSearchResultPane) { |
||||||
|
this.myDelegate = searchResult; |
||||||
|
this.searchResultList = searchResultList; |
||||||
|
this.leftSearchResultPane = leftSearchResultPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addElement(AlphaCellModel element) { |
||||||
|
AlphaFineHelper.checkCancel(); |
||||||
|
int index = myDelegate.size(); |
||||||
|
myDelegate.add(element); |
||||||
|
fireContentsChanged(this, index, index); |
||||||
|
fireSelectedStateChanged(element, index); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void fireContentsChanged(Object source, int index0, int index1) { |
||||||
|
if (myDelegate.size() > MAX_SHOW_SIZE) { |
||||||
|
leftSearchResultPane.getVerticalScrollBar().setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0)); |
||||||
|
leftSearchResultPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 2)); |
||||||
|
} else { |
||||||
|
leftSearchResultPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); |
||||||
|
} |
||||||
|
super.fireContentsChanged(source, index0, index1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 触发选中第一有效的项 |
||||||
|
* |
||||||
|
* @param element |
||||||
|
* @param index |
||||||
|
*/ |
||||||
|
private void fireSelectedStateChanged(AlphaCellModel element, int index) { |
||||||
|
if (element.hasAction() && !isValidSelected()) { |
||||||
|
searchResultList.setSelectedIndex(index); |
||||||
|
setValidSelected(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AlphaCellModel getElementAt(int index) { |
||||||
|
return myDelegate.get(index); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void add(int index, AlphaCellModel element) { |
||||||
|
myDelegate.add(index, element); |
||||||
|
fireIntervalAdded(this, index, index); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AlphaCellModel remove(int index) { |
||||||
|
AlphaCellModel object = myDelegate.get(index); |
||||||
|
myDelegate.remove(object); |
||||||
|
fireContentsChanged(this, index, index); |
||||||
|
return object; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getSize() { |
||||||
|
return this.myDelegate.size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeAllElements() { |
||||||
|
this.myDelegate.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 重置选中状态 |
||||||
|
*/ |
||||||
|
public void resetSelectedState() { |
||||||
|
setValidSelected(false); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isValidSelected() { |
||||||
|
return isValidSelected; |
||||||
|
} |
||||||
|
|
||||||
|
private void setValidSelected(boolean selected) { |
||||||
|
isValidSelected = selected; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isEmpty() { |
||||||
|
return myDelegate.isEmpty(); |
||||||
|
} |
||||||
|
|
||||||
|
public void resetState() { |
||||||
|
for (int i = 0; i < getSize(); i++) { |
||||||
|
getElementAt(i).resetState(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineUtil; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JList; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.ListCellRenderer; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/19 |
||||||
|
*/ |
||||||
|
public class SearchResultContentCellRender implements ListCellRenderer<Object> { |
||||||
|
|
||||||
|
private static final int OFFSET = 45; |
||||||
|
private static final String SELECTED_PATH = AlphaFineConstants.IMAGE_URL + "selected"; |
||||||
|
private static final String CELL_PATH = AlphaFineConstants.IMAGE_URL + "alphafine"; |
||||||
|
private static final String SUFFIX = ".png"; |
||||||
|
|
||||||
|
private String[] segmentationResult; |
||||||
|
|
||||||
|
public SearchResultContentCellRender(String[] segmentationResult) { |
||||||
|
this.segmentationResult = segmentationResult; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, |
||||||
|
boolean cellHasFocus) { |
||||||
|
|
||||||
|
|
||||||
|
AlphaCellModel model = (AlphaCellModel) value; |
||||||
|
JPanel panel = new JPanel(new BorderLayout()); |
||||||
|
panel.setBackground(null); |
||||||
|
panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); |
||||||
|
// 图标icon 样式
|
||||||
|
UILabel iconLabel = new UILabel(); |
||||||
|
if (isSelected) { |
||||||
|
iconLabel.setText(StringUtils.BLANK + model.getName()); |
||||||
|
String iconUrl = SELECTED_PATH + model.getType().getTypeValue() + SUFFIX; |
||||||
|
panel.setBackground(AlphaFineConstants.BLUE); |
||||||
|
iconLabel.setForeground(Color.WHITE); |
||||||
|
iconLabel.setIcon(IOUtils.readIcon(iconUrl)); |
||||||
|
} else { |
||||||
|
iconLabel.setText(AlphaFineUtil.highLightModelName(model.getName(), segmentationResult)); |
||||||
|
String iconUrl = CELL_PATH + model.getType().getTypeValue() + SUFFIX; |
||||||
|
iconLabel.setIcon(IOUtils.readIcon(iconUrl)); |
||||||
|
} |
||||||
|
iconLabel.setFont(AlphaFineConstants.MEDIUM_FONT); |
||||||
|
|
||||||
|
|
||||||
|
// 内容详情label 样式
|
||||||
|
UILabel detailLabel = new UILabel(); |
||||||
|
String description = model.getDescription(); |
||||||
|
if (StringUtils.isNotBlank(description)) { |
||||||
|
detailLabel.setText("-" + description); |
||||||
|
detailLabel.setForeground(AlphaFineConstants.LIGHT_GRAY); |
||||||
|
panel.add(detailLabel, BorderLayout.CENTER); |
||||||
|
int width = (int) (iconLabel.getPreferredSize().getWidth() + detailLabel.getPreferredSize().getWidth()); |
||||||
|
if (width > AlphaFineConstants.LEFT_WIDTH - OFFSET) { |
||||||
|
int nameWidth = (int) (AlphaFineConstants.LEFT_WIDTH - detailLabel.getPreferredSize().getWidth() - OFFSET); |
||||||
|
iconLabel.setPreferredSize(new Dimension(nameWidth, AlphaFineConstants.CELL_HEIGHT)); |
||||||
|
} |
||||||
|
} else { |
||||||
|
iconLabel.setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH - OFFSET, AlphaFineConstants.CELL_HEIGHT)); |
||||||
|
} |
||||||
|
|
||||||
|
panel.add(iconLabel, BorderLayout.WEST); |
||||||
|
panel.setPreferredSize(new Dimension(list.getFixedCellWidth(), AlphaFineConstants.CELL_HEIGHT)); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.model.SearchResult; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.ResultShowPane; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class SearchResultPane extends JPanel { |
||||||
|
|
||||||
|
private AlphaFineList searchResultList; |
||||||
|
|
||||||
|
private SearchListModel searchListModel; |
||||||
|
|
||||||
|
private UIScrollPane leftSearchResultPane; |
||||||
|
|
||||||
|
|
||||||
|
public SearchResultPane(String[] segmentationResult, ResultShowPane rightSearchResultPane) { |
||||||
|
searchResultList = new AlphaFineList(); |
||||||
|
searchResultList.setFixedCellHeight(AlphaFineConstants.CELL_HEIGHT); |
||||||
|
leftSearchResultPane = new UIScrollPane(searchResultList); |
||||||
|
leftSearchResultPane.setBorder(null); |
||||||
|
leftSearchResultPane.setBackground(Color.WHITE); |
||||||
|
leftSearchResultPane.setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH, AlphaFineConstants.CONTENT_HEIGHT)); |
||||||
|
searchListModel = new SearchListModel(new SearchResult(), searchResultList, leftSearchResultPane); |
||||||
|
searchResultList.setModel(searchListModel); |
||||||
|
searchResultList.setCellRenderer(new SearchResultContentCellRender(segmentationResult)); |
||||||
|
searchResultList.setResultShowPane(rightSearchResultPane); |
||||||
|
this.setPreferredSize(AlphaFineConstants.CONTENT_SIZE); |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
this.add(leftSearchResultPane, BorderLayout.WEST); |
||||||
|
this.add(rightSearchResultPane, BorderLayout.EAST); |
||||||
|
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
public AlphaFineList getSearchResultList() { |
||||||
|
return searchResultList; |
||||||
|
} |
||||||
|
|
||||||
|
public UIScrollPane getLeftSearchResultPane() { |
||||||
|
return leftSearchResultPane; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Point; |
||||||
|
import javax.swing.Popup; |
||||||
|
import javax.swing.PopupFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class SearchTooltipPopup { |
||||||
|
|
||||||
|
private static final SearchTooltipPopup INSTANCE = new SearchTooltipPopup(); |
||||||
|
|
||||||
|
public static SearchTooltipPopup getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
private AlphaSearchTooltipPane alphaSearchTooltipPane; |
||||||
|
|
||||||
|
private SearchTooltipPopup() { |
||||||
|
alphaSearchTooltipPane = new AlphaSearchTooltipPane(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean showPopup; |
||||||
|
|
||||||
|
private Popup popup; |
||||||
|
|
||||||
|
public void show(Component owner) { |
||||||
|
if (popup == null || !showPopup) { |
||||||
|
PopupFactory pf = PopupFactory.getSharedInstance(); |
||||||
|
Point point = owner.getLocationOnScreen(); |
||||||
|
alphaSearchTooltipPane.refreshHistory(); |
||||||
|
popup = pf.getPopup(owner, alphaSearchTooltipPane, point.x, point.y + owner.getHeight()); |
||||||
|
} |
||||||
|
if (!showPopup) { |
||||||
|
alphaSearchTooltipPane.repaint(); |
||||||
|
popup.show(); |
||||||
|
getAlphaFineToolTipList().clearSelection(); |
||||||
|
showPopup = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public AlphaFineToolTipList getAlphaFineToolTipList() { |
||||||
|
return alphaSearchTooltipPane.getAlphaFineToolTipList(); |
||||||
|
} |
||||||
|
|
||||||
|
public void hide() { |
||||||
|
if (popup != null) { |
||||||
|
popup.hide(); |
||||||
|
} |
||||||
|
showPopup = false; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.component; |
||||||
|
|
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineUtil; |
||||||
|
import com.fr.design.mainframe.alphafine.CellType; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.RenderingHints; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/07 |
||||||
|
*/ |
||||||
|
public class SelectedLabel extends UILabel { |
||||||
|
|
||||||
|
private static final int WIDTH = 4; |
||||||
|
private static final int HEIGHT = 4; |
||||||
|
private static final int GAP = 0; |
||||||
|
private static final int BORDER_RIGHT = 5; |
||||||
|
private static final int BORDER_TOP = 2; |
||||||
|
|
||||||
|
private boolean selected; |
||||||
|
private CellType cellType; |
||||||
|
|
||||||
|
public SelectedLabel(String text, CellType cellType, boolean selected) { |
||||||
|
super(text); |
||||||
|
this.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); |
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(BORDER_TOP, 0, 0, BORDER_RIGHT)); |
||||||
|
this.selected = selected; |
||||||
|
this.cellType = cellType; |
||||||
|
} |
||||||
|
|
||||||
|
public SelectedLabel(String text, CellType cellType) { |
||||||
|
this(text, cellType, false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paintComponent(Graphics g) { |
||||||
|
Graphics2D g2d = (Graphics2D) g; |
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, |
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON); |
||||||
|
if (selected) { |
||||||
|
g2d.setColor(UIConstants.FLESH_BLUE); |
||||||
|
setForeground(UIConstants.FLESH_BLUE); |
||||||
|
g2d.drawLine(0, this.getHeight() - 1, this.getWidth() - BORDER_RIGHT, this.getHeight() - 1); |
||||||
|
} |
||||||
|
super.paintComponent(g); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintBorder(Graphics g) { |
||||||
|
super.paintBorder(g); |
||||||
|
Graphics2D g2d = (Graphics2D) g; |
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||||
|
if (cellType == CellType.PRODUCT_NEWS && AlphaFineUtil.unread()) { |
||||||
|
Color oldColor = g.getColor(); |
||||||
|
g2d.setColor(Color.RED); |
||||||
|
g2d.fillOval(getWidth() - WIDTH, GAP, WIDTH, HEIGHT); |
||||||
|
g2d.setColor(oldColor); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSelected() { |
||||||
|
return selected; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSelected(boolean selected) { |
||||||
|
this.selected = selected; |
||||||
|
} |
||||||
|
|
||||||
|
public CellType getCellType() { |
||||||
|
return cellType; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/27 |
||||||
|
*/ |
||||||
|
public class AlphaFineNetworkException extends RuntimeException { |
||||||
|
|
||||||
|
public AlphaFineNetworkException() { |
||||||
|
super("NetWork Error"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,200 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.model; |
||||||
|
|
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import java.awt.Image; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* 产品动态 |
||||||
|
* |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/05 |
||||||
|
*/ |
||||||
|
public class ProductNews { |
||||||
|
|
||||||
|
private long id; |
||||||
|
private String title; |
||||||
|
|
||||||
|
private Tag tag; |
||||||
|
private Target target; |
||||||
|
|
||||||
|
private Status status; |
||||||
|
private String url; |
||||||
|
private Image image; |
||||||
|
|
||||||
|
|
||||||
|
private Date pushDate; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建cid的用户 |
||||||
|
*/ |
||||||
|
private int creator; |
||||||
|
|
||||||
|
public long getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setId(long id) { |
||||||
|
this.id = id; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTitle() { |
||||||
|
return title; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setTitle(String title) { |
||||||
|
this.title = title; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Tag getTag() { |
||||||
|
return tag; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setTag(Tag tag) { |
||||||
|
this.tag = tag; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Target getTarget() { |
||||||
|
return target; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setTarget(Target target) { |
||||||
|
this.target = target; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Status getStatus() { |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setStatus(Status status) { |
||||||
|
this.status = status; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUrl() { |
||||||
|
return url; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setUrl(String url) { |
||||||
|
this.url = url; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Image getImage() { |
||||||
|
return image; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setImage(Image image) { |
||||||
|
this.image = image; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getPushDate() { |
||||||
|
return pushDate; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setPushDate(Date pushDate) { |
||||||
|
this.pushDate = pushDate; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCreator() { |
||||||
|
return creator; |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNews setCreator(int creator) { |
||||||
|
this.creator = creator; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
interface CodeParser { |
||||||
|
int getCode(); |
||||||
|
} |
||||||
|
|
||||||
|
public enum Status implements CodeParser { |
||||||
|
STOP(0), START(1); |
||||||
|
|
||||||
|
private final int code; |
||||||
|
|
||||||
|
Status(int code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public static Status parseCode(int code) { |
||||||
|
for (Status status : values()) { |
||||||
|
if (code == status.code) { |
||||||
|
return status; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public enum Tag { |
||||||
|
SOLUTION(1, Toolkit.i18nText("Fine-Design_Report_AlphaFine_Solution")), |
||||||
|
MATERIAL(2, Toolkit.i18nText("Fine-Design_Report_AlphaFine_Material")), |
||||||
|
NEW_PRODUCT(3, Toolkit.i18nText("Fine-Design_Report_AlphaFine_New_Product")); |
||||||
|
|
||||||
|
private final int code; |
||||||
|
|
||||||
|
private final String desc; |
||||||
|
|
||||||
|
Tag(int code, String desc) { |
||||||
|
this.code = code; |
||||||
|
this.desc = desc; |
||||||
|
} |
||||||
|
|
||||||
|
public static Tag parseCode(int code) { |
||||||
|
for (Tag tag :values()) { |
||||||
|
if (tag.code == code) { |
||||||
|
return tag; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDesc() { |
||||||
|
return desc; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public enum Target { |
||||||
|
ALL_USER(0); |
||||||
|
|
||||||
|
private final int code; |
||||||
|
|
||||||
|
Target(int code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public static Target parseCode(int code) { |
||||||
|
for (Target target : values()) { |
||||||
|
if (target.code == code) { |
||||||
|
return target; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,121 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.gui.icontainer.UIScrollPane; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.component.ProductNewsContentCellRender; |
||||||
|
import com.fr.design.mainframe.alphafine.component.ProductNewsList; |
||||||
|
import com.fr.design.mainframe.alphafine.exception.AlphaFineNetworkException; |
||||||
|
import com.fr.design.mainframe.alphafine.model.ProductNews; |
||||||
|
import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; |
||||||
|
import com.fr.design.utils.DesignUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.util.List; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.ImageIcon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/14 |
||||||
|
*/ |
||||||
|
public class DefaultProductNewsPane extends JPanel { |
||||||
|
|
||||||
|
|
||||||
|
private static final String LOADING = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Loading"); |
||||||
|
private static final ImageIcon LOADING_ICON = new ImageIcon(DefaultProductNewsPane.class.getResource("/com/fr/web/images/loading-local.gif")); |
||||||
|
|
||||||
|
private SwingWorker<List<ProductNews>, Void> worker; |
||||||
|
|
||||||
|
public DefaultProductNewsPane() { |
||||||
|
|
||||||
|
setLayout(new BorderLayout()); |
||||||
|
this.add(createLoadingPane()); |
||||||
|
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); |
||||||
|
this.worker = createWorker(); |
||||||
|
this.worker.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private JPanel createLoadingPane() { |
||||||
|
JPanel loadingPane = new JPanel(new BorderLayout()); |
||||||
|
UILabel loadingLabel = new UILabel(LOADING); |
||||||
|
loadingLabel.setForeground(AlphaFineConstants.MEDIUM_GRAY); |
||||||
|
loadingLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); |
||||||
|
loadingLabel.setBorder(BorderFactory.createEmptyBorder(0, 280, 0, 0)); |
||||||
|
UILabel loadingIconLabel = new UILabel(LOADING_ICON); |
||||||
|
loadingIconLabel.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); |
||||||
|
loadingPane.add(loadingIconLabel, BorderLayout.NORTH); |
||||||
|
loadingPane.add(loadingLabel, BorderLayout.CENTER); |
||||||
|
loadingPane.setBackground(Color.WHITE); |
||||||
|
return loadingPane; |
||||||
|
} |
||||||
|
|
||||||
|
private SwingWorker<List<ProductNews>, Void> createWorker() { |
||||||
|
if (this.worker != null && !this.worker.isDone()) { |
||||||
|
this.worker.cancel(true); |
||||||
|
this.worker = null; |
||||||
|
} |
||||||
|
return new SwingWorker<List<ProductNews>, Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected List<ProductNews> doInBackground() throws Exception { |
||||||
|
if (!AlphaFineHelper.isNetworkOk()) { |
||||||
|
throw new AlphaFineNetworkException(); |
||||||
|
} |
||||||
|
return ProductNewsSearchManager.getInstance().getProductNewsList(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
DefaultProductNewsPane.this.removeAll(); |
||||||
|
try { |
||||||
|
DefaultProductNewsPane.this.add(createContentPane(get())); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
if (e.getCause() instanceof AlphaFineNetworkException) { |
||||||
|
DefaultProductNewsPane.this.add(new NetWorkFailedPane(() -> { |
||||||
|
DefaultProductNewsPane.this.removeAll(); |
||||||
|
add(createLoadingPane()); |
||||||
|
refresh(); |
||||||
|
worker = createWorker(); |
||||||
|
worker.execute(); |
||||||
|
})); |
||||||
|
} |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void refresh() { |
||||||
|
this.validate(); |
||||||
|
this.repaint(); |
||||||
|
if (AlphaFineHelper.getAlphaFineDialog() != null) { |
||||||
|
AlphaFineHelper.getAlphaFineDialog().repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private UIScrollPane createContentPane(List<ProductNews> productNewsList) { |
||||||
|
DefaultListModel<ProductNews> productNewsDefaultListModel = new DefaultListModel<>(); |
||||||
|
for (ProductNews productNews : productNewsList) { |
||||||
|
productNewsDefaultListModel.addElement(productNews); |
||||||
|
} |
||||||
|
ProductNewsList productNewsJList = new ProductNewsList(productNewsDefaultListModel); |
||||||
|
productNewsJList.setBackground(Color.WHITE); |
||||||
|
productNewsJList.setCellRenderer(new ProductNewsContentCellRender(productNewsJList)); |
||||||
|
UIScrollPane scrollPane = new UIScrollPane(productNewsJList); |
||||||
|
scrollPane.setBackground(Color.WHITE); |
||||||
|
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20)); |
||||||
|
return scrollPane; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,167 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.utils.BrowseUtils; |
||||||
|
import com.fr.design.utils.DesignUtils; |
||||||
|
import com.fr.json.JSON; |
||||||
|
import com.fr.json.JSONArray; |
||||||
|
import com.fr.json.JSONFactory; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.GridLayout; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.JSeparator; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/13 |
||||||
|
*/ |
||||||
|
public class HelpDocumentNoResultPane extends JPanel { |
||||||
|
|
||||||
|
private static final String RECOMMEND = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Recommend_For_You"); |
||||||
|
|
||||||
|
private static final Color DOT_COLOR = new Color(200, 201, 205); |
||||||
|
|
||||||
|
private SwingWorker<Boolean, Void> worker; |
||||||
|
|
||||||
|
private String title; |
||||||
|
|
||||||
|
private Icon icon; |
||||||
|
|
||||||
|
private Map<String, String> linkMap; |
||||||
|
|
||||||
|
public HelpDocumentNoResultPane(String title, Icon icon) { |
||||||
|
this.title = title; |
||||||
|
this.icon = icon; |
||||||
|
this.linkMap = generateMap(); |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
worker = createWorker(); |
||||||
|
worker.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
private SwingWorker<Boolean, Void> createWorker() { |
||||||
|
if (this.worker != null && !this.worker.isDone()) { |
||||||
|
this.worker.cancel(true); |
||||||
|
this.worker = null; |
||||||
|
} |
||||||
|
return new SwingWorker<Boolean, Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Boolean doInBackground() throws Exception { |
||||||
|
return AlphaFineHelper.isNetworkOk(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
HelpDocumentNoResultPane.this.removeAll(); |
||||||
|
try { |
||||||
|
if (get()) { |
||||||
|
add(new NoResultPane(title, icon, 150), BorderLayout.CENTER); |
||||||
|
add(createRecommendPane(linkMap), BorderLayout.EAST); |
||||||
|
} else { |
||||||
|
add(new NetWorkFailedPane(() -> { |
||||||
|
worker = createWorker(); |
||||||
|
worker.execute(); |
||||||
|
})); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
refresh(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void refresh() { |
||||||
|
this.validate(); |
||||||
|
this.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private Map<String, String> generateMap() { |
||||||
|
JSONArray jsonArray = JSONFactory.createJSON(JSON.ARRAY, AlphaFineConstants.ALPHA_HELP_RECOMMEND); |
||||||
|
Map<String, String> linkMap = new LinkedHashMap<>(); |
||||||
|
for (int i = 0, len = jsonArray.size(); i < len; i++) { |
||||||
|
JSONObject json = jsonArray.getJSONObject(i); |
||||||
|
linkMap.put(json.getString("name"), json.getString("link")); |
||||||
|
} |
||||||
|
return linkMap; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createRecommendPane(Map<String, String> linkMap) { |
||||||
|
JPanel wrapRecommendPane = new JPanel(new BorderLayout()); |
||||||
|
wrapRecommendPane.setPreferredSize(new Dimension(200, 305)); |
||||||
|
JPanel recommendPane = new JPanel(); |
||||||
|
recommendPane.setLayout(new GridLayout(0, 1)); |
||||||
|
recommendPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 130, 0)); |
||||||
|
recommendPane.setBackground(Color.WHITE); |
||||||
|
recommendPane.add(new UILabel(RECOMMEND)); |
||||||
|
for (Map.Entry<String, String> entry : linkMap.entrySet()) { |
||||||
|
recommendPane.add(createListLabel(entry.getKey(), entry.getValue())); |
||||||
|
} |
||||||
|
// 分割线
|
||||||
|
JSeparator sep = new JSeparator(); |
||||||
|
sep.setOrientation(JSeparator.VERTICAL); |
||||||
|
sep.setLayout(new GridLayout(0, 1)); |
||||||
|
sep.setPreferredSize(new Dimension(1, 285)); |
||||||
|
sep.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); |
||||||
|
sep.add(new UILabel()); |
||||||
|
wrapRecommendPane.add(sep, BorderLayout.WEST); |
||||||
|
wrapRecommendPane.add(recommendPane, BorderLayout.CENTER); |
||||||
|
return wrapRecommendPane; |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createListLabel(String text, String link) { |
||||||
|
UILabel listLabel = new UILabel(String.format("%s", text)); |
||||||
|
listLabel.setForeground(UIConstants.FLESH_BLUE); |
||||||
|
listLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
listLabel.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
responseClick(link); |
||||||
|
} |
||||||
|
}); |
||||||
|
listLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
||||||
|
|
||||||
|
JPanel listPane = new JPanel(new BorderLayout()); |
||||||
|
listPane.setBackground(Color.WHITE); |
||||||
|
UILabel dotLabel = new UILabel("·"); |
||||||
|
dotLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); |
||||||
|
dotLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); |
||||||
|
dotLabel.setHorizontalAlignment(SwingConstants.LEADING); |
||||||
|
dotLabel.setForeground(DOT_COLOR); |
||||||
|
listPane.add(dotLabel, BorderLayout.WEST); |
||||||
|
listPane.add(listLabel, BorderLayout.CENTER); |
||||||
|
listPane.setPreferredSize(new Dimension(100, 20)); |
||||||
|
return listPane; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 方便记录埋点 |
||||||
|
* |
||||||
|
* @param link |
||||||
|
*/ |
||||||
|
private void responseClick(String link) { |
||||||
|
BrowseUtils.browser(link); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,167 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.CellType; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.FileModel; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.PluginModel; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import com.fr.workspace.server.exporter.LocalExportOperator; |
||||||
|
import com.fr.workspace.server.exporter.TemplateExportOperator; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.io.IOException; |
||||||
|
import java.net.URL; |
||||||
|
import java.util.concurrent.ExecutionException; |
||||||
|
import javax.imageio.ImageIO; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.ImageIcon; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/20 |
||||||
|
*/ |
||||||
|
public class LoadingRightSearchResultPane extends ResultShowPane { |
||||||
|
|
||||||
|
private SwingWorker<BufferedImage, Void> showWorker; |
||||||
|
|
||||||
|
public LoadingRightSearchResultPane() { |
||||||
|
|
||||||
|
this.setBackground(Color.WHITE); |
||||||
|
this.setPreferredSize(new Dimension(AlphaFineConstants.RIGHT_WIDTH - 1, AlphaFineConstants.CONTENT_HEIGHT)); |
||||||
|
initLoadingLabel(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void initLoadingLabel() { |
||||||
|
UILabel label = new UILabel(new ImageIcon(getClass().getResource("/com/fr/design/mainframe/alphafine/images/opening.gif"))); |
||||||
|
label.setBorder(BorderFactory.createEmptyBorder(120, 0, 0, 0)); |
||||||
|
this.add(label, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
private void showDefaultPreviewPane() { |
||||||
|
this.removeAll(); |
||||||
|
initLoadingLabel(); |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
revalidate(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void showResult(AlphaCellModel selectedValue) { |
||||||
|
showDefaultPreviewPane(); |
||||||
|
checkWorker(); |
||||||
|
if (selectedValue.getType() == CellType.FILE) { |
||||||
|
fileShowWorker(selectedValue); |
||||||
|
} |
||||||
|
|
||||||
|
if (selectedValue.getType() == CellType.PLUGIN) { |
||||||
|
pluginShowWorker(selectedValue); |
||||||
|
} |
||||||
|
this.showWorker.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
private void fileShowWorker(AlphaCellModel selectedValue) { |
||||||
|
this.showWorker = new SwingWorker<BufferedImage, Void>() { |
||||||
|
@Override |
||||||
|
protected BufferedImage doInBackground() throws Exception { |
||||||
|
final String fileName = ((FileModel) selectedValue).getFilePath().substring(ProjectConstants.REPORTLETS_NAME.length() + 1); |
||||||
|
if (fileName.endsWith(ProjectConstants.FRM_SUFFIX)) { |
||||||
|
return frmToImage(fileName); |
||||||
|
} else if (fileName.endsWith(ProjectConstants.CPT_SUFFIX)) { |
||||||
|
return cptToImage(fileName); |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
if (!isCancelled()) { |
||||||
|
LoadingRightSearchResultPane.this.removeAll(); |
||||||
|
try { |
||||||
|
LoadingRightSearchResultPane.this.add(new FilePreviewPane(get())); |
||||||
|
} catch (InterruptedException | ExecutionException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
private void pluginShowWorker(AlphaCellModel selectedValue) { |
||||||
|
this.showWorker = new SwingWorker<BufferedImage, Void>() { |
||||||
|
@Override |
||||||
|
protected BufferedImage doInBackground() { |
||||||
|
BufferedImage bufferedImage = null; |
||||||
|
try { |
||||||
|
bufferedImage = ImageIO.read(new URL(((PluginModel) selectedValue).getImageUrl())); |
||||||
|
} catch (IOException e) { |
||||||
|
try { |
||||||
|
bufferedImage = ImageIO.read(getClass().getResource("/com/fr/design/mainframe/alphafine/images/default_product.png")); |
||||||
|
} catch (IOException e1) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
return bufferedImage; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
try { |
||||||
|
if (!isCancelled()) { |
||||||
|
LoadingRightSearchResultPane.this.removeAll(); |
||||||
|
LoadingRightSearchResultPane.this.add(new PluginPreviewPane((selectedValue).getName(), get(), ((PluginModel) selectedValue).getVersion(), ((PluginModel) selectedValue).getJartime(), ((PluginModel) selectedValue).getType(), ((PluginModel) selectedValue).getPrice())); |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private BufferedImage frmToImage(String fileName) throws Exception { |
||||||
|
byte[] bytes = null; |
||||||
|
try { |
||||||
|
bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportFormAsImageData(fileName); |
||||||
|
} catch (Exception ignored) { |
||||||
|
// 兼容下老版本
|
||||||
|
bytes = new LocalExportOperator().exportFormAsImageData(fileName); |
||||||
|
} |
||||||
|
return TemplateExportOperator.byteDataToImage(bytes); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private BufferedImage cptToImage(String fileName) throws Exception { |
||||||
|
byte[] bytes = null; |
||||||
|
try { |
||||||
|
bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName); |
||||||
|
} catch (Exception ignored) { |
||||||
|
// 兼容下老版本
|
||||||
|
bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName); |
||||||
|
} |
||||||
|
return TemplateExportOperator.byteDataToImage(bytes); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void checkWorker() { |
||||||
|
if (this.showWorker != null && !this.showWorker.isDone()) { |
||||||
|
this.showWorker.cancel(true); |
||||||
|
this.showWorker = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.share.ui.base.MouseClickListener; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.FlowLayout; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/28 |
||||||
|
*/ |
||||||
|
public class NetWorkFailedPane extends JPanel { |
||||||
|
|
||||||
|
private Runnable reload; |
||||||
|
|
||||||
|
public NetWorkFailedPane() { |
||||||
|
this(() -> {}); |
||||||
|
} |
||||||
|
|
||||||
|
public NetWorkFailedPane(Runnable reload) { |
||||||
|
this.reload = reload; |
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
this.add(createInternetErrorPane()); |
||||||
|
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); |
||||||
|
this.setBackground(Color.WHITE); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createInternetErrorPane() { |
||||||
|
JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); |
||||||
|
panel.setBackground(Color.WHITE); |
||||||
|
UILabel imagePanel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/internet_error.png")); |
||||||
|
imagePanel.setBorder(BorderFactory.createEmptyBorder(50, 280, 0, 0)); |
||||||
|
panel.add(imagePanel); |
||||||
|
UILabel uiLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed")); |
||||||
|
uiLabel.setBorder(BorderFactory.createEmptyBorder(0, 300, 0, 0)); |
||||||
|
uiLabel.setForeground(Color.decode("#8F8F92")); |
||||||
|
UILabel reloadLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Online_Reload")); |
||||||
|
reloadLabel.setBorder(BorderFactory.createEmptyBorder(0, 310, 0, 0)); |
||||||
|
reloadLabel.setForeground(Color.decode("#419BF9")); |
||||||
|
reloadLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
||||||
|
reloadLabel.addMouseListener(new MouseClickListener() { |
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
reload.run(); |
||||||
|
} |
||||||
|
}); |
||||||
|
panel.add(uiLabel); |
||||||
|
panel.add(reloadLabel); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
|
||||||
|
private UILabel tipLabel(String text) { |
||||||
|
UILabel tipLabel = new UILabel(text); |
||||||
|
tipLabel.setHorizontalAlignment(SwingConstants.CENTER); |
||||||
|
return tipLabel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.dialog.link.MessageWithLink; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.utils.BrowseUtils; |
||||||
|
import com.fr.design.utils.DesignUtils; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.event.HyperlinkEvent; |
||||||
|
import javax.swing.event.HyperlinkListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* 带跳转链接的无结果面板 |
||||||
|
* |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/12 |
||||||
|
*/ |
||||||
|
public class NoResultWithLinkPane extends NoResultPane { |
||||||
|
|
||||||
|
private static final String TAG_A_START = "<a>"; |
||||||
|
private static final String TAG_A_END = "</a>"; |
||||||
|
|
||||||
|
public NoResultWithLinkPane(String title, Icon icon) { |
||||||
|
super(title, icon); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Component generateDescription(String title) { |
||||||
|
String[] para1 = title.split(TAG_A_START); |
||||||
|
String[] para2 = para1[1].split(TAG_A_END); |
||||||
|
|
||||||
|
MessageWithLink messageWithLink = new MessageWithLink(para1[0], para2[0], AlphaFineConstants.ALPHA_GO_TO_FORUM, para2[1], Color.WHITE, DesignUtils.getDefaultGUIFont().applySize(14), AlphaFineConstants.MEDIUM_GRAY) { |
||||||
|
@Override |
||||||
|
protected void initListener(String link) { |
||||||
|
|
||||||
|
addHyperlinkListener(new HyperlinkListener() { |
||||||
|
@Override |
||||||
|
public void hyperlinkUpdate(HyperlinkEvent e) { |
||||||
|
if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { |
||||||
|
jumpToForum(link); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
messageWithLink.setBorder(BorderFactory.createEmptyBorder(0, AlphaFineConstants.LEFT_WIDTH - 30, 135, 0)); |
||||||
|
return messageWithLink; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 方便记录埋点 |
||||||
|
* |
||||||
|
* @param link |
||||||
|
*/ |
||||||
|
private void jumpToForum(String link) { |
||||||
|
BrowseUtils.browser(link); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public abstract class ResultShowPane extends JPanel { |
||||||
|
|
||||||
|
public abstract void showResult(AlphaCellModel selectedValue); |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
|
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.ImageIcon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/21 |
||||||
|
*/ |
||||||
|
public class SearchLoadingPane extends JPanel { |
||||||
|
|
||||||
|
private static final ImageIcon LOADING_ICON = new ImageIcon(SearchLoadingPane.class.getResource("/com/fr/design/mainframe/alphafine/images/opening.gif")); |
||||||
|
|
||||||
|
public SearchLoadingPane() { |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
this.add(new UILabel(LOADING_ICON)); |
||||||
|
this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); |
||||||
|
this.setBackground(Color.WHITE); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.preview; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.CellType; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/20 |
||||||
|
*/ |
||||||
|
public class SimpleRightSearchResultPane extends ResultShowPane { |
||||||
|
|
||||||
|
public SimpleRightSearchResultPane(JPanel contentPane) { |
||||||
|
this.add(contentPane); |
||||||
|
this.setBackground(Color.WHITE); |
||||||
|
this.setPreferredSize(new Dimension(AlphaFineConstants.RIGHT_WIDTH - 1, AlphaFineConstants.CONTENT_HEIGHT)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void showResult(AlphaCellModel selectedValue) { |
||||||
|
if (selectedValue.getType() == CellType.DOCUMENT) { |
||||||
|
this.removeAll(); |
||||||
|
this.add(new DocumentPreviewPane((selectedValue).getName(), (selectedValue).getContent())); |
||||||
|
validate(); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.question; |
||||||
|
|
||||||
|
import com.fr.base.svg.SVGLoader; |
||||||
|
import com.fr.base.svg.SystemScaleUtils; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineUtil; |
||||||
|
import com.fr.design.utils.SvgPaintUtils; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import javax.swing.JPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/15 |
||||||
|
*/ |
||||||
|
public class QuestionPane extends JPanel { |
||||||
|
|
||||||
|
private static final Image NEW_MESSAGE_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/group_new.svg"); |
||||||
|
|
||||||
|
private static final Image QUESTION_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/group.svg"); |
||||||
|
|
||||||
|
private static final Image QUESTION_BACKGROUND_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg"); |
||||||
|
|
||||||
|
public QuestionPane() { |
||||||
|
this.setBackground(new Color(0, 0, 0, 0)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintComponent(Graphics g) { |
||||||
|
super.paintComponent(g); |
||||||
|
Graphics2D g2 = (Graphics2D) g; |
||||||
|
SvgPaintUtils.beforePaint(g2); |
||||||
|
// 宽高保持
|
||||||
|
int width = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getWidth() * SVGLoader.SYSTEM_SCALE) : getWidth(); |
||||||
|
int height = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getHeight() * SVGLoader.SYSTEM_SCALE) : getHeight(); |
||||||
|
|
||||||
|
if (AlphaFineUtil.unread() && DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isProductDynamics()) { |
||||||
|
g2.drawImage(NEW_MESSAGE_IMAGE, 0, 0, this); |
||||||
|
} else { |
||||||
|
g2.drawImage(QUESTION_BACKGROUND_IMAGE, 0, 0, this); |
||||||
|
} |
||||||
|
|
||||||
|
int imageWidth = QUESTION_IMAGE.getWidth(this); |
||||||
|
int imageHeight = QUESTION_IMAGE.getHeight(this); |
||||||
|
g2.drawImage(QUESTION_IMAGE, (width - imageWidth) / 2 - 2, (height - imageHeight) / 2 - 2,this); |
||||||
|
SvgPaintUtils.afterPaint(g2); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize() { |
||||||
|
return new Dimension(40, 40); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.question; |
||||||
|
|
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseMotionAdapter; |
||||||
|
import java.awt.event.WindowAdapter; |
||||||
|
import java.awt.event.WindowEvent; |
||||||
|
import javax.swing.JWindow; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/15 |
||||||
|
*/ |
||||||
|
public class QuestionWindow extends JWindow { |
||||||
|
|
||||||
|
private static final QuestionWindow INSTANCE = new QuestionWindow(); |
||||||
|
private final QuestionPane questionPane = new QuestionPane(); |
||||||
|
private int pressX; |
||||||
|
private int pressY; |
||||||
|
private QuestionWindow() { |
||||||
|
this.setBackground(new Color(0, 0, 0, 0)); |
||||||
|
questionPane.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
AlphaFineHelper.showAlphaFineDialog(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
pressX = e.getX(); |
||||||
|
pressY = e.getY(); |
||||||
|
} |
||||||
|
}); |
||||||
|
questionPane.addMouseMotionListener(new MouseMotionAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseDragged(MouseEvent e) { |
||||||
|
int left = getLocation().x; |
||||||
|
int top = getLocation().y; |
||||||
|
setLocation(left + e.getX() - pressX, top + e.getY() - pressY); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
DesignerContext.getDesignerFrame().addWindowListener(new WindowAdapter() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void windowActivated(WindowEvent e) { |
||||||
|
QuestionWindow.getInstance().setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void windowDeactivated(WindowEvent e) { |
||||||
|
QuestionWindow.getInstance().dispose(); |
||||||
|
QuestionWindow.getInstance().setVisible(false); |
||||||
|
} |
||||||
|
}); |
||||||
|
questionPane.setToolTipText(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Learn_More_About")); |
||||||
|
this.setContentPane(questionPane); |
||||||
|
this.setSize(new Dimension(40, 40)); |
||||||
|
// 这个地方可以设置alwaysOnTop 弹窗会跟随主页面失去激活状态而隐藏 不会与其他弹窗冲突
|
||||||
|
this.setAlwaysOnTop(true); |
||||||
|
this.setLocation(DesignerContext.getDesignerFrame().getWidth() - 100, |
||||||
|
DesignerContext.getDesignerFrame().getHeight() - 100); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setVisible(boolean visible) { |
||||||
|
if (visible && !DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
super.setVisible(visible); |
||||||
|
} |
||||||
|
|
||||||
|
public static QuestionWindow getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.search; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.CellType; |
||||||
|
import com.fr.design.mainframe.alphafine.component.AlphaFineFrame; |
||||||
|
import com.fr.design.mainframe.alphafine.component.ProductNewsSearchResultPane; |
||||||
|
import com.fr.design.mainframe.alphafine.model.ProductNews; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import java.util.List; |
||||||
|
import java.util.function.Function; |
||||||
|
import javax.swing.DefaultListModel; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/22 |
||||||
|
*/ |
||||||
|
public class ProductNewsSearchWorkerManager implements SearchManager { |
||||||
|
|
||||||
|
private final CellType cellType; |
||||||
|
|
||||||
|
private SwingWorker<DefaultListModel<ProductNews>, Void> searchWorker; |
||||||
|
|
||||||
|
private Function<SearchTextBean, List<ProductNews>> searchFunction; |
||||||
|
|
||||||
|
private ProductNewsSearchResultPane searchResultPane; |
||||||
|
|
||||||
|
private AlphaFineFrame alphaFineFrame; |
||||||
|
|
||||||
|
private volatile boolean hasSearchResult = true; |
||||||
|
|
||||||
|
private volatile boolean searchOver = false; |
||||||
|
|
||||||
|
private volatile boolean networkError = false; |
||||||
|
|
||||||
|
public ProductNewsSearchWorkerManager(CellType cellType, Function<SearchTextBean, List<ProductNews>> searchFunction, AlphaFineFrame alphaFineFrame) { |
||||||
|
this.cellType = cellType; |
||||||
|
this.searchFunction = searchFunction; |
||||||
|
this.alphaFineFrame = alphaFineFrame; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void doSearch(SearchTextBean searchTextBean) { |
||||||
|
checkSearchWork(); |
||||||
|
searchOver = false; |
||||||
|
networkError = false; |
||||||
|
if (searchResultPane != null) { |
||||||
|
alphaFineFrame.removeSearchResultPane(searchResultPane); |
||||||
|
} |
||||||
|
searchResultPane = new ProductNewsSearchResultPane(searchTextBean.getSegmentation()); |
||||||
|
alphaFineFrame.addResult(searchResultPane, cellType.getFlagStr4Result()); |
||||||
|
|
||||||
|
this.searchWorker = new SwingWorker<DefaultListModel<ProductNews>, Void>() { |
||||||
|
@Override |
||||||
|
protected DefaultListModel<ProductNews> doInBackground() throws Exception { |
||||||
|
DefaultListModel<ProductNews> productNewsDefaultListModel = new DefaultListModel<>(); |
||||||
|
if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) { |
||||||
|
networkError = true; |
||||||
|
FineLoggerFactory.getLogger().warn("alphaFine network error"); |
||||||
|
return productNewsDefaultListModel; |
||||||
|
} |
||||||
|
List<ProductNews> productNewsList = searchFunction.apply(searchTextBean); |
||||||
|
for (ProductNews productNews : productNewsList) { |
||||||
|
productNewsDefaultListModel.addElement(productNews); |
||||||
|
} |
||||||
|
return productNewsDefaultListModel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
searchOver = true; |
||||||
|
if (!isCancelled()) { |
||||||
|
try { |
||||||
|
if (networkError) { |
||||||
|
alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
DefaultListModel<ProductNews> productNewsDefaultListModel = get(); |
||||||
|
hasSearchResult = !productNewsDefaultListModel.isEmpty(); |
||||||
|
searchResultPane.getProductNewsList().setModel(get()); |
||||||
|
if (alphaFineFrame.getSelectedType() == cellType) { |
||||||
|
if (!hasSearchResult) { |
||||||
|
alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None()); |
||||||
|
return; |
||||||
|
} |
||||||
|
alphaFineFrame.showResult(cellType.getFlagStr4Result()); |
||||||
|
searchResultPane.getProductNewsList().setSelectedIndex(0); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
this.searchWorker.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
public ProductNewsSearchResultPane getSearchResultPane() { |
||||||
|
return searchResultPane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hasSearchResult() { |
||||||
|
return hasSearchResult; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isSearchOver() { |
||||||
|
return searchOver; |
||||||
|
} |
||||||
|
|
||||||
|
private void checkSearchWork() { |
||||||
|
if (this.searchWorker != null && !this.searchWorker.isDone()) { |
||||||
|
this.searchWorker.cancel(true); |
||||||
|
this.searchWorker = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isNetWorkError() { |
||||||
|
return networkError; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.search; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/17 |
||||||
|
*/ |
||||||
|
public interface SearchManager { |
||||||
|
|
||||||
|
void doSearch(SearchTextBean searchTextBean); |
||||||
|
|
||||||
|
boolean hasSearchResult(); |
||||||
|
|
||||||
|
boolean isSearchOver(); |
||||||
|
|
||||||
|
boolean isNetWorkError(); |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.search; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/17 |
||||||
|
*/ |
||||||
|
public class SearchTextBean { |
||||||
|
|
||||||
|
private String searchText; |
||||||
|
|
||||||
|
/** |
||||||
|
* 分词搜索 |
||||||
|
*/ |
||||||
|
private String[] segmentation; |
||||||
|
|
||||||
|
public SearchTextBean(String searchText, String[] segmentation) { |
||||||
|
this.searchText = searchText; |
||||||
|
this.segmentation = segmentation; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSearchText() { |
||||||
|
return searchText; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSearchText(String searchText) { |
||||||
|
this.searchText = searchText; |
||||||
|
} |
||||||
|
|
||||||
|
public String[] getSegmentation() { |
||||||
|
return segmentation; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSegmentation(String[] segmentation) { |
||||||
|
this.segmentation = segmentation; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,146 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.search; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineConstants; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.CellType; |
||||||
|
import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; |
||||||
|
import com.fr.design.mainframe.alphafine.component.AlphaFineFrame; |
||||||
|
import com.fr.design.mainframe.alphafine.component.AlphaFineList; |
||||||
|
import com.fr.design.mainframe.alphafine.component.SearchListModel; |
||||||
|
import com.fr.design.mainframe.alphafine.component.SearchResultPane; |
||||||
|
import com.fr.design.mainframe.alphafine.model.SearchResult; |
||||||
|
import com.fr.design.mainframe.alphafine.preview.ResultShowPane; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import java.util.function.Function; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author hades |
||||||
|
* @version 11.0 |
||||||
|
* Created by hades on 2022/4/16 |
||||||
|
*/ |
||||||
|
public class SearchWorkerManager implements SearchManager { |
||||||
|
|
||||||
|
private final CellType cellType; |
||||||
|
|
||||||
|
private SwingWorker<SearchListModel, Void> searchWorker; |
||||||
|
|
||||||
|
private Function<SearchTextBean, SearchResult> searchResultFunction; |
||||||
|
|
||||||
|
private SearchResultPane searchResultPane; |
||||||
|
|
||||||
|
private AlphaFineFrame alphaFineFrame; |
||||||
|
|
||||||
|
private ResultShowPane resultShowPane; |
||||||
|
|
||||||
|
private volatile boolean hasSearchResult = true; |
||||||
|
|
||||||
|
private volatile boolean searchOver = false; |
||||||
|
|
||||||
|
private volatile boolean networkError = false; |
||||||
|
|
||||||
|
public SearchWorkerManager(CellType cellType, Function<SearchTextBean, SearchResult> function, AlphaFineFrame alphaFineFrame, ResultShowPane resultShowPane) { |
||||||
|
this.cellType = cellType; |
||||||
|
this.searchResultFunction = function; |
||||||
|
this.alphaFineFrame = alphaFineFrame; |
||||||
|
this.resultShowPane = resultShowPane; |
||||||
|
} |
||||||
|
|
||||||
|
private void initSearchResult(SearchTextBean searchTextBean) { |
||||||
|
if (searchResultPane != null) { |
||||||
|
alphaFineFrame.removeSearchResultPane(searchResultPane); |
||||||
|
} |
||||||
|
searchResultPane = new SearchResultPane(searchTextBean.getSegmentation(), resultShowPane); |
||||||
|
alphaFineFrame.addResult(searchResultPane, cellType.getFlagStr4Result()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void checkSearchWork() { |
||||||
|
if (this.searchWorker != null && !this.searchWorker.isDone()) { |
||||||
|
this.searchWorker.cancel(true); |
||||||
|
this.searchWorker = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void initSearchWorker(SearchTextBean searchTextBean) { |
||||||
|
this.searchOver = false; |
||||||
|
this.networkError = false; |
||||||
|
this.searchWorker = new SwingWorker<SearchListModel, Void>() { |
||||||
|
@Override |
||||||
|
protected SearchListModel doInBackground() throws Exception { |
||||||
|
SearchListModel searchListModel = new SearchListModel(new SearchResult(), searchResultPane.getSearchResultList(), searchResultPane.getLeftSearchResultPane()); |
||||||
|
if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) { |
||||||
|
networkError = true; |
||||||
|
FineLoggerFactory.getLogger().warn("alphaFine network error"); |
||||||
|
return searchListModel; |
||||||
|
} |
||||||
|
SearchResult searchResult = searchResultFunction.apply(searchTextBean); |
||||||
|
for (AlphaCellModel object : searchResult) { |
||||||
|
AlphaFineHelper.checkCancel(); |
||||||
|
searchListModel.addElement(object); |
||||||
|
} |
||||||
|
return searchListModel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
searchOver = true; |
||||||
|
if (!isCancelled()) { |
||||||
|
try { |
||||||
|
if (networkError) { |
||||||
|
alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
SearchListModel searchListModel = get(); |
||||||
|
hasSearchResult = !searchListModel.isEmpty(); |
||||||
|
searchResultPane.getSearchResultList().setModel(get()); |
||||||
|
if (alphaFineFrame.getSelectedType() == cellType) { |
||||||
|
if (!hasSearchResult) { |
||||||
|
alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None()); |
||||||
|
return; |
||||||
|
} |
||||||
|
alphaFineFrame.showResult(cellType.getFlagStr4Result()); |
||||||
|
searchResultPane.getSearchResultList().setSelectedIndex(0); |
||||||
|
searchResultPane.getSearchResultList().requestFocus(); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doSearch(SearchTextBean searchTextBean) { |
||||||
|
initSearchResult(searchTextBean); |
||||||
|
checkSearchWork(); |
||||||
|
initSearchWorker(searchTextBean); |
||||||
|
this.searchWorker.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hasSearchResult() { |
||||||
|
return hasSearchResult; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isSearchOver() { |
||||||
|
return searchOver; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isNetWorkError() { |
||||||
|
return networkError; |
||||||
|
} |
||||||
|
|
||||||
|
@Nullable |
||||||
|
public AlphaFineList getSearchResultList() { |
||||||
|
if (searchResultPane != null) { |
||||||
|
return searchResultPane.getSearchResultList(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue