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.
992 lines
38 KiB
992 lines
38 KiB
package com.fr.design.javascript; |
|
|
|
import com.fr.base.svg.IconUtils; |
|
import com.fr.design.border.UIRoundedBorder; |
|
import com.fr.design.constants.UIConstants; |
|
import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent; |
|
import com.fr.design.gui.autocomplete.BasicCompletion; |
|
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.JSImplPaneAutoCompletion; |
|
import com.fr.design.gui.ibutton.UIButton; |
|
import com.fr.design.gui.icontainer.UIScrollPane; |
|
import com.fr.design.gui.ilable.UILabel; |
|
import com.fr.design.gui.itextarea.UITextArea; |
|
import com.fr.design.gui.itextfield.PlaceholderTextField; |
|
import com.fr.design.i18n.LocaleLinkProvider; |
|
import com.fr.design.i18n.Toolkit; |
|
import com.fr.design.javascript.jsapi.JSAPITreeHelper; |
|
import com.fr.design.javascript.jsapi.JSAPIUserObject; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.general.ComparatorUtils; |
|
import com.fr.general.GeneralContext; |
|
import com.fr.general.http.HttpToolbox; |
|
import com.fr.json.JSONArray; |
|
import com.fr.json.JSONException; |
|
import com.fr.json.JSONObject; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.stable.StringUtils; |
|
|
|
import javax.swing.BorderFactory; |
|
import javax.swing.DefaultListCellRenderer; |
|
import javax.swing.DefaultListModel; |
|
import javax.swing.JComponent; |
|
import javax.swing.JLabel; |
|
import javax.swing.JList; |
|
import javax.swing.JPanel; |
|
import javax.swing.JPopupMenu; |
|
import javax.swing.JScrollPane; |
|
import javax.swing.JTree; |
|
import javax.swing.SwingWorker; |
|
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.TreeNode; |
|
import javax.swing.tree.TreePath; |
|
import java.awt.BorderLayout; |
|
import java.awt.CardLayout; |
|
import java.awt.Color; |
|
import java.awt.Component; |
|
import java.awt.Cursor; |
|
import java.awt.Desktop; |
|
import java.awt.Dimension; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.FocusAdapter; |
|
import java.awt.event.FocusEvent; |
|
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.IOException; |
|
import java.net.URI; |
|
import java.net.URISyntaxException; |
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.Comparator; |
|
import java.util.List; |
|
import java.util.concurrent.ExecutionException; |
|
|
|
public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener { |
|
|
|
//搜索关键词输入框 |
|
private PlaceholderTextField keyWordTextField = new PlaceholderTextField(16); |
|
//搜索出的提示列表 |
|
private JList tipsList; |
|
private DefaultListModel tipsListModel = new DefaultListModel(); |
|
|
|
private JList interfaceNameList; |
|
private DefaultListModel interfaceNameModel; |
|
|
|
private JTree moduleTree; |
|
|
|
private DefaultCompletionProvider completionProvider; |
|
private JSImplPaneAutoCompletion autoCompletion; |
|
|
|
//函数说明文本框 |
|
private UITextArea descriptionTextArea; |
|
|
|
private JPopupMenu popupMenu; |
|
|
|
private JPanel endBracketsPanel; |
|
private JLabel warningLabel; |
|
|
|
private InterfaceAndDescriptionPanel interfaceAndDescriptionPanel; |
|
private JList helpDOCList; |
|
|
|
private int ifHasBeenWriten = 0; |
|
private int currentPosition = 0; |
|
private int beginPosition = 0; |
|
private int insertPosition = 0; |
|
private static final String SEPARATOR = "_"; |
|
|
|
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; |
|
|
|
private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com"; |
|
|
|
private static final String DOCUMENT_SEARCH_URL = "https://help.fanruan.com/finereport/api-helpdoc-title-"; |
|
|
|
private String currentValue; |
|
|
|
private static CardLayout card; |
|
|
|
private static final String RELOAD_CARD = "reloadCard"; |
|
private static final String DOC_LIST_CARD = "docListCard"; |
|
|
|
/** |
|
* 云中心Js高级编辑器帮助链接前缀在配置文件中对应的配置文件key |
|
*/ |
|
private static final String PROPS_LINK_KEY = "Fine-Design-CloudCenter_Js_Editor"; |
|
|
|
/** |
|
* 云中心Js高级编辑器帮助链接前缀在配置文件中对应的配置文件key |
|
*/ |
|
private static final String PROPS_LINK_KEY_DEFAULT = "Fine-Design-CloudCenter_Js_Editor_Default"; |
|
public JSContentWithDescriptionPane(String[] args) { |
|
this.setLayout(new BorderLayout()); |
|
//=============================== |
|
this.initFunctionTitle(args); |
|
JPanel jsParaAndSearchPane = new JPanel(new BorderLayout()); |
|
|
|
//js函数声明面板 |
|
JPanel jsParaPane = createJSParaPane(); |
|
|
|
jsParaPane.setPreferredSize(new Dimension(650, 80)); |
|
//右上角的搜索提示面板 |
|
JPanel tipsPane = createTipsPane(); |
|
|
|
jsParaAndSearchPane.add(jsParaPane, BorderLayout.CENTER); |
|
jsParaAndSearchPane.add(tipsPane, BorderLayout.EAST); |
|
|
|
initPopTips(); |
|
|
|
//js文本编辑面板 |
|
UIScrollPane contentTextAreaPanel = createContentTextAreaPanel(); |
|
initContextAreaListener(); |
|
|
|
contentTextAreaPanel.setPreferredSize(new Dimension(850, 250)); |
|
//js函数结束标签 |
|
UILabel endBracketsLabel = new UILabel(); |
|
endBracketsLabel.setText("}"); |
|
|
|
//结尾括号和复用函数按钮面板 |
|
endBracketsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
if (isNeedContentWarning()) { |
|
warningLabel = initWarningLabel(); |
|
endBracketsPanel.add(endBracketsLabel, BorderLayout.NORTH); |
|
} else { |
|
endBracketsPanel.add(endBracketsLabel, BorderLayout.WEST); |
|
} |
|
|
|
JPanel northPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
northPanel.add(jsParaAndSearchPane, BorderLayout.NORTH); |
|
|
|
northPanel.add(contentTextAreaPanel, BorderLayout.CENTER); |
|
northPanel.add(endBracketsPanel, BorderLayout.SOUTH); |
|
|
|
//主编辑框,也就是面板的正中间部分 |
|
this.add(northPanel, BorderLayout.CENTER); |
|
|
|
//函数分类和函数说明面板================================== |
|
JPanel functionNameAndDescriptionPanel = createInterfaceAndDescriptionPanel(); |
|
functionNameAndDescriptionPanel.setPreferredSize(new Dimension(880, 220)); |
|
|
|
this.add(functionNameAndDescriptionPanel, BorderLayout.SOUTH); |
|
} |
|
|
|
protected void updateWarningTip(String tip) { |
|
if (!StringUtils.equals(warningLabel.getText(), tip)) { |
|
warningLabel.setText(tip); |
|
} |
|
} |
|
|
|
@Override |
|
protected void removeWarningLabel() { |
|
endBracketsPanel.remove(warningLabel); |
|
endBracketsPanel.revalidate(); |
|
} |
|
|
|
@Override |
|
protected void addWarningLabel() { |
|
endBracketsPanel.add(warningLabel, BorderLayout.SOUTH); |
|
endBracketsPanel.revalidate(); |
|
} |
|
|
|
public void populate(String js) { |
|
contentTextArea.setText(js); |
|
ifHasBeenWriten = 1; |
|
currentPosition = contentTextArea.getCaretPosition(); |
|
beginPosition = getBeginPosition(); |
|
insertPosition = beginPosition; |
|
} |
|
|
|
private void initContextAreaListener() { |
|
contentTextArea.addKeyListener(new KeyAdapter() { |
|
@Override |
|
public void keyTyped(KeyEvent e) { |
|
if ((e.getKeyChar() >= 'A' && e.getKeyChar() <= 'z') || e.getKeyChar() == '_') { |
|
if (autoCompletion != null) { |
|
autoCompletion.doCompletion(); |
|
} |
|
} |
|
} |
|
|
|
@Override |
|
public void keyReleased(KeyEvent e) { |
|
contentTextArea.setForeground(Color.black); |
|
} |
|
}); |
|
contentTextArea.addKeyListener(this); |
|
contentTextArea.addFocusListener(new FocusAdapter() { |
|
@Override |
|
public void focusGained(FocusEvent e) { |
|
if (autoCompletion == null) { |
|
installAutoCompletion(); |
|
} |
|
} |
|
|
|
@Override |
|
public void focusLost(FocusEvent e) { |
|
uninstallAutoCompletion(); |
|
} |
|
}); |
|
contentTextArea.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
insertPosition = contentTextArea.getCaretPosition(); |
|
if (ifHasBeenWriten == 0) { |
|
contentTextArea.setText(StringUtils.EMPTY); |
|
ifHasBeenWriten = 1; |
|
contentTextArea.setForeground(Color.black); |
|
insertPosition = 0; |
|
} |
|
} |
|
|
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
currentPosition = contentTextArea.getCaretPosition(); |
|
if (currentPosition == insertPosition) { |
|
beginPosition = getBeginPosition(); |
|
insertPosition = beginPosition; |
|
} |
|
} |
|
}); |
|
} |
|
|
|
@Override |
|
public void keyTyped(KeyEvent e) { |
|
|
|
} |
|
|
|
@Override |
|
public void keyPressed(KeyEvent e) { |
|
if (ifHasBeenWriten == 0) { |
|
this.contentTextArea.setText(StringUtils.EMPTY); |
|
} |
|
} |
|
|
|
@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) //如果是删除符号 ,为了可读性 没有和其他按键的程序相融合 |
|
{ |
|
currentPosition = contentTextArea.getCaretPosition(); |
|
insertPosition = currentPosition; |
|
beginPosition = getBeginPosition(); |
|
} else { |
|
if (contentTextArea.getText().trim().length() == 0) { |
|
insertPosition = 0; |
|
} else { |
|
contentTextArea.setForeground(Color.black); |
|
currentPosition = contentTextArea.getCaretPosition(); |
|
beginPosition = getBeginPosition(); |
|
insertPosition = beginPosition; |
|
ifHasBeenWriten = 1; |
|
} |
|
} |
|
} |
|
|
|
private int getBeginPosition() { |
|
int i = currentPosition; |
|
String textArea = contentTextArea.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 static boolean isNum(char tested) { |
|
return tested >= '0' && tested <= '9'; |
|
} |
|
|
|
private boolean isChar(char tested) { |
|
return tested >= 'A' && tested <= 'Z' || tested >= 'a' && tested < 'z'; |
|
} |
|
|
|
public class InterfaceAndDescriptionPanel extends JPanel implements AutoCompleteExtraRefreshComponent { |
|
@Override |
|
public void refresh(String replacementText) { |
|
fixInterfaceNameList(replacementText); |
|
} |
|
} |
|
|
|
private void fixInterfaceNameList(String interfaceName) { |
|
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) moduleTree.getModel(); |
|
TreeNode root = (TreeNode) defaultTreeModel.getRoot(); |
|
String directCategory = JSAPITreeHelper.getDirectCategory(interfaceName); |
|
if (directCategory == null) { |
|
return; |
|
} |
|
setModuleTreeSelection(root, directCategory, defaultTreeModel); |
|
interfaceNameModel = (DefaultListModel) interfaceNameList.getModel(); |
|
interfaceNameModel.clear(); |
|
List<String> interfaceNames = JSAPITreeHelper.getNames(directCategory); |
|
int index = 0; |
|
for (int i = 0; i < interfaceNames.size(); i++) { |
|
interfaceNameModel.addElement(interfaceNames.get(i)); |
|
if (StringUtils.equals(interfaceNames.get(i), interfaceName)) { |
|
index = i; |
|
} |
|
} |
|
interfaceNameList.setSelectedIndex(index); |
|
interfaceNameList.ensureIndexIsVisible(index); |
|
} |
|
|
|
private boolean setModuleTreeSelection(TreeNode node, String directCategory, DefaultTreeModel treeModel) { |
|
|
|
DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) node; |
|
Object userObject = defaultMutableTreeNode.getUserObject(); |
|
if (userObject instanceof JSAPIUserObject) { |
|
String value = ((JSAPIUserObject) userObject).getValue(); |
|
if (StringUtils.equals(value, directCategory)) { |
|
moduleTree.setSelectionPath(new TreePath(treeModel.getPathToRoot(node))); |
|
moduleTree.scrollPathToVisible(moduleTree.getSelectionPath()); |
|
return true; |
|
} |
|
} |
|
for (int i = 0; i < node.getChildCount(); i++) { |
|
if (setModuleTreeSelection(node.getChildAt(i), directCategory, treeModel)) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
private JPanel createInterfaceAndDescriptionPanel() { |
|
interfaceAndDescriptionPanel = new InterfaceAndDescriptionPanel(); |
|
interfaceAndDescriptionPanel.setLayout(new BorderLayout(4, 4)); |
|
JPanel interfacePanel = new JPanel(new BorderLayout(4, 4)); |
|
interfaceAndDescriptionPanel.add(interfacePanel, BorderLayout.WEST); |
|
JPanel descriptionAndDocumentPanel = new JPanel(new BorderLayout(4, 4)); |
|
//函数说明和帮助文档框 |
|
initDescriptionArea(descriptionAndDocumentPanel); |
|
|
|
//模块和接口面板 |
|
initInterfaceModuleTree(interfacePanel); |
|
initInterfaceNameList(interfacePanel); |
|
|
|
initHelpDocumentPane(descriptionAndDocumentPanel); |
|
|
|
interfaceAndDescriptionPanel.add(descriptionAndDocumentPanel, BorderLayout.CENTER); |
|
return interfaceAndDescriptionPanel; |
|
} |
|
|
|
private void doHelpDocumentSearch() { |
|
Object value = interfaceNameList.getSelectedValue(); |
|
if (value != null) { |
|
new SwingWorker<List<HelpDocument>, Void>() { |
|
@Override |
|
protected List<HelpDocument> doInBackground() { |
|
List<HelpDocument> helpDocuments = new ArrayList<>(); |
|
updateHelpDocuments(value, helpDocuments); |
|
return helpDocuments; |
|
} |
|
|
|
@Override |
|
protected void done() { |
|
try { |
|
List<HelpDocument> helpDocuments = get(); |
|
DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel(); |
|
helpDOCModel.clear(); |
|
for (HelpDocument helpDocument : helpDocuments) { |
|
helpDOCModel.addElement(helpDocument); |
|
} |
|
} catch (InterruptedException | ExecutionException e) { |
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
} |
|
} |
|
|
|
}.execute(); |
|
} |
|
} |
|
|
|
private void updateHelpDocuments(Object value, List<HelpDocument> helpDocuments) { |
|
String url = LocaleLinkProvider.getInstance().getLink(PROPS_LINK_KEY, PROPS_LINK_KEY_DEFAULT) + value.toString(); |
|
try { |
|
JSONArray jsonArray = null; |
|
//目前简中繁中之外的语言高级编辑器功能及文档不完善,右侧展示的文档链接列表暂时为空白 |
|
if(GeneralContext.isChineseEnv()) { |
|
String result = HttpToolbox.get(url); |
|
JSONObject jsonObject = new JSONObject(result); |
|
jsonArray = jsonObject.optJSONArray("list"); |
|
} |
|
if (jsonArray != null) { |
|
for (int i = 0; i < jsonArray.length(); i++) { |
|
JSONObject resultJSONObject = jsonArray.optJSONObject(i); |
|
String docURL = resultJSONObject.optString("url"); |
|
String name = resultJSONObject.optString("title").trim(); |
|
HelpDocument helpDocument = new HelpDocument(docURL, name); |
|
helpDocuments.add(helpDocument); |
|
} |
|
} |
|
} catch (JSONException e) { |
|
FineLoggerFactory.getLogger().debug(e.getMessage(), e); |
|
} catch (Exception e) { |
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
} |
|
} |
|
|
|
private void initHelpDocumentPane(JPanel descriptionAndDocumentPanel) { |
|
card = new CardLayout(); |
|
JPanel mainPane = new JPanel(card); |
|
initHelpDocumentList(); |
|
UIScrollPane helpDOCScrollPane = new UIScrollPane(helpDOCList); |
|
helpDOCScrollPane.setPreferredSize(new Dimension(200, 200)); |
|
helpDOCScrollPane.setBorder(null); |
|
mainPane.add(helpDOCScrollPane, DOC_LIST_CARD); |
|
|
|
UILabel imageLabel = new UILabel(); |
|
imageLabel.setIcon(IconUtils.readIcon("com/fr/design/javascript/jsapi/images/connectFailed.svg")); |
|
imageLabel.setPreferredSize(new Dimension(180, 65)); |
|
JPanel imagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
imagePane.setBorder(BorderFactory.createEmptyBorder(0, 42, 0, 0)); |
|
imagePane.add(imageLabel); |
|
imagePane.setBackground(Color.WHITE); |
|
|
|
UILabel failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Net_Connect_Failed"), 0); |
|
failedLabel.setPreferredSize(new Dimension(180, 20)); |
|
UILabel reloadLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Reload"), 0); |
|
reloadLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
|
reloadLabel.setPreferredSize(new Dimension(180, 20)); |
|
reloadLabel.setForeground(Color.blue); |
|
JPanel labelPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, 0, 0, 0); |
|
|
|
labelPane.setBorder(BorderFactory.createEmptyBorder(35, 45, 0, 0)); |
|
labelPane.setBackground(Color.WHITE); |
|
labelPane.add(imagePane); |
|
labelPane.add(failedLabel); |
|
labelPane.add(reloadLabel); |
|
JPanel containerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
containerPanel.add(labelPane, BorderLayout.CENTER); |
|
reloadLabel.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if (isNetworkOk()) { |
|
doHelpDocumentSearch(); |
|
card.show(mainPane, DOC_LIST_CARD); |
|
} |
|
} |
|
}); |
|
mainPane.add(containerPanel, RELOAD_CARD); |
|
if (isNetworkOk()) { |
|
doHelpDocumentSearch(); |
|
card.show(mainPane, DOC_LIST_CARD); |
|
} else { |
|
card.show(mainPane, RELOAD_CARD); |
|
} |
|
descriptionAndDocumentPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Relevant_Cases"), mainPane), BorderLayout.EAST); |
|
} |
|
|
|
private void initHelpDocumentList() { |
|
helpDOCList = new JList(new DefaultListModel()); |
|
initHelpDOCListRender(); |
|
initHelpDOCListListener(); |
|
} |
|
|
|
private void initHelpDOCListListener() { |
|
helpDOCList.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if (e.getClickCount() == 2) { |
|
Object value = helpDOCList.getSelectedValue(); |
|
if (value instanceof HelpDocument) { |
|
String url = ((HelpDocument) value).getDocumentUrl(); |
|
browse(url); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
private void browse(String url){ |
|
try { |
|
Desktop.getDesktop().browse(new URI(url)); |
|
} catch (IOException | URISyntaxException ex) { |
|
FineLoggerFactory.getLogger().error(ex.getMessage(), ex); |
|
} |
|
} |
|
|
|
private void initHelpDOCListRender() { |
|
helpDOCList.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 HelpDocument) { |
|
this.setText(((HelpDocument) value).getName()); |
|
this.setForeground(Color.BLUE); |
|
} |
|
return this; |
|
} |
|
}); |
|
} |
|
|
|
private static boolean isNetworkOk() { |
|
try { |
|
HttpToolbox.get(URL_FOR_TEST_NETWORK); |
|
return true; |
|
} catch (Exception ignore) { |
|
// 网络异常 |
|
return false; |
|
} |
|
} |
|
|
|
private static class HelpDocument { |
|
private String documentUrl; |
|
|
|
|
|
private String name; |
|
|
|
public HelpDocument(String documentUrl, String name) { |
|
this.documentUrl = documentUrl; |
|
this.name = name; |
|
} |
|
|
|
public String getDocumentUrl() { |
|
return documentUrl; |
|
} |
|
|
|
public String getName() { |
|
return name; |
|
} |
|
} |
|
|
|
private void initDescriptionArea(JPanel descriptionPanel) { |
|
descriptionTextArea = new UITextArea(); |
|
UIScrollPane descriptionScrollPane = new UIScrollPane(descriptionTextArea); |
|
descriptionScrollPane.setPreferredSize(new Dimension(300, 200)); |
|
descriptionPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Interface_Description"), descriptionScrollPane), BorderLayout.CENTER); |
|
descriptionTextArea.setBackground(Color.white); |
|
descriptionTextArea.setLineWrap(true); |
|
descriptionTextArea.setWrapStyleWord(true); |
|
descriptionTextArea.setEditable(false); |
|
} |
|
|
|
private void installAutoCompletion() { |
|
CompletionProvider provider = createCompletionProvider(); |
|
autoCompletion = new JSImplPaneAutoCompletion(provider); |
|
autoCompletion.setListCellRenderer(new CompletionCellRenderer()); |
|
autoCompletion.install(contentTextArea); |
|
autoCompletion.installExtraRefreshComponent(interfaceAndDescriptionPanel); |
|
} |
|
|
|
private void uninstallAutoCompletion() { |
|
if (autoCompletion != null) { |
|
autoCompletion.uninstall(); |
|
autoCompletion = null; |
|
} |
|
} |
|
|
|
private CompletionProvider createCompletionProvider() { |
|
if (completionProvider == null) { |
|
completionProvider = new DefaultCompletionProvider(); |
|
for (String name : JSAPITreeHelper.getAllNames()) { |
|
completionProvider.addCompletion(new BasicCompletion(completionProvider, name)); |
|
} |
|
} |
|
return completionProvider; |
|
} |
|
|
|
private void initInterfaceModuleTree(JPanel interfacePanel) { |
|
moduleTree = new JTree(); |
|
UIScrollPane moduleTreePane = new UIScrollPane(moduleTree); |
|
moduleTreePane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
|
interfacePanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Module"), moduleTreePane), BorderLayout.WEST); |
|
moduleTreePane.setPreferredSize(new Dimension(180, 200)); |
|
|
|
moduleTree.setRootVisible(false); |
|
moduleTree.setShowsRootHandles(true); |
|
moduleTree.setCellRenderer(moduleTreeCellRender); |
|
DefaultTreeModel moduleTreeModel = (DefaultTreeModel) moduleTree.getModel(); |
|
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) moduleTreeModel.getRoot(); |
|
rootNode.removeAllChildren(); |
|
|
|
JSAPITreeHelper.createJSAPITree(rootNode); |
|
moduleTreeModel.reload(); |
|
|
|
initModuleTreeSelectionListener(); |
|
} |
|
|
|
private void initModuleTreeSelectionListener() { |
|
moduleTree.addTreeSelectionListener(new TreeSelectionListener() { |
|
@Override |
|
public void valueChanged(TreeSelectionEvent e) { |
|
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) moduleTree.getLastSelectedPathComponent(); |
|
Object selectedValue = selectedTreeNode.getUserObject(); |
|
if (null == selectedValue) { |
|
return; |
|
} |
|
if (selectedValue instanceof JSAPIUserObject) { |
|
interfaceNameModel = (DefaultListModel) interfaceNameList.getModel(); |
|
interfaceNameModel.clear(); |
|
String text = ((JSAPIUserObject) selectedValue).getValue(); |
|
List<String> allInterfaceNames = JSAPITreeHelper.getNames(text); |
|
for (String interfaceName : allInterfaceNames) { |
|
interfaceNameModel.addElement(interfaceName); |
|
} |
|
if (interfaceNameModel.size() > 0) { |
|
interfaceNameList.setSelectedIndex(0); |
|
setDescription(interfaceNameList.getSelectedValue().toString()); |
|
interfaceNameList.ensureIndexIsVisible(0); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
|
|
private DefaultTreeCellRenderer moduleTreeCellRender = 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 JSAPIUserObject) { |
|
this.setText(((JSAPIUserObject) userObj).getDisplayText()); |
|
this.setIcon(null); |
|
} |
|
return this; |
|
} |
|
|
|
}; |
|
|
|
|
|
private void initInterfaceNameList(JPanel interfacePanel) { |
|
interfaceNameList = new JList(new DefaultListModel()); |
|
UIScrollPane interfaceNamePanelScrollPane = new UIScrollPane(interfaceNameList); |
|
interfaceNamePanelScrollPane.setPreferredSize(new Dimension(180, 200)); |
|
interfacePanel.add( |
|
this.createNamePane(Toolkit.i18nText("Fine-Design_Interface") + ":", interfaceNamePanelScrollPane), |
|
BorderLayout.CENTER); |
|
|
|
interfaceNamePanelScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
|
initInterfaceNameModule(); |
|
initInterfaceNameListSelectionListener(); |
|
initInterfaceNameListMouseListener(); |
|
} |
|
|
|
private void initInterfaceNameModule() { |
|
DefaultTreeModel defaultTreeModel = (DefaultTreeModel) moduleTree.getModel(); |
|
TreeNode root = (TreeNode) defaultTreeModel.getRoot(); |
|
while (root.getChildCount() > 0){ |
|
root = root.getChildAt(0); |
|
} |
|
moduleTree.setSelectionPath(new TreePath(defaultTreeModel.getPathToRoot(root))); |
|
} |
|
|
|
private void setDescription(String interfaceName) { |
|
StringBuilder il8Key = new StringBuilder(); |
|
moduleTree.getSelectionPath().getPath(); |
|
Object obj = moduleTree.getSelectionPath().getPath()[moduleTree.getSelectionPath().getPath().length - 1]; |
|
Object userObject = ((DefaultMutableTreeNode) obj).getUserObject(); |
|
if (userObject instanceof JSAPIUserObject) { |
|
il8Key.append(JSAPITreeHelper.getDirectCategory(interfaceName)); |
|
} |
|
interfaceName = interfaceName.toUpperCase(); |
|
if (!interfaceName.startsWith(SEPARATOR)) { |
|
interfaceName = SEPARATOR + interfaceName; |
|
} |
|
il8Key.append(interfaceName); |
|
descriptionTextArea.setText(Toolkit.i18nText(il8Key.toString())); |
|
descriptionTextArea.moveCaretPosition(0); |
|
} |
|
|
|
private void initInterfaceNameListSelectionListener() { |
|
interfaceNameList.addListSelectionListener(new ListSelectionListener() { |
|
|
|
public void valueChanged(ListSelectionEvent evt) { |
|
Object selectedValue = interfaceNameList.getSelectedValue(); |
|
if (selectedValue == null) { |
|
return; |
|
} |
|
String interfaceName = selectedValue.toString(); |
|
if (!StringUtils.equals(interfaceName, currentValue)) { |
|
setDescription(interfaceName); |
|
doHelpDocumentSearch(); |
|
currentValue = interfaceName; |
|
} |
|
|
|
} |
|
}); |
|
} |
|
|
|
|
|
private void initInterfaceNameListMouseListener() { |
|
interfaceNameList.addMouseListener(new MouseAdapter() { |
|
public void mouseClicked(MouseEvent evt) { |
|
if (evt.getClickCount() >= 2) { |
|
Object selectedValue = interfaceNameList.getSelectedValue(); |
|
String interfaceName = selectedValue.toString(); |
|
applyText(interfaceName); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
private void applyText(String text) { |
|
if (text == null || text.length() <= 0) { |
|
return; |
|
} |
|
if (ifHasBeenWriten == 0) { |
|
contentTextArea.setForeground(Color.black); |
|
contentTextArea.setText(StringUtils.EMPTY); |
|
ifHasBeenWriten = 1; |
|
insertPosition = 0; |
|
} |
|
String textAll = contentTextArea.getText(); |
|
currentPosition = contentTextArea.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); |
|
contentTextArea.setText(beforeIndexOfInsertString + text + afterIndexofInsertString); |
|
contentTextArea.getText(); |
|
contentTextArea.requestFocus(); |
|
insertPosition = contentTextArea.getCaretPosition(); |
|
} |
|
|
|
private JPanel createNamePane(String name, JComponent comp) { |
|
JPanel namePane = new JPanel(new BorderLayout(4, 4)); |
|
namePane.add(new UILabel(name), BorderLayout.NORTH); |
|
namePane.add(comp, BorderLayout.CENTER); |
|
return namePane; |
|
} |
|
|
|
private JPanel createTipsPane() { |
|
JPanel tipsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
tipsPane.setLayout(new BorderLayout(4, 4)); |
|
tipsPane.setBorder(BorderFactory.createEmptyBorder(30, 2, 0, 0)); |
|
JPanel searchPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
searchPane.setLayout(new BorderLayout(4, 4)); |
|
keyWordTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Search_Interface")); |
|
searchPane.add(keyWordTextField, BorderLayout.CENTER); |
|
|
|
//搜索按钮 |
|
UIButton searchButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Search")); |
|
searchButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
String toFind = keyWordTextField.getText(); |
|
search(toFind); |
|
popTips(); |
|
tipsList.requestFocusInWindow(); |
|
} |
|
}); |
|
|
|
keyWordTextField.addKeyListener(new KeyAdapter() { |
|
@Override |
|
public void keyPressed(KeyEvent e) { |
|
if (e.getKeyChar() == KeyEvent.VK_ENTER) { |
|
e.consume(); |
|
String toFind = keyWordTextField.getText(); |
|
search(toFind); |
|
popTips(); |
|
tipsList.requestFocusInWindow(); |
|
} |
|
} |
|
}); |
|
|
|
searchPane.add(searchButton, BorderLayout.EAST); |
|
tipsPane.add(searchPane, BorderLayout.NORTH); |
|
|
|
tipsList = new JList(tipsListModel); |
|
tipsList.addMouseListener(tipsListMouseListener); |
|
tipsList.addListSelectionListener(tipsListSelectionListener); |
|
tipsList.addKeyListener(tipListKeyListener); |
|
|
|
return tipsPane; |
|
} |
|
|
|
private void search(String key) { |
|
tipsListModel.removeAllElements(); |
|
tipsListModel.clear(); |
|
key = key.replaceAll(StringUtils.BLANK, StringUtils.EMPTY); |
|
ArrayList<String> list = new ArrayList<>(); |
|
if (!StringUtils.isEmpty(key)) { |
|
List<String> allNames = JSAPITreeHelper.getAllNames(); |
|
for (String name : allNames) { |
|
if (searchResult(key, name)) { |
|
list.add(name); |
|
} |
|
} |
|
String finalKey = key; |
|
Collections.sort(list, new Comparator<String>() { |
|
@Override |
|
public int compare(String o1, String o2) { |
|
int result; |
|
boolean o1StartWidth = o1.toLowerCase().startsWith(finalKey.toLowerCase()); |
|
boolean o2StartWidth = o2.toLowerCase().startsWith(finalKey.toLowerCase()); |
|
if (o1StartWidth) { |
|
result = o2StartWidth ? o1.compareTo(o2) : -1; |
|
} else { |
|
result = o2StartWidth ? 1 : o1.compareTo(o2); |
|
} |
|
return result; |
|
} |
|
}); |
|
for (String name : list) { |
|
tipsListModel.addElement(name); |
|
} |
|
if (!tipsListModel.isEmpty()) { |
|
tipsList.setSelectedIndex(0); |
|
} |
|
} |
|
} |
|
|
|
private boolean searchResult(String key, String interfaceName) { |
|
if (StringUtils.isBlank(key) || StringUtils.isBlank(interfaceName)) { |
|
return false; |
|
} |
|
int length = key.length(); |
|
String temp = interfaceName.toUpperCase(); |
|
for (int i = 0; i < length; i++) { |
|
String check = key.substring(i, i + 1); |
|
int index = temp.indexOf(check.toUpperCase()); |
|
if (index == -1) { |
|
return false; |
|
} else { |
|
temp = temp.substring(index + 1); |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
private void initPopTips() { |
|
popupMenu = new JPopupMenu(); |
|
JScrollPane tipsScrollPane = new JScrollPane(tipsList); |
|
popupMenu.add(tipsScrollPane); |
|
tipsScrollPane.setPreferredSize(new Dimension(220, 146)); |
|
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); |
|
} |
|
|
|
private void popTips() { |
|
popupMenu.show(keyWordTextField, 0, 23); |
|
} |
|
|
|
private ListSelectionListener tipsListSelectionListener = new ListSelectionListener() { |
|
@Override |
|
public void valueChanged(ListSelectionEvent e) { |
|
Object selectValue = tipsList.getSelectedValue(); |
|
if (selectValue == null) { |
|
return; |
|
} |
|
String interfaceName = selectValue.toString(); |
|
fixInterfaceNameList(interfaceName); |
|
} |
|
}; |
|
|
|
private KeyListener tipListKeyListener = new KeyAdapter() { |
|
@Override |
|
public void keyPressed(KeyEvent e) { |
|
if (e.getKeyChar() == KeyEvent.VK_ENTER) { |
|
Object selectValue = tipsList.getSelectedValue(); |
|
if (selectValue == null) { |
|
return; |
|
} |
|
tipListValueSelectAction(selectValue.toString()); |
|
if (popupMenu != null) { |
|
popupMenu.setVisible(false); |
|
} |
|
contentTextArea.requestFocusInWindow(); |
|
} |
|
} |
|
}; |
|
|
|
private void tipListValueSelectAction(String value) { |
|
if (ifHasBeenWriten == 0) { |
|
contentTextArea.setForeground(Color.black); |
|
contentTextArea.setText(StringUtils.EMPTY); |
|
} |
|
contentTextArea.setForeground(Color.black); |
|
currentPosition = contentTextArea.getCaretPosition(); |
|
String output = value; |
|
String textAll = contentTextArea.getText(); |
|
String textReplaced; |
|
int position = 0; |
|
if (insertPosition <= currentPosition) { |
|
textReplaced = textAll.substring(0, insertPosition) + output + textAll.substring(currentPosition); |
|
position = insertPosition + output.length(); |
|
} else { |
|
textReplaced = textAll.substring(0, currentPosition) + output + textAll.substring(insertPosition); |
|
position = currentPosition + output.length(); |
|
} |
|
contentTextArea.setText(textReplaced); |
|
contentTextArea.setCaretPosition(position); |
|
insertPosition = position; |
|
ifHasBeenWriten = 1; |
|
tipsListModel.removeAllElements(); |
|
} |
|
|
|
private MouseListener tipsListMouseListener = new MouseAdapter() { |
|
String singlePressContent; |
|
|
|
String doublePressContent; |
|
|
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
int index = tipsList.getSelectedIndex(); |
|
if (index != -1) { |
|
if (e.getClickCount() == 1) { |
|
singlePressContent = (String) tipsListModel.getElementAt(index); |
|
} else if (e.getClickCount() == 2) { |
|
doublePressContent = (String) tipsListModel.getElementAt(index); |
|
} |
|
} |
|
} |
|
|
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
int index = tipsList.getSelectedIndex(); |
|
if (index != -1) { |
|
if (e.getClickCount() == 1) { |
|
if (ComparatorUtils.equals((String) tipsListModel.getElementAt(index), singlePressContent)) { |
|
singleClickActuator(singlePressContent); |
|
} |
|
} else if (e.getClickCount() == 2) { |
|
if (ComparatorUtils.equals((String) tipsListModel.getElementAt(index), doublePressContent)) { |
|
doubleClickActuator(doublePressContent); |
|
} |
|
if (popupMenu != null) { |
|
popupMenu.setVisible(false); |
|
} |
|
} |
|
} |
|
} |
|
|
|
private void singleClickActuator(String currentLineContent) { |
|
setDescription(currentLineContent); |
|
fixInterfaceNameList(currentLineContent); |
|
} |
|
|
|
private void doubleClickActuator(String currentLineContent) { |
|
tipListValueSelectAction(currentLineContent); |
|
} |
|
}; |
|
}
|
|
|