Browse Source

Merge pull request #666 in DESIGN/design from ~PLOUGH/10-design:release/10.0 to release/10.0

* commit '093635c3688fcb07d36a50e2fa87d53fe64e3c5e':
  REPORT-12850 10.0mac公式不显示=>调整代码
  REPORT-12850 10.0mac公式不显示=>FunctionConstants 重构
  REPORT-12850 10.0mac公式不显示
  REPORT-12850 10.0mac公式不显示=>公式面板简单重构
bugfix/10.0
plough 6 years ago
parent
commit
757b7a13e1
  1. 69
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  2. 305
      designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java
  3. 40
      designer-base/src/test/java/com/fr/design/formula/FunctionConstantsTest.java

69
designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

@ -63,19 +63,19 @@ import java.util.Locale;
*/
public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
protected VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
protected RSyntaxTextArea formulaTextArea;
protected UITextField keyWordTextField = new UITextField(18);
protected int currentPosition = 0;
protected int beginPosition = 0;
protected int insertPosition = 0;
protected JList tipsList;
private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
private RSyntaxTextArea formulaTextArea;
private UITextField keyWordTextField = new UITextField(18);
private int currentPosition = 0;
private int beginPosition = 0;
private int insertPosition = 0;
private JList tipsList;
protected DefaultListModel listModel = new DefaultListModel();
protected int ifHasBeenWriten = 0;
protected DefaultListModel functionTypeListModel = new DefaultListModel();
protected QuickList functionTypeList;
protected DefaultListModel functionNameModel;
protected JList functionNameList;
private int ifHasBeenWriten = 0;
private DefaultListModel functionTypeListModel = new DefaultListModel();
private QuickList functionTypeList;
private DefaultListModel functionNameModel;
private JList functionNameList;
public FormulaPane() {
initComponents();
@ -184,6 +184,18 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
protected void initComponents() {
this.setLayout(new BorderLayout(4, 4));
initTextPane();
initTipsPane();
initVariableTreeAndDescriptionArea();
}
private void initVariableTreeAndDescriptionArea() {
variableTreeAndDescriptionArea = new VariableTreeAndDescriptionArea();
this.add(variableTreeAndDescriptionArea, BorderLayout.SOUTH);
}
private void initTextPane() {
// text
JPanel textPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(textPane, BorderLayout.CENTER);
@ -199,7 +211,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
textPane.add(formulaTextAreaScrollPane, BorderLayout.CENTER);
textPane.add(checkBoxandbuttonPane, BorderLayout.SOUTH);
initTipsPane();
UIButton checkValidButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Check_Valid"));
checkValidButton.addActionListener(checkValidActionListener);
@ -209,8 +220,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
checkBoxandbuttonPane.add(checkBoxPane, BorderLayout.WEST);
checkBoxandbuttonPane.add(checkValidButton, BorderLayout.EAST);
extendCheckBoxPane(checkBoxPane);
variableTreeAndDescriptionArea = new VariableTreeAndDescriptionArea();
this.add(variableTreeAndDescriptionArea, BorderLayout.SOUTH);
}
@ -218,7 +227,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
protected void configFormulaArea() {
private void configFormulaArea() {
formulaTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_FORMULA);
formulaTextArea.setAnimateBracketMatching(true);
formulaTextArea.setAntiAliasingEnabled(true);
@ -313,7 +322,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
}
protected void fixFunctionNameList() {
private void fixFunctionNameList() {
if (tipsList.getSelectedValue() != null) {
int signOfContinue = 1;
int indexOfFunction = 0;
@ -346,7 +355,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
protected int getBeginPosition() {
private int getBeginPosition() {
int i = currentPosition;
String textArea = formulaTextArea.getText();
for (; i > 0; i--) {
@ -361,7 +370,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
return i;
}
protected void firstStepToFindTips(int theBeginPosition) {
private void firstStepToFindTips(int theBeginPosition) {
String textArea = formulaTextArea.getText();
if (currentPosition > 0 && theBeginPosition < currentPosition) {
@ -443,7 +452,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
/**
* Apply text.
*/
public void applyText(String text) {
private void applyText(String text) {
if (text == null || text.length() <= 0) {
return;
}
@ -541,7 +550,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
// check valid
protected ActionListener checkValidActionListener = new ActionListener() {
private ActionListener checkValidActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// Execute Formula default cell element.
@ -579,7 +588,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private JTree variablesTree;
private UITextArea descriptionTextArea;
public VariableTreeAndDescriptionArea() {
VariableTreeAndDescriptionArea() {
this.initComponents();
}
@ -802,13 +811,15 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initComponents() {
this.setLayout(new BorderLayout(4, 4));
// Function
initVariablesTree();
initFunctionPane();
}
private void initFunctionPane() {
JPanel functionPane = new JPanel(new BorderLayout(4, 4));
this.add(functionPane, BorderLayout.WEST);
initFunctionTypeList(functionPane);
initFunctionNameList(functionPane);
initVariablesTree();
// 选择:
functionTypeList.setSelectedIndex(0);
}
@ -959,7 +970,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private Icon icon;
private String[] subNodes = new String[0];
public TextFolderUserObject(String text, Icon icon, String[] subNodes) {
TextFolderUserObject(String text, Icon icon, String[] subNodes) {
this.text = text;
this.icon = icon;
this.subNodes = subNodes;
@ -986,11 +997,11 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public static class TextUserObject {
public TextUserObject(String text) {
TextUserObject(String text) {
this(text, text);
}
public TextUserObject(String text, String displayText) {
TextUserObject(String text, String displayText) {
this.text = text;
this.displayText = displayText;
}
@ -999,7 +1010,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
return this.text;
}
public String getDisplayText() {
String getDisplayText() {
return this.displayText;
}

305
designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java

@ -13,6 +13,7 @@ import com.fr.function.SUM;
import com.fr.function.TIME;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.ExtraClassManager;
import com.fr.stable.EncodeConstants;
import com.fr.stable.OperatingSystem;
@ -34,13 +35,75 @@ import java.util.zip.ZipFile;
import javax.swing.DefaultListModel;
public abstract class FunctionConstants {
public final class FunctionConstants {
public static FunctionGroup PLUGIN = getPluginFunctionGroup();
public static FunctionGroup CUSTOM = getCustomFunctionGroup();
static NameAndFunctionList COMMON = getCommonFunctionList();
static NameAndTypeAndFunctionList[] EMBFUNCTIONS = getEmbededFunctionListArray();
public static FunctionGroup ALL = getAllFunctionGroup();
static {
loadEmbededFunctions();
}
/**
* Don't let anyone instantiate this class.
*/
private FunctionConstants() {}
private static void loadEmbededFunctions() {
String pkgName = "com.fr.function";
Class<Function> iface = Function.class;
ClassLoader classloader = iface.getClassLoader();
Enumeration<URL> urlEnumeration = null;
try {
urlEnumeration = classloader.getResources(pkgName.replace('.', '/'));
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
return;
}
while (urlEnumeration.hasMoreElements()) {
URL url = urlEnumeration.nextElement();
String classFilePath = url.getFile();
/*
* alex:url.getFile获取的地址中,如果有空格或中文会被URLEncoder.encode处理
* 会变成%20这种%打头的东西,但是new File的时候%20是无法解析成空格,所以在此需要做URLDecoder.decode处理
*/
try {
classFilePath = URLDecoder.decode(classFilePath, EncodeConstants.ENCODING_UTF_8);
} catch (UnsupportedEncodingException e1) {
FRContext.getLogger().error(e1.getMessage(), e1);
}
FRContext.getLogger().info("ClassFilePath:" + classFilePath);
/*
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
for (String fileName : findClassNamesUnderFilePath(classFilePath)) {
try {
Class<?> cls = Class.forName(pkgName + "." + fileName.substring(0, fileName.length() - 6));
if (StableUtils.classInstanceOf(cls, iface)) {
Function inst;
inst = (Function)cls.newInstance();
for (NameAndTypeAndFunctionList EMBFUNCTION : EMBFUNCTIONS) {
if (EMBFUNCTION.test(inst)) {
break;
}
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ignore) {
}
}
}
}
/**
* 将函数分组插件中的函数添加到对应的列表中
* @param listModel
*/
public static void addFunctionGroupFromPlugins(DefaultListModel listModel){
static void addFunctionGroupFromPlugins(DefaultListModel listModel){
//hugh:自定义函数分组
Set<Mutable> containers = ExtraClassManager.getInstance().getArray(FunctionDefContainer.MARK_STRING);
if(!containers.isEmpty()){
@ -75,98 +138,6 @@ public abstract class FunctionConstants {
};
}
public static FunctionGroup PLUGIN = new FunctionGroup() {
@Override
public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Base_Formula_Plugin");
}
@Override
public NameAndDescription[] getDescriptions() {
FunctionDef[] fs = ExtraClassManager.getInstance().getFunctionDef();
int count = fs.length;
FunctionDefNAD[] nads = new FunctionDefNAD[count];
for (int i = 0; i < count; i ++) {
nads[i] = new FunctionDefNAD(fs[i]);
}
return nads;
}
};
public static FunctionGroup CUSTOM = new FunctionGroup() {
@Override
public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Custom_Function");
}
@Override
public NameAndDescription[] getDescriptions() {
FunctionConfig funtionManager = FunctionConfig.getInstance();
if (funtionManager != null) {
int functionDefCount = funtionManager.getFunctionDefCount();
FunctionDefNAD[] nads = new FunctionDefNAD[functionDefCount];
for (int i = 0; i < functionDefCount; i++) {
nads[i] = new FunctionDefNAD(funtionManager.getFunctionDef(i));
}
return nads;
}
return new NameAndDescription[0];
}
};
public static NameAndFunctionList COMMON = new NameAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Most_Recently_Used"), new Function[] {
new SUM(), new COUNT(), new AVERAGE(), new CHAR(), new DATE(), new MAX(), new MIN(), new TIME(), new RANGE()
});
public static NameAndTypeAndFunctionList[] EMBFUNCTIONS = new NameAndTypeAndFunctionList[] {
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Math_&_Trig"), Function.MATH),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Text"), Function.TEXT),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Date_&_Time"), Function.DATETIME),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Logical"), Function.LOGIC),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Array"), Function.ARRAY),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Report"), Function.REPORT),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Other"), Function.OTHER),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Function_Type_Hierarchy"), Function.HA)
};
public static FunctionGroup ALL = new FunctionGroup() {
@Override
public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_All");
}
@Override
public NameAndDescription[] getDescriptions() {
List<NameAndDescription> all = new ArrayList<NameAndDescription>();
for (int i = 0; i < EMBFUNCTIONS.length; i++) {
all.addAll(Arrays.asList(EMBFUNCTIONS[i].getDescriptions()));
}
Collections.addAll(all, PLUGIN.getDescriptions());
Collections.addAll(all, CUSTOM.getDescriptions());
//hugh:自定义函数分组
Set<Mutable> containers = ExtraClassManager.getInstance().getArray(FunctionDefContainer.MARK_STRING);
if(!containers.isEmpty()){
for(Mutable container : containers){
Collections.addAll(all,createFunctionGroup(((FunctionDefContainer)container)).getDescriptions());
}
}
java.util.Collections.sort(all, NameAndDescriptionComparator);
return all.toArray(new NameAndDescription[all.size()]);
}
};
private static Comparator<NameAndDescription> NameAndDescriptionComparator = new Comparator<NameAndDescription>() {
@Override
public int compare(NameAndDescription o1, NameAndDescription o2) {
return ComparatorUtils.compare(o1.getName(), o2.getName());
}
};
private static String[] findClassNamesUnderFilePath(String filePath) {
java.util.List<String> classNameList = new ArrayList<String>();
@ -174,7 +145,7 @@ public abstract class FunctionConstants {
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
if (filePath.indexOf("!/") >= 0) {
if (filePath.contains("!/")) {
String[] arr = filePath.split("!/");
String jarPath = arr[0].substring(6); // alex:substring(6)去掉前面的file:/这六个字符
String classPath = arr[1];
@ -197,7 +168,7 @@ public abstract class FunctionConstants {
}
String entryName = entry.getName();
if (entryName.indexOf(classPath) < 0 || !entryName.endsWith(".class")) {
if (!entryName.contains(classPath) || !entryName.endsWith(".class")) {
continue;
}
@ -208,57 +179,117 @@ public abstract class FunctionConstants {
}
} else {
File dir = new File(filePath);
for (File f : dir.listFiles()) {
String fileName = f.getName();
if (fileName.endsWith(".class")) {
classNameList.add(fileName);
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
String fileName = f.getName();
if (fileName.endsWith(".class")) {
classNameList.add(fileName);
}
}
}
}
return classNameList.toArray(new String[classNameList.size()]);
return classNameList.toArray(new String[0]);
}
// alex:读取com.fr.script.function包下面所有的Function类
static {
String pkgName = "com.fr.function";
Class<Function> iface = Function.class;
ClassLoader classloader = iface.getClassLoader();
URL url = classloader.getResource(pkgName.replace('.', '/'));
String classFilePath = url.getFile();
private static FunctionGroup getPluginFunctionGroup() {
return new FunctionGroup() {
@Override
public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Base_Formula_Plugin");
}
/*
* alex:url.getFile获取的地址中,如果有空格或中文会被URLEncoder.encode处理
* 会变成%20这种%打头的东西,但是new File的时候%20是无法解析成空格,所以在此需要做URLDecoder.decode处理
*/
try {
classFilePath = URLDecoder.decode(classFilePath, EncodeConstants.ENCODING_UTF_8);
} catch (UnsupportedEncodingException e1) {
FRContext.getLogger().error(e1.getMessage(), e1);
}
FRContext.getLogger().info("ClassFilePath:" + classFilePath);
/*
* alex:如果是jar包中的class文件
* file:/D:/opt/FineReport6.5/WebReport/WEB-INF/lib/fr-server-6.5.jar!/com/fr/rpt/script/function
*/
for (String fileName : findClassNamesUnderFilePath(classFilePath)) {
try {
Class<?> cls = Class.forName(pkgName + "." + fileName.substring(0, fileName.length() - 6));
if (StableUtils.classInstanceOf(cls, iface)) {
Function inst;
inst = (Function)cls.newInstance();
for (int fi = 0; fi < EMBFUNCTIONS.length; fi++) {
if (EMBFUNCTIONS[fi].test(inst)) {
break;
}
@Override
public NameAndDescription[] getDescriptions() {
FunctionDef[] fs = ExtraClassManager.getInstance().getFunctionDef();
int count = fs.length;
FunctionDefNAD[] nads = new FunctionDefNAD[count];
for (int i = 0; i < count; i ++) {
nads[i] = new FunctionDefNAD(fs[i]);
}
return nads;
}
};
}
private static FunctionGroup getCustomFunctionGroup() {
return new FunctionGroup() {
@Override
public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Custom_Function");
}
@Override
public NameAndDescription[] getDescriptions() {
FunctionConfig funtionManager = FunctionConfig.getInstance();
if (funtionManager != null) {
int functionDefCount = funtionManager.getFunctionDefCount();
FunctionDefNAD[] nads = new FunctionDefNAD[functionDefCount];
for (int i = 0; i < functionDefCount; i++) {
nads[i] = new FunctionDefNAD(funtionManager.getFunctionDef(i));
}
return nads;
}
} catch (ClassNotFoundException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
return new NameAndDescription[0];
}
}
};
}
private static NameAndFunctionList getCommonFunctionList() {
return new NameAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Most_Recently_Used"), new Function[] {
new SUM(), new COUNT(), new AVERAGE(), new CHAR(), new DATE(), new MAX(), new MIN(), new TIME(), new RANGE()
});
}
private static NameAndTypeAndFunctionList[] getEmbededFunctionListArray() {
return new NameAndTypeAndFunctionList[] {
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Math_&_Trig"), Function.MATH),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Text"), Function.TEXT),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Date_&_Time"), Function.DATETIME),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Logical"), Function.LOGIC),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Array"), Function.ARRAY),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Report"), Function.REPORT),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Other"), Function.OTHER),
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Function_Type_Hierarchy"), Function.HA)
};
}
private static FunctionGroup getAllFunctionGroup() {
return new FunctionGroup() {
@Override
public String getGroupName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_All");
}
@Override
public NameAndDescription[] getDescriptions() {
List<NameAndDescription> all = new ArrayList<NameAndDescription>();
for (int i = 0; i < EMBFUNCTIONS.length; i++) {
all.addAll(Arrays.asList(EMBFUNCTIONS[i].getDescriptions()));
}
Collections.addAll(all, PLUGIN.getDescriptions());
Collections.addAll(all, CUSTOM.getDescriptions());
//hugh:自定义函数分组
Set<Mutable> containers = ExtraClassManager.getInstance().getArray(FunctionDefContainer.MARK_STRING);
if(!containers.isEmpty()){
for(Mutable container : containers){
Collections.addAll(all,createFunctionGroup(((FunctionDefContainer)container)).getDescriptions());
}
}
Collections.sort(all, new Comparator<NameAndDescription>() {
@Override
public int compare(NameAndDescription o1, NameAndDescription o2) {
return ComparatorUtils.compare(o1.getName(), o2.getName());
}
});
return all.toArray(new NameAndDescription[0]);
}
};
}
}

40
designer-base/src/test/java/com/fr/design/formula/FunctionConstantsTest.java

@ -0,0 +1,40 @@
package com.fr.design.formula;
import org.junit.Test;
import static junit.framework.Assert.fail;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
/**
* Created by plough on 2018/12/7.
*/
public class FunctionConstantsTest {
@Test
public void testNewInstanceFail() throws Exception {
try {
FunctionConstants.class.newInstance();
fail("Not allowed to instantiate FunctionConstants!");
} catch (IllegalAccessException e) {
assertTrue(true);
}
}
@Test
public void testEmbedFuntionsAfterStaticInit() {
NameAndTypeAndFunctionList[] embFunctionLists = FunctionConstants.EMBFUNCTIONS;
// 一共有 8 个分类
assertEquals(8, embFunctionLists.length);
for (NameAndTypeAndFunctionList embFunctionsList : embFunctionLists) {
// 每个分类下都有函数
NameAndDescription[] nameAndDescriptions = embFunctionsList.getDescriptions();
assertTrue(nameAndDescriptions.length > 0);
}
}
@Test
public void testCommonFuntionsAfterStaticInit() {
NameAndFunctionList commonFunctionList = FunctionConstants.COMMON;
assertEquals(9, commonFunctionList.getDescriptions().length);
}
}
Loading…
Cancel
Save