帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1571 lines
64 KiB

package com.fr.design.formula;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.BaseFormula;
import com.fr.base.BaseUtils;
import com.fr.base.Parameter;
import com.fr.base.ParameterMapNameSpace;
import com.fr.base.TableDataNameSpace;
import com.fr.base.Utils;
import com.fr.base.io.IOFile;
import com.fr.data.TableDataSource;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.DialogActionListener;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent;
import com.fr.design.gui.autocomplete.CompletionCellRenderer;
import com.fr.design.gui.autocomplete.CompletionProvider;
import com.fr.design.gui.autocomplete.DefaultCompletionProvider;
import com.fr.design.gui.autocomplete.FormulaCompletion;
import com.fr.design.gui.autocomplete.FormulaPaneAutoCompletion;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.QuickList;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.parameter.ParameterInputNoneListenerPane;
import com.fr.design.parameter.ParameterInputPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.FArray;
import com.fr.log.FineLoggerFactory;
import com.fr.parser.ArrayExpression;
import com.fr.parser.BlockIntervalLiteral;
import com.fr.parser.ColumnRowRangeInPage;
import com.fr.parser.NumberLiteral;
import com.fr.parser.SheetIntervalLiteral;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.report.core.namespace.SimpleCellValueNameSpace;
import com.fr.script.Calculator;
import com.fr.script.ScriptConstants;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.stable.EncodeConstants;
import com.fr.stable.EssentialUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.parser.CRAddress;
import com.fr.stable.script.ColumnRowRange;
import com.fr.stable.script.Expression;
import com.fr.stable.script.Node;
import com.fr.stable.script.Tiny;
import com.fr.stable.script.TinyHunter;
import java.awt.Window;
import javax.swing.SwingConstants;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
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.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
/**
* 公式编辑面板
*
* @editor zhou
* @since 2012-3-29下午1:50:53
*/
@EnableMetrics
public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public static final int DEFUAL_FOMULA_LENGTH = FineUIScale.scale(103);
public static final String ELLIPSIS = "...";
public static final char KEY_CODE_A = 'A';
public static final char KEY_CODE_Z = 'z';
public static final String NEWLINE = "\n";
private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
private RSyntaxTextArea formulaTextArea;
private UITextField keyWordTextField = new UITextField(18);
private int currentPosition = 0;
private int beginPosition = 0;
private int insertPosition = 0;
protected static UICheckBox autoCompletionCheck;
protected static UICheckBox checkBeforeColse;
private JList tipsList;
private JPopupMenu popupMenu;
protected DefaultListModel listModel = new DefaultListModel();
private int ifHasBeenWriten = 0;
private DefaultListModel functionTypeListModel = new DefaultListModel();
private QuickList functionTypeList;
private DefaultListModel functionNameModel;
private JList functionNameList;
private UITableEditorPane<ParameterProvider> editor4CalPane;
private FormulaPaneAutoCompletion autoCompletion;
private DefaultCompletionProvider completionProvider;
private static final Map<String, String> PARAM_PREFIX_MAP = new HashMap<>();
public FormulaPane() {
initComponents();
}
private void initFormulaTextAreaKeyListener() {
formulaTextArea.addKeyListener(this);
formulaTextArea.addKeyListener(new KeyAdapter() {
//用来判断一下是不是组合键
@Override
public void keyTyped(KeyEvent e) {
if (inKeyCodeRange(e) && autoCompletionCheck.isSelected()) {
autoCompletion.doCompletion();
}
}
private boolean inKeyCodeRange(KeyEvent e) {
return (e.getKeyChar() >= KEY_CODE_A && e.getKeyChar() <= KEY_CODE_Z);
}
@Override
public void keyReleased(KeyEvent e) {
formulaTextArea.setForeground(Color.black);
String text = formulaTextArea.getText();
// 判断在中文输入状态是否还包含提示符 要删掉
//Tips:You_Can_Input_B1_To_Input_The_Data_Of_The_First_Row_Second_Column
String tip = "\n\n\n" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Tips");
if (text.contains(tip)) {
text = text.substring(0, text.indexOf(tip));
insertPosition = 0;
formulaTextArea.setText(text);
}
}
});
}
private void initFormulaTextAreaMouseListener() {
formulaTextArea.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
insertPosition = formulaTextArea.getCaretPosition();
if (ifHasBeenWriten == 0) {
formulaTextArea.setText("");
ifHasBeenWriten = 1;
formulaTextArea.setForeground(Color.black);
insertPosition = 0;
}
}
@Override
public void mouseReleased(MouseEvent e) {
currentPosition = formulaTextArea.getCaretPosition();
if (currentPosition == insertPosition) {
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
}
}
});
}
private void initFormulaTextArea() {
formulaTextArea = new RSyntaxTextArea();
configFormulaArea();
initFormulaTextAreaKeyListener();
initFormulaTextAreaMouseListener();
}
private void initKeyWordTextFieldKeyListener() {
keyWordTextField.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
//do nothing
}
@Override
public void keyReleased(KeyEvent e) {
//do nothing
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String toFind = keyWordTextField.getText();
search(toFind, false);
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
e.consume();
}
}
});
}
private JPanel initTipsPane() {
// tipsPane
UIButton searchButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Search"));
UILabel formulaLabel = new UILabel(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Input_Formula_In_The_Text_Area_Below") + ":", SwingConstants.LEFT);
JPanel containerSPane = row(
cell(formulaLabel),
flex(),
cell(keyWordTextField),
cell(searchButton)
).getComponent();
initKeyWordTextFieldKeyListener();
tipsList = new JList(listModel);
tipsList.addMouseListener(new DoubleClick());
searchButton.addActionListener(e -> {
String toFind = keyWordTextField.getText();
search(toFind, false);
popTips();
formulaTextArea.requestFocusInWindow();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
});
return containerSPane;
}
protected void initComponents() {
this.setLayout(new BorderLayout());
JPanel textPane = initTextPane();
JPanel tipsPane = initTipsPane();
JPanel variablePane = initVariableTreeAndDescriptionArea();
this.add(Layouts.column(LayoutConstants.VERTICAL_GAP,
cell(tipsPane),
cell(textPane).weight(1),
cell(variablePane).weight(2)
).getComponent());
refocusInWindow();
}
public void refocusInWindow() {
SwingUtilities.invokeLater(() -> formulaTextArea.requestFocusInWindow());
}
private JPanel initVariableTreeAndDescriptionArea() {
variableTreeAndDescriptionArea = new VariableTreeAndDescriptionArea();
return variableTreeAndDescriptionArea;
}
private JPanel initTextPane() {
JPanel textPane = new JPanel(new BorderLayout(0, LayoutConstants.VERTICAL_GAP));
JPanel checkBoxAndButtonPane = new JPanel(new BorderLayout());
// text
initFormulaTextArea();
UIScrollPane formulaTextAreaScrollPane = new UIScrollPane(formulaTextArea);
formulaTextAreaScrollPane.setBorder(new FineRoundBorder());
// buttonPane
JPanel buttonPane = row(8).getComponent();
UIButton checkValidButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Check_Valid"));
UIButton calButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Button"));
checkValidButton.addActionListener(checkValidActionListener);
calButton.addActionListener(calculateActionListener);
buttonPane.add(checkValidButton);
buttonPane.add(calButton);
// checkBoxPane
JPanel checkBoxPane = row(8).getComponent();
if (autoCompletionCheck == null) {
autoCompletionCheck = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_AutoCompletion"));
autoCompletionCheck.setSelected(true);
}
if (checkBeforeColse == null) {
checkBeforeColse = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Before_Closed"));
checkBeforeColse.setSelected(true);
}
checkBoxPane.add(autoCompletionCheck);
checkBoxPane.add(checkBeforeColse);
extendCheckBoxPane(checkBoxPane);
// layout
checkBoxAndButtonPane.add(checkBoxPane, BorderLayout.WEST);
checkBoxAndButtonPane.add(buttonPane, BorderLayout.EAST);
textPane.add(formulaTextAreaScrollPane, BorderLayout.CENTER);
textPane.add(checkBoxAndButtonPane, BorderLayout.SOUTH);
ParameterTableModel model = new ParameterTableModel(0);
editor4CalPane = new UITableEditorPane<>(model);
formulaTextArea.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// 获得焦点时 安装
if (autoCompletion == null && autoCompletionCheck.isSelected()) {
installAutoCompletion();
}
}
@Override
public void focusLost(FocusEvent e) {
// 失去焦点时 卸载
uninstallAutoCompletion();
}
});
return textPane;
}
private CompletionProvider createCompletionProvider() {
if (completionProvider == null) {
completionProvider = new DefaultCompletionProvider();
NameAndDescription[] nameAndDescriptions = FunctionConstants.ALL.getDescriptions();
for (NameAndDescription nameAndDescription : nameAndDescriptions) {
completionProvider.addCompletion(new FormulaCompletion(completionProvider, nameAndDescription.getName(), new LazyIcon("formula")));
}
VariableResolver variableResolver = VariableResolver.DEFAULT;
List<String> allParameters = new ArrayList<>();
allParameters.addAll(Arrays.asList(variableResolver.resolveCurReportVariables()));
allParameters.addAll(Arrays.asList(variableResolver.resolveColumnNames()));
allParameters.addAll(Arrays.asList(variableResolver.resolveGlobalParameterVariables()));
allParameters.addAll(Arrays.asList(variableResolver.resolveReportParameterVariables()));
allParameters.addAll(Arrays.asList(variableResolver.resolveTableDataParameterVariables()));
//先把参数前缀拿出来
for (String parameter : allParameters) {
String paramWithoutPre;
if (parameter.startsWith("$$")) {
paramWithoutPre = parameter.substring(2);
PARAM_PREFIX_MAP.put(paramWithoutPre, "$$");
} else if (parameter.startsWith("$")) {
paramWithoutPre = parameter.substring(1);
PARAM_PREFIX_MAP.put(paramWithoutPre, "$");
} else {
paramWithoutPre = parameter;
PARAM_PREFIX_MAP.put(paramWithoutPre, StringUtils.EMPTY);
}
completionProvider.addCompletion(new FormulaCompletion(completionProvider, paramWithoutPre, new LazyIcon("param")));
}
return completionProvider;
}
return completionProvider;
}
public static boolean containsParam(String param) {
return PARAM_PREFIX_MAP.containsKey(param);
}
public static String getParamPrefix(String param) {
return PARAM_PREFIX_MAP.getOrDefault(param, StringUtils.EMPTY);
}
private void uninstallAutoCompletion() {
if (autoCompletion != null) {
autoCompletion.uninstall();
autoCompletion = null;
}
}
private void installAutoCompletion() {
CompletionProvider provider = createCompletionProvider();
autoCompletion = new FormulaPaneAutoCompletion(provider);
autoCompletion.setListCellRenderer(new CompletionCellRenderer());
autoCompletion.install(formulaTextArea);
autoCompletion.installExtraRefreshComponent(variableTreeAndDescriptionArea);
}
protected void extendCheckBoxPane(JPanel checkBoxPane) {
// do nothing
}
private void configFormulaArea() {
formulaTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_FORMULA);
formulaTextArea.setAnimateBracketMatching(true);
formulaTextArea.setAntiAliasingEnabled(true);
formulaTextArea.setAutoIndentEnabled(true);
formulaTextArea.setCodeFoldingEnabled(true);
formulaTextArea.setUseSelectedTextColor(true);
formulaTextArea.setCloseCurlyBraces(true);
formulaTextArea.setBracketMatchingEnabled(true);
formulaTextArea.setAntiAliasingEnabled(true);
formulaTextArea.setCloseMarkupTags(true);
formulaTextArea.setLineWrap(true);
}
public class DoubleClick extends MouseAdapter {
String singlePressContent;
String doublePressContent;
@Override
public void mousePressed(MouseEvent e) {
int index = tipsList.getSelectedIndex();
if (index != -1) {
if (e.getClickCount() == 1) {
singlePressContent = (String) listModel.getElementAt(index);
} else if (e.getClickCount() == 2) {
doublePressContent = (String) listModel.getElementAt(index);
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
int index = tipsList.getSelectedIndex();
if (index != -1) {
if (e.getClickCount() == 1) {
if (ComparatorUtils.equals((String) listModel.getElementAt(index), singlePressContent)) {
singleClickActuator(singlePressContent);
}
} else if (e.getClickCount() == 2) {
if (ComparatorUtils.equals((String) listModel.getElementAt(index), doublePressContent)) {
doubleClickActuator(doublePressContent);
}
if (popupMenu != null) {
popupMenu.setVisible(false);
}
}
}
}
private void singleClickActuator(String currentLineContent) {
refreshDescriptionTextArea(currentLineContent);
formulaTextArea.requestFocusInWindow();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
}
private void doubleClickActuator(String currentLineContent) {
if (ifHasBeenWriten == 0) {
formulaTextArea.setForeground(Color.black);
formulaTextArea.setText("");
}
formulaTextArea.setForeground(Color.black);
currentPosition = formulaTextArea.getCaretPosition();
String output = currentLineContent + "()";
String textAll = formulaTextArea.getText();
String textReplaced;
int position = 0;
if (insertPosition <= currentPosition) {
textReplaced = textAll.substring(0, insertPosition) + output + textAll.substring(currentPosition);
position = insertPosition + output.length() - 1;
} else {
textReplaced = textAll.substring(0, currentPosition) + output + textAll.substring(insertPosition);
position = currentPosition + output.length() - 1;
}
formulaTextArea.setText(textReplaced);
formulaTextArea.requestFocusInWindow();
formulaTextArea.setCaretPosition(position);
insertPosition = position;
ifHasBeenWriten = 1;
listModel.removeAllElements();
}
}
@Override
public void keyPressed(KeyEvent e) {
if (ifHasBeenWriten == 0) {
this.formulaTextArea.setText(StringUtils.EMPTY);
}
}
//hugh:为啥会是10呢?搞不懂~~~
private static final int KEY_10 = 10;
//上下左右
private static final int KEY_37 = 37;
private static final int KEY_38 = 38;
private static final int KEY_39 = 39;
private static final int KEY_40 = 40;
@Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KEY_38 || key == KEY_40 || key == KEY_37 || key == KEY_39 || key == KEY_10) //如果是删除符号 ,为了可读性 没有和其他按键的程序相融合
{
listModel.removeAllElements();
currentPosition = formulaTextArea.getCaretPosition();
insertPosition = currentPosition;
beginPosition = getBeginPosition();
} else {
if (this.formulaTextArea.getText().trim().length() == 0) {
insertPosition = 0;
this.listModel.removeAllElements();
} else {
this.formulaTextArea.setForeground(Color.black);
currentPosition = formulaTextArea.getCaretPosition();
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
ifHasBeenWriten = 1;
}
}
}
private void fixFunctionNameList(String functionName) {
int signOfContinue = 1;
int indexOfFunction = 0;
boolean found = false;
for (int i = 0; i < functionTypeListModel.size(); i++) {
int signOfType = 0;
FunctionGroup functionType = (FunctionGroup) functionTypeListModel.getElementAt(i);
NameAndDescription[] nads = functionType.getDescriptions();
if (signOfContinue == 1) {
functionNameModel.removeAllElements();
for (int k = 0; k < nads.length; k++) {
functionNameModel.addElement(nads[k]);
if (functionName.equals(nads[k].getName()))//若相等,找出显示的函数的index,setSelectedIndex()
{
signOfType = 1;
signOfContinue = 0;
indexOfFunction = k;
found = true;
}
}
if (signOfType == 1) {
functionTypeList.setSelectedIndex(i);
signOfType = 0;
}
}
}
if (found) {
functionNameList.setSelectedIndex(indexOfFunction);
functionNameList.ensureIndexIsVisible(indexOfFunction);
} else {
functionTypeList.setSelectedIndex(0);
}
}
private int getBeginPosition() {
int i = currentPosition;
String textArea = formulaTextArea.getText();
for (; i > 0; i--) {
String tested = textArea.substring(i - 1, i).toUpperCase();
char[] testedChar = tested.toCharArray();
if (isChar(testedChar[0]) || isNum(testedChar[0])) {
continue;
} else {
break;
}
}
return i;
}
private void firstStepToFindTips(int theBeginPosition) {
String textArea = formulaTextArea.getText();
if (currentPosition > 0 && theBeginPosition < currentPosition) {
String next = textArea.substring(theBeginPosition, theBeginPosition + 1);
char[] nextChar = next.toCharArray();
if (!isNum(nextChar[0])) {
String toFind = textArea.substring(theBeginPosition, currentPosition);
search(toFind, false);
formulaTextArea.requestFocusInWindow();
} else {
listModel.removeAllElements();
}
} else {
String toFind = textArea.substring(theBeginPosition, currentPosition);
search(toFind, false);
formulaTextArea.requestFocusInWindow();
}
}
private static boolean isNum(char tested) {
return tested >= '0' && tested <= '9';
}
private boolean isChar(char tested) {
return tested >= 'A' && tested <= 'Z';
}
@Override
public void keyTyped(KeyEvent e) {
// do nothing
}
private void popTips() {
popupMenu = new JPopupMenu();
JScrollPane tipsScrollPane = new JScrollPane(tipsList);
popupMenu.add(tipsScrollPane);
tipsScrollPane.setPreferredSize(new Dimension(FineUIScale.scale(240), FineUIScale.scale(146)));
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
popupMenu.show(keyWordTextField, 0, 23);
}
protected void search(String keyWord, boolean findDescription) {
listModel.removeAllElements();
keyWord = removeAllSpace(keyWord);
if (keyWord.length() != 0) {
NameAndDescription[] descriptions = FunctionConstants.ALL.getDescriptions();
int lengthOfDes = descriptions.length;
List<String> list = new ArrayList<>();
for (int i = 0; i < lengthOfDes; i++) {
NameAndDescription and = descriptions[i];
String functionName = and.searchResult(keyWord, findDescription);
if (StringUtils.isNotBlank(functionName)) {
list.add(functionName);
}
}
Collections.sort(list, new SimilarComparator(keyWord));
for (String name : list) {
listModel.addElement(name);
}
if (!listModel.isEmpty()) {
tipsList.setSelectedIndex(0);
refreshDescriptionTextArea((String) listModel.getElementAt(0));
}
}
}
private void refreshDescriptionTextArea(String line) {
NameAndDescription[] descriptions = FunctionConstants.ALL.getDescriptions();
int length = descriptions.length;
for (int i = 0; i < length; i++) {
NameAndDescription function = descriptions[i];
String functionName = function.getName();
if (functionName.equals(line)) {
variableTreeAndDescriptionArea.descriptionTextArea.setText(function.getDesc());
variableTreeAndDescriptionArea.descriptionTextArea.moveCaretPosition(0);
break;
}
}
}
private String removeAllSpace(String toFind) {
int index = toFind.indexOf(" ");
while (index != -1) {
toFind = toFind.substring(0, index) + toFind.substring(index + 1);
index = toFind.indexOf(" ");
}
return toFind;
}
/**
* Apply text.
*/
private void applyText(String text) {
if (text == null || text.length() <= 0) {
return;
}
if (ifHasBeenWriten == 0) {
formulaTextArea.setForeground(Color.black);
formulaTextArea.setText("");
ifHasBeenWriten = 1;
insertPosition = 0;
}
String textAll = formulaTextArea.getText();
currentPosition = formulaTextArea.getCaretPosition();
int insert = 0;
int current = 0;
if (insertPosition <= currentPosition) {
insert = insertPosition;
current = currentPosition;
} else {
insert = currentPosition;
current = insertPosition;
}
String beforeIndexOfInsertString = textAll.substring(0, insert);
String afterIndexofInsertString = textAll.substring(current);
formulaTextArea.setText(beforeIndexOfInsertString + text + afterIndexofInsertString);
formulaTextArea.getText();
if (text.indexOf("()") != -1) {
formulaTextArea.setCaretPosition(insert + text.length() - 1);
}
formulaTextArea.requestFocus();
insertPosition = formulaTextArea.getCaretPosition();
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Formula_Definition");
}
public BasicDialog showLargeWindow(Window window, DialogActionListener l) {
int width = 900;
int height = 640;
BasicDialog basicDialog = super.showWindowWithCustomSize(window, l, FineUIScale.scale(new Dimension(width, height)));
basicDialog.setMinimumSize(FineUIScale.scale(new Dimension(width, height)));
basicDialog.setResizable(true);
return basicDialog;
}
/**
* Populate
*/
public void populate(BaseFormula formula) {
this.populate(formula, VariableResolver.DEFAULT);
}
public void populate(BaseFormula formula, VariableResolver variableResolver) {
this.variableTreeAndDescriptionArea.populate(variableResolver);
// set text
if (formula != null) {
String content = formula.getContent();
if (content.trim().equals("=")) {
this.formulaTextArea.setForeground(Color.gray);
//Tips:You_Can_Input_B1_To_Input_The_Data_Of_The_First_Row_Second_Column
this.formulaTextArea.setText("\n\n\n" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Tips"));
this.formulaTextArea.setCaretPosition(0);
ifHasBeenWriten = 0;
this.listModel.removeAllElements();
} else if (content.trim().charAt(0) == '=') {
this.formulaTextArea.setText(content.trim().substring(1));
currentPosition = formulaTextArea.getCaretPosition();
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
ifHasBeenWriten = 1;
} else {
this.formulaTextArea.setText(content);
currentPosition = formulaTextArea.getCaretPosition();
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
ifHasBeenWriten = 1;
}
}
}
/**
* update
*/
public BaseFormula update() {
BaseFormula formula;
if (ifHasBeenWriten == 0) {
formula = BaseFormula.createFormulaBuilder().build();
return formula;
} else {
String content = this.formulaTextArea.getText();
if (StringUtils.isEmpty(content) || content.trim().charAt(0) == '=') {
formula = BaseFormula.createFormulaBuilder().build(content);
} else {
formula = BaseFormula.createFormulaBuilder().build("=" + content);
}
return formula;
}
}
// check valid
private final ActionListener checkValidActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// Execute Formula default cell element.
String formulaText = formulaTextArea.getText().trim();
FormulaCheckResult checkResult = FormulaChecker.check(formulaText);
confirmCheckResult(checkResult, checkResult.getTips());
}
};
private void calculateFormula() {
String formulaText = formulaTextArea.getText().trim();
String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText);
if (unSupportFormula != null) {
showMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, false, true);
return;
}
boolean calException = false;
String messageTips;
FormulaCheckResult checkResult = FormulaChecker.check(formulaText);
if (checkResult.grammarValid()) {
messageTips = checkResult.getTips() + NEWLINE;
Map<String, Object> paramsMap = setParamsIfExist(formulaText);
Calculator calculator = Calculator.createCalculator();
ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap);
calculator.pushNameSpace(parameterMapNameSpace);
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (currentEditingTemplate != null) {
IOFile file = (IOFile) currentEditingTemplate.getTarget();
calculator.setAttribute(TableDataSource.KEY, file);
calculator.pushNameSpace(TableDataNameSpace.getInstance());
calculator.pushNameSpace(SimpleCellValueNameSpace.getInstance());
}
BaseFormula baseFormula = BaseFormula.createFormulaBuilder().build(formulaText);
Object calResult;
try {
calResult = calculator.evalValue(baseFormula);
String objectToString = EssentialUtils.objectToString(calResult);
String result = objectToString.length() > DEFUAL_FOMULA_LENGTH ?
objectToString.substring(0, DEFUAL_FOMULA_LENGTH - ELLIPSIS.length()) + ELLIPSIS : objectToString;
messageTips = messageTips + Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + result;
} catch (Exception ce) {
//模拟计算如果出现错误,则抛出错误
calResult = ce.getMessage();
calException = true;
FineLoggerFactory.getLogger().error(ce.getMessage(), ce);
messageTips = messageTips + Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Error") + ":" + calResult;
}
FineLoggerFactory.getLogger().info("value:{}", calResult);
} else {
messageTips = checkResult.getTips();
}
if (checkResult.isValid()) {
showMessageDialog(messageTips, checkResult.isValid(), calException);
} else {
confirmCheckResult(checkResult, messageTips);
}
}
private final ActionListener calculateActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
calculateFormula();
}
};
private boolean confirmCheckResult(FormulaCheckResult checkResult, String messageTips) {
if (checkResult.isValid()) {
showMessageDialog(checkResult.getTips(), checkResult.isValid(), false);
} else {
int columns = checkResult.getFormulaCoordinates().getColumns() + 1;
String position = StringUtils.EMPTY;
if (columns > 0) {
position = Toolkit.i18nText("Fine-Design_Basic_Formula_The") + columns
+ Toolkit.i18nText("Fine-Design_Basic_Formula_Error_Position") + " ";
}
int confirmDialog = FineJOptionPane.showConfirmDialog(
FormulaPane.this,
position + messageTips,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
new String[]{Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Result"), Toolkit.i18nText("Fine-Design_Basic_Formula_Continue")},
Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Result"));
if (confirmDialog == 0) {
formulaTextArea.setCaretPosition(Math.max(columns, 0));
formulaTextArea.requestFocus();
return false;
}
}
return true;
}
private void showMessageDialog(String message, boolean formulaValid, boolean calException) {
if (formulaValid && !calException) {
FineJOptionPane.showMessageDialog(
FormulaPane.this,
message);
} else {
FineJOptionPane.showMessageDialog(
FormulaPane.this,
message,
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.WARNING_MESSAGE);
}
}
private String containsUnsupportedSimulationFormulas(String formulaText) {
try {
Expression expression = Calculator.createCalculator().parse(formulaText);
UnsupportedFormulaScanner scanner = new UnsupportedFormulaScanner();
if (!scanner.travelFormula(expression.getConditionalExpression())) {
return scanner.getUnSupportFormula();
}
UnsupportedSimulationNodeHunter unsupportedSimulationFormulaHunter = new UnsupportedSimulationNodeHunter();
expression.traversal4Tiny(unsupportedSimulationFormulaHunter);
return unsupportedSimulationFormulaHunter.isSupported() ? null : unsupportedSimulationFormulaHunter.getUnSupportedNode();
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return null;
}
@Override
public boolean confirmContinueBeforeDoOK() {
if (checkBeforeColse.isSelected()) {
String formula = formulaTextArea.getText().trim();
FormulaCheckResult checkResult = FormulaChecker.check(formula);
if (!checkResult.isValid()) {
return confirmCheckResult(checkResult, checkResult.getTips());
}
}
return true;
}
private Map<String, Object> setParamsIfExist(String formulaText) {
Map<String, Object> parameterMap = new HashMap<>();
try {
Calculator calculator = Calculator.createCalculator();
Expression expression = calculator.parse(formulaText);
ParameterCellHunter parameterCellHunter = new ParameterCellHunter();
expression.traversal4Tiny(parameterCellHunter);
Parameter[] parameters = parameterCellHunter.getParameterBooty();
if (parameters.length < 1 && editor4CalPane.update().size() < 1) {
return parameterMap;
}
ParameterInputPane pPane = new ParameterInputNoneListenerPane(parameters);
pPane.showSmallWindow(new JFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
parameterMap.putAll(pPane.update());
}
}).setVisible(true);
//过滤出数组参数,如:[1,2]
for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
if (entry.getValue().toString().startsWith("[") && entry.getValue().toString().endsWith("]")) {
Expression parse = calculator.parse(entry.getValue());
ArrayExpression arrayExpression = (ArrayExpression) parse.getConditionalExpression();
Node[] arrays = arrayExpression.getArrays();
List<Object> arrayList = new ArrayList<>();
for (Node array : arrays) {
if (array instanceof NumberLiteral) {
arrayList.add(NumberFormat.getInstance().parse(array.toString()));
} else {
arrayList.add(array);
}
}
FArray<Object> fArray = new FArray<>(arrayList);
parameterMap.put(entry.getKey(), fArray);
} else if (Utils.isNumeric(entry.getValue().toString())) {
try {
Number number = NumberFormat.getInstance().parse(entry.getValue().toString());
parameterMap.put(entry.getKey(), number);
} catch (Exception e) {
FineLoggerFactory.getLogger().warn("", e);
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return parameterMap;
}
private static class ParameterCellHunter extends TinyHunter {
private final Set<Parameter> parameterList = new HashSet<>();
Parameter[] getParameterBooty() {
return parameterList.toArray(new Parameter[0]);
}
public void hunter4Tiny(Tiny tiny) {
String statement = tiny.getStatement();
if (StringUtils.isNotBlank(statement) && statement.startsWith(ScriptConstants.DETAIL_TAG)) {
if (statement.startsWith(ScriptConstants.SUMMARY_TAG)) {
parameterList.add(new Parameter(statement));
} else {
parameterList.add(new Parameter(statement.substring(1)));
}
} else if (tiny.getClass() == ColumnRowRange.class ||
tiny.getClass() == SheetIntervalLiteral.class || tiny.getClass() == BlockIntervalLiteral.class) {
parameterList.add(new Parameter(tiny.toString()));
}
}
}
private static class UnsupportedSimulationNodeHunter extends TinyHunter {
private boolean supported = true;
private String unSupportedNode;
private String[] curReportVariables;
public UnsupportedSimulationNodeHunter() {
curReportVariables = VariableResolver.DEFAULT.resolveCurReportVariables();
}
public boolean isSupported() {
return supported;
}
public String getUnSupportedNode() {
return unSupportedNode;
}
public void hunter4Tiny(Tiny tiny) {
if (tiny.getClass() == ColumnRowRangeInPage.class || tiny.getClass() == CRAddress.class
|| Arrays.asList(curReportVariables).contains(tiny.toString())) {
supported = false;
unSupportedNode = tiny.toString();
}
}
}
public class VariableTreeAndDescriptionArea extends JPanel implements AutoCompleteExtraRefreshComponent {
private JTree variablesTree;
private UITextArea descriptionTextArea;
VariableTreeAndDescriptionArea() {
this.initComponents();
}
private JPanel initFunctionTypeList() {
functionTypeList = new QuickList(functionTypeListModel);
UIScrollPane functionTypeScrollPane = new UIScrollPane(functionTypeList);
functionTypeScrollPane.setBorder(new FineRoundBorder());
functionTypeList.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
initTypeListCellRenderer();
initGroupTypeModel();
initTypeListSelectionListener();
return this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Category"), functionTypeScrollPane);
}
private void initTypeListCellRenderer() {
functionTypeList.setCellRenderer(
new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof FunctionGroup) {
this.setText(((FunctionGroup) value).getGroupName());
}
return this;
}
});
}
private void initTypeListSelectionListener() {
functionTypeList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
Object selectedValue = ((JList) evt.getSource()).getSelectedValue();
if (!(selectedValue instanceof FunctionGroup)) {
return;
}
NameAndDescription[] nads = ((FunctionGroup) selectedValue).getDescriptions();
functionNameModel = (DefaultListModel) functionNameList.getModel();
functionNameModel.clear();
for (NameAndDescription nad : nads) {
functionNameModel.addElement(nad);
}
if (functionNameModel.size() > 0) {
functionNameList.setSelectedIndex(0);
functionNameList.ensureIndexIsVisible(0);
}
}
});
}
private void initGroupTypeModel() {
functionTypeListModel.addElement(FunctionConstants.COMMON);
functionTypeListModel.addElement(FunctionConstants.NEW);
for (int i = 0; i < FunctionConstants.EMBFUNCTIONS.length; i++) {
functionTypeListModel.addElement(FunctionConstants.EMBFUNCTIONS[i]);
}
functionTypeListModel.addElement(FunctionConstants.ALL);
functionTypeListModel.addElement(FunctionConstants.CUSTOM);
functionTypeListModel.addElement(FunctionConstants.PLUGIN);
//hugh: 从函数分组插件中添加分组
FunctionConstants.addFunctionGroupFromPlugins(functionTypeListModel);
}
private void initFunctionNameListCellRenderer() {
functionNameList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof NameAndDescription) {
this.setText(((NameAndDescription) value).getName());
}
return this;
}
});
}
private void initFunctionNameListSelectionListener() {
functionNameList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
Object selectedValue = functionNameList.getSelectedValue();
if (!(selectedValue instanceof NameAndDescription)) {
return;
}
String description = ((NameAndDescription) selectedValue).getDesc();
descriptionTextArea.setText(description);
setTextAreaText(description);
descriptionTextArea.moveCaretPosition(0);
}
});
}
private void initFunctionNameListMouseListener() {
functionNameList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() >= 2) {
Object selectedValue = functionNameList.getSelectedValue();
if (!(selectedValue instanceof NameAndDescription)) {
return;
}
String insert = ((NameAndDescription) selectedValue).getName() + "()";
applyText(insert);
}
if (SwingUtilities.isRightMouseButton(evt)) {
JPopupMenu popupMenu = new JPopupMenu();
LookDetailAction lookDetailAction = new LookDetailAction();
popupMenu.add(lookDetailAction);
// peter: 只有弹出菜单有子菜单的时候,才需要弹出来.
GUICoreUtils.showPopupMenu(popupMenu, functionNameList, evt.getX() - 1, evt.getY() - 1);
}
}
});
}
private JPanel initFunctionNameList() {
functionNameList = new JList(new DefaultListModel());
UIScrollPane functionNameScrollPane = new UIScrollPane(functionNameList);
functionNameScrollPane.setBorder(new FineRoundBorder());
functionNameList.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
initFunctionNameListCellRenderer();
initFunctionNameListSelectionListener();
initFunctionNameListMouseListener();
return this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Name"), functionNameScrollPane);
}
private void initDescriptionTextArea() {
// Description
descriptionTextArea = new UITextArea();
descriptionTextArea.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setWrapStyleWord(true);
descriptionTextArea.setEditable(false);
descriptionTextArea.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() >= 2) {
showPopupPane();
}
}
});
}
private StringBuilder getText(TextUserObject selectedValue, String path) throws IOException {
Reader desReader;
StringBuilder desBuf = new StringBuilder();
InputStream desInputStream = BaseUtils.readResource(path + ((TextUserObject) selectedValue).displayText + ".txt");
if (desInputStream == null) {
String description = "";
desReader = new StringReader(description);
} else {
desReader = new InputStreamReader(desInputStream, EncodeConstants.ENCODING_UTF_8);
}
BufferedReader reader = new BufferedReader(desReader);
String lineText;
while ((lineText = reader.readLine()) != null) {
if (desBuf.length() > 0) {
desBuf.append('\n');
}
desBuf.append(lineText);
}
reader.close();
desReader.close();
return desBuf;
}
private void initVariablesTreeSelectionListener() {
variablesTree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) variablesTree.getLastSelectedPathComponent();
Object selectedValue = selectedTreeNode.getUserObject();
Object selectedParentValue = ((DefaultMutableTreeNode) selectedTreeNode.getParent()).getUserObject();
if (selectedValue == null) {
return;
}
if (selectedValue instanceof TextUserObject) {
//有公式说明的条件:1.属于TextUserObject 2.parent是系统参数
if (ComparatorUtils.equals(((TextFolderUserObject) selectedParentValue).getText(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables"))) {
descriptionTextArea.setText(com.fr.design.i18n.Toolkit.i18nText(FormulaConstants.getValueByKey(((TextUserObject) selectedValue).getText())));
} else {
descriptionTextArea.setText(StringUtils.EMPTY);
}
} else if (selectedValue instanceof TextFolderUserObject) {
descriptionTextArea.setText(StringUtils.EMPTY);
}
descriptionTextArea.moveCaretPosition(0);
}
});
}
private JPanel initVariablesTree() {
// variable
variablesTree = new JTree();
UIScrollPane variablesTreePane = new UIScrollPane(variablesTree);
variablesTreePane.setBorder(new FineRoundBorder());
variablesTree.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
variablesTree.setRootVisible(false);
variablesTree.setShowsRootHandles(true);
variablesTree.addMouseListener(applyTextMouseListener);
variablesTree.setCellRenderer(applyTreeCellRenderer);
initDescriptionTextArea();
UIScrollPane desScrollPane = new UIScrollPane(descriptionTextArea);
desScrollPane.setBorder(null);
initVariablesTreeSelectionListener();
return Layouts.row(LayoutConstants.HORIZONTAL_GAP,
cell(this.createNamePane(
Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables"), variablesTreePane)
).weight(1),
cell(this.createNamePane(
Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Formula_Description"), desScrollPane)
).weight(1)
).getComponent();
}
private void initComponents() {
this.setLayout(new BorderLayout());
JPanel variablesTreePane = initVariablesTree();
JPanel functionPane = initFunctionPane();
this.add(Layouts.row(LayoutConstants.HORIZONTAL_GAP,
cell(functionPane).weight(1),
cell(variablesTreePane).weight(2)
).getComponent());
}
private JPanel initFunctionPane() {
JPanel functionTypePane = initFunctionTypeList();
JPanel functionNamePane = initFunctionNameList();
functionTypeList.setSelectedIndex(0);
return Layouts.row(LayoutConstants.HORIZONTAL_GAP,
cell(functionTypePane).weight(1), cell(functionNamePane).weight(1)
).getComponent();
}
@Override
public void refresh(String replacementText) {
refreshText(replacementText);
}
/*
* 查看函数的详细信息
*/
private class LookDetailAction extends UpdateAction {
public LookDetailAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Function_Detail"));
this.setMnemonic('L');
this.setSmallIcon(new LazyIcon("preview"));
}
// 弹出的窗口中显示函数的用法明细
public void actionPerformed(ActionEvent evt) {
showPopupPane();
}
}
private void showPopupPane() {
BasicPane basicPane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Function_Detail");
}
};
basicPane.setLayout(FRGUIPaneFactory.createBorderLayout());
UITextArea desArea = new UITextArea();
desArea.setText(this.getTextAreaText());
basicPane.add(new UIScrollPane(desArea), BorderLayout.CENTER);
BasicDialog dialog = basicPane.showWindow(DesignerContext.getDesignerFrame());
dialog.setVisible(true);
}
private String getTextAreaText() {
return this.descriptionTextArea.getText();
}
private void setTextAreaText(String text) {
this.descriptionTextArea.setText(text);
}
private JPanel createNamePane(String name, JComponent comp) {
JPanel namePane = new JPanel(new BorderLayout(0, 4));
UILabel label = new UILabel(name);
FineUIStyle.setStyle(label, FineUIStyle.LABEL_BOLD);
namePane.add(label, BorderLayout.NORTH);
namePane.add(comp, BorderLayout.CENTER);
return namePane;
}
private MouseListener applyTextMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() >= 2) {
Object source = evt.getSource();
if (source instanceof JTree) {
JTree tree = (JTree) source;
TreePath selectedTreePah = tree.getSelectionPath();
if (selectedTreePah != null) {
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) selectedTreePah.getLastPathComponent();
Object userObject = selectedTreeNode.getUserObject();
if (userObject != null && userObject instanceof TextUserObject) {
applyText(((TextUserObject) userObject).getText());
}
}
}
}
}
};
private DefaultTreeCellRenderer applyTreeCellRenderer = new DefaultTreeCellRenderer() {
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, selected,
expanded, leaf, row, hasFocus);
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
Object userObj = treeNode.getUserObject();
if (userObj instanceof TextUserObject) {
this.setIcon(null);
this.setText(((TextUserObject) userObj).getDisplayText());
} else if (userObj instanceof TextFolderUserObject) {
TextFolderUserObject textUserObject = (TextFolderUserObject) userObj;
if (leaf) {
this.setText(textUserObject.getText());
} else {
this.setText(textUserObject.getText() + " - ["
+ treeNode.getChildCount() + "]");
}
this.setIcon(textUserObject.getIcon());
}
return this;
}
};
public void refreshText(String line) {
fixFunctionNameList(line);
refreshDescriptionTextArea(line);
}
public void populate(VariableResolver variableResolver) {
// varibale tree.
DefaultTreeModel variableModel = (DefaultTreeModel) variablesTree.getModel();
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) variableModel.getRoot();
rootNode.removeAllChildren();
if (variableResolver.isBindCell()) {
// 加上当前值"$$$"
DefaultMutableTreeNode bindCellNode = new DefaultMutableTreeNode(new TextUserObject("$$$"));
rootNode.add(bindCellNode);
}
// todo: 缺一些icon
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Data_Fields"),
BaseUtils.readIcon("/com/fr/design/images/dialog/table.png"),
variableResolver.resolveColumnNames()).createMutableTreeNode());
// Set cutReport Variable
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables"),
BaseUtils.readIcon("/com/fr/design/images/dialog/variable.png"),
variableResolver.resolveCurReportVariables()).createMutableTreeNode());
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter_Source_Type_Tabledata"),
BaseUtils.readIcon("/com/fr/design/images/dialog/parameter.gif"),
variableResolver.resolveTableDataParameterVariables()).createMutableTreeNode());
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_ParameterD_Report_Parameter"),
new LazyIcon("param"),
variableResolver.resolveReportParameterVariables()).createMutableTreeNode());
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Server_Global_Parameters"),
BaseUtils.readIcon("/com/fr/design/images/dialog/parameter.gif"),
variableResolver.resolveGlobalParameterVariables()).createMutableTreeNode());
variableModel.reload();
// Expand
for (int row = 0; row < this.variablesTree.getRowCount(); row++) {
this.variablesTree.expandRow(row);
}
}
}
public static class SimilarComparator implements Comparator<String> {
private String searchKey;
public SimilarComparator(String searchKey) {
this.searchKey = searchKey.toLowerCase();
}
/**
* 把以关键词开头的和不以关键词开头的分别按照字母表顺序排序
*
* @param o1 待比较对象1
* @param o2 待比较对象2
* @return 比较结果,1表示 o1 > o2, -1表示 o1 < o2, 0表示 o1 = o2
*/
@Override
public int compare(String o1, String o2) {
int result;
boolean o1StartWith = o1.toLowerCase().startsWith(searchKey);
boolean o2StartWith = o2.toLowerCase().startsWith(searchKey);
if (o1StartWith) {
result = o2StartWith ? o1.compareTo(o2) : -1;
} else {
result = o2StartWith ? 1 : o1.compareTo(o2);
}
return result;
}
}
public static class TextFolderUserObject {
private String text;
private Icon icon;
private String[] subNodes = new String[0];
TextFolderUserObject(String text, Icon icon, String[] subNodes) {
this.text = text;
this.icon = icon;
this.subNodes = subNodes;
}
public String getText() {
return this.text;
}
public Icon getIcon() {
return this.icon;
}
MutableTreeNode createMutableTreeNode() {
DefaultMutableTreeNode variableTreeNode = new DefaultMutableTreeNode(this);
for (String subNode : subNodes) {
variableTreeNode.add(new DefaultMutableTreeNode(new TextUserObject(subNode)));
}
return variableTreeNode;
}
}
public static class TextUserObject {
TextUserObject(String text) {
this(text, text);
}
TextUserObject(String text, String displayText) {
this.text = text;
this.displayText = displayText;
}
public String getText() {
return this.text;
}
String getDisplayText() {
return this.displayText;
}
private String text;
private String displayText;
}
public static void main(String[] args) {
FunctionGroup group = FunctionConstants.ALL;
NameAndDescription[] nameAndDescriptions = group.getDescriptions();
StringBuffer buffer = new StringBuffer();
for (NameAndDescription d : nameAndDescriptions) {
String name = d.getName();
buffer.append("\"");
buffer.append(name.toUpperCase());
buffer.append("\"");
buffer.append("|");
buffer.append(NEWLINE);
buffer.append("\"");
buffer.append(name.toLowerCase());
buffer.append("\"");
buffer.append("|");
buffer.append(NEWLINE);
}
FineLoggerFactory.getLogger().debug(buffer.toString());
}
}