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.
336 lines
12 KiB
336 lines
12 KiB
package com.fr.design.javascript; |
|
|
|
import com.fine.theme.icon.LazyIcon; |
|
import com.fr.base.svg.IconUtils; |
|
import com.fr.design.DesignerEnvManager; |
|
import com.fr.design.border.UIRoundedBorder; |
|
import com.fr.design.constants.KeyWords; |
|
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.gui.autocomplete.AutoCompletion; |
|
import com.fr.design.gui.autocomplete.BasicCompletion; |
|
import com.fr.design.gui.autocomplete.CompletionProvider; |
|
import com.fr.design.gui.autocomplete.DefaultCompletionProvider; |
|
import com.fr.design.gui.autocomplete.ShorthandCompletion; |
|
import com.fr.design.gui.icontainer.UIScrollPane; |
|
import com.fr.design.gui.ilable.UILabel; |
|
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.javascript.beautify.JavaScriptFormatHelper; |
|
import com.fr.design.javascript.jsapi.JSImplPopulateAction; |
|
import com.fr.design.javascript.jsapi.JSImplUpdateAction; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.general.IOUtils; |
|
import com.fr.js.JavaScriptImpl; |
|
|
|
import javax.swing.BorderFactory; |
|
import javax.swing.JPanel; |
|
import javax.swing.KeyStroke; |
|
import javax.swing.SwingConstants; |
|
import javax.swing.SwingWorker; |
|
import java.awt.BorderLayout; |
|
import java.awt.Cursor; |
|
import java.awt.Dimension; |
|
import java.awt.FontMetrics; |
|
import java.awt.event.FocusEvent; |
|
import java.awt.event.FocusListener; |
|
import java.awt.event.MouseAdapter; |
|
import java.awt.event.MouseEvent; |
|
import java.util.ArrayList; |
|
|
|
import static com.fine.swing.ui.layout.Layouts.row; |
|
import static com.fine.swing.ui.layout.Layouts.cell; |
|
|
|
public class JSContentPane extends BasicPane { |
|
protected RSyntaxTextArea contentTextArea; |
|
private UILabel funNameLabel = new UILabel(); |
|
private AutoCompletion ac; |
|
private static final Dimension FUNCTION_NAME_LABEL_SIZE = new Dimension(300, 80); |
|
private String[] defaultArgs; |
|
private int titleWidth = 180; |
|
private JPanel labelPane = new JPanel(); |
|
private NewJavaScriptImplPane newJavaScriptImplPane = null; |
|
private JavaScriptImpl javaScript; |
|
private JSImplUpdateAction jsImplUpdateAction; |
|
private JSImplPopulateAction jsImplPopulateAction; |
|
private boolean modal; |
|
BasicDialog advancedEditorDialog ; |
|
public JSContentPane(){} |
|
|
|
public JSContentPane(String[] args) { |
|
defaultArgs = args; |
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
initFunctionTitle(args); |
|
|
|
JPanel jsParaPane = createJSParaPane(); |
|
if (needAdvancedEditor()) { |
|
addNewPaneLabel(); |
|
} |
|
this.add(jsParaPane, BorderLayout.NORTH); |
|
|
|
UIScrollPane sp = createContentTextAreaPanel(); |
|
initContentTextAreaListener(); |
|
this.add(sp, BorderLayout.CENTER); |
|
|
|
UILabel funNameLabel2 = new UILabel(); |
|
funNameLabel2.setText("}"); |
|
this.add(funNameLabel2, BorderLayout.SOUTH); |
|
} |
|
public JSContentPane(String[] args,boolean modal) { |
|
this(args); |
|
this.modal = modal; |
|
} |
|
|
|
|
|
public void setJsImplUpdateAction(JSImplUpdateAction jsImplUpdateAction){ |
|
this.jsImplUpdateAction = jsImplUpdateAction; |
|
} |
|
|
|
public void setJsImplPopulateAction(JSImplPopulateAction jsImplPopulateAction){ |
|
this.jsImplPopulateAction = jsImplPopulateAction; |
|
} |
|
|
|
public void updateJSImpl(JavaScriptImpl javaScript){ |
|
this.javaScript = javaScript; |
|
} |
|
|
|
|
|
private void addNewPaneLabel(){ |
|
UILabel advancedEditorLabel = new UILabel(Toolkit.i18nText("Fine-Design_Advanced_Editor"), new LazyIcon("advanced_editor"), SwingConstants.LEFT); |
|
advancedEditorLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
|
advancedEditorLabel.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if(newJavaScriptImplPane == null){ |
|
newJavaScriptImplPane = new NewJavaScriptImplPane(defaultArgs); |
|
} |
|
jsImplUpdateAction.update(javaScript); |
|
newJavaScriptImplPane.populate(javaScript); |
|
if(advancedEditorDialog == null || !advancedEditorDialog.isVisible()) { |
|
advancedEditorDialog = newJavaScriptImplPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { |
|
@Override |
|
public void doOk() { |
|
if (javaScript != null) { |
|
newJavaScriptImplPane.updateBean(javaScript); |
|
jsImplPopulateAction.populate(javaScript); |
|
} |
|
} |
|
|
|
@Override |
|
public void doCancel() { |
|
super.doCancel(); |
|
} |
|
},new Dimension(900,800)); |
|
advancedEditorDialog.setModal(modal); |
|
advancedEditorDialog.setResizable(true); |
|
advancedEditorDialog.pack(); |
|
advancedEditorDialog.setVisible(true); |
|
} |
|
advancedEditorDialog.requestFocus(); |
|
} |
|
}); |
|
labelPane.add(advancedEditorLabel,BorderLayout.EAST); |
|
} |
|
|
|
protected UIScrollPane createContentTextAreaPanel(){ |
|
contentTextArea = new RSyntaxTextArea(); |
|
contentTextArea.setCloseCurlyBraces(true); |
|
contentTextArea.setLineWrap(true); |
|
contentTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT); |
|
contentTextArea.setCodeFoldingEnabled(true); |
|
contentTextArea.setAntiAliasingEnabled(true); |
|
return new UIScrollPane(contentTextArea); |
|
} |
|
|
|
private void initContentTextAreaListener(){ |
|
contentTextArea.addFocusListener(new FocusListener() { |
|
@Override |
|
public void focusGained(FocusEvent e) { |
|
// 获得焦点时 安装 |
|
installAutoCompletion(); |
|
} |
|
|
|
@Override |
|
public void focusLost(FocusEvent e) { |
|
// 失去焦点时 卸载 |
|
uninstallAutoCompletion(); |
|
} |
|
}); |
|
} |
|
|
|
protected JPanel createJSParaPane(){ |
|
UILabel label = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Format_JavaScript"), IOUtils.readIcon("com/fr/design/images/edit/format.png"), SwingConstants.LEFT); |
|
label.setCursor(new Cursor(Cursor.HAND_CURSOR)); |
|
label.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Format_JavaScript")); |
|
label.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
new SwingWorker<String, Void>() { |
|
@Override |
|
protected String doInBackground() throws Exception { |
|
return JavaScriptFormatHelper.beautify(contentTextArea.getText()); |
|
} |
|
|
|
@Override |
|
protected void done() { |
|
try { |
|
String text = get(); |
|
contentTextArea.setText(text); |
|
} catch (Exception ignore) { |
|
|
|
} |
|
} |
|
}.execute(); |
|
} |
|
}); |
|
labelPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); |
|
labelPane.add(label,BorderLayout.CENTER); |
|
JPanel jsParaPane = new JPanel(new BorderLayout()); |
|
|
|
UIScrollPane scrollPane = new UIScrollPane(funNameLabel); |
|
scrollPane.setBorder(new UIRoundedBorder(UIConstants.TITLED_BORDER_COLOR, 1, UIConstants.ARC)); |
|
jsParaPane.add(row(10, |
|
cell(scrollPane).weight(0.6), |
|
cell(labelPane).weight(0.4) |
|
).getComponent()); |
|
return jsParaPane; |
|
} |
|
|
|
protected void initFunctionTitle(String[] args){ |
|
funNameLabel = new UILabel(); |
|
this.setFunctionTitle(args); |
|
} |
|
|
|
private KeyStroke convert2KeyStroke(String ks) { |
|
return KeyStroke.getKeyStroke(ks.replace("+", "pressed")); |
|
} |
|
|
|
/** |
|
* 注册安装 自动补全监听 |
|
*/ |
|
private void installAutoCompletion() { |
|
if (ac == null) { |
|
CompletionProvider provider = createCompletionProvider(); |
|
ac = new AutoCompletion(provider); |
|
String shortCuts = DesignerEnvManager.getEnvManager().getAutoCompleteShortcuts(); |
|
|
|
ac.setTriggerKey(convert2KeyStroke(shortCuts)); |
|
ac.install(contentTextArea); |
|
} |
|
} |
|
|
|
/** |
|
* 卸载移除 自动补全监听 |
|
*/ |
|
private void uninstallAutoCompletion() { |
|
if (ac != null) { |
|
ac.uninstall(); |
|
ac = null; |
|
} |
|
} |
|
|
|
@Override |
|
protected String title4PopupWindow() { |
|
return "JS"; |
|
} |
|
|
|
public void populate(String js) { |
|
this.contentTextArea.setText(js); |
|
} |
|
|
|
public String update() { |
|
return this.contentTextArea.getText(); |
|
} |
|
|
|
public void reset() { |
|
this.contentTextArea.setText(null); |
|
} |
|
|
|
public void setFunctionTitle(String[] args) { |
|
funNameLabel.setText(createFunctionTitle(args)); |
|
} |
|
|
|
public void setFunctionTitle(String[] args, String[] defaultArgs) { |
|
String[] titles; |
|
if (defaultArgs == null) { |
|
titles = args; |
|
} else if (args == null) { |
|
titles = defaultArgs; |
|
} else { |
|
ArrayList list = new ArrayList(); |
|
for (String s : defaultArgs) { |
|
list.add(s); |
|
} |
|
for (String s : args) { |
|
list.add(s); |
|
} |
|
titles = (String[]) list.toArray(new String[list.size()]); |
|
} |
|
setFunctionTitle(titles); |
|
} |
|
|
|
/** |
|
* 用html,方便换行 |
|
* |
|
* @param args |
|
* @return |
|
*/ |
|
private String createFunctionTitle(String[] args) { |
|
StringBuffer sb = new StringBuffer(); |
|
sb.append("<html> <body> <div style='height:16px'>function("); |
|
int width = titleWidth; |
|
FontMetrics cellFM = this.getFontMetrics(this.getFont()); |
|
int tempwidth = 0; |
|
if (args != null) { |
|
for (int i = 0; i < args.length; i++) { |
|
if (args[i] == null) { |
|
continue; |
|
} |
|
if (cellFM.stringWidth(args[i]) < width) { |
|
tempwidth = tempwidth + cellFM.stringWidth(args[i]); |
|
if (tempwidth < width) { |
|
sb.append(args[i]); |
|
if (i != args.length - 1) { |
|
sb.append(","); |
|
} |
|
} else { |
|
tempwidth = 0; |
|
i = i - 1;// 后退一步 |
|
sb.append("</p><p>     "); |
|
} |
|
} else { |
|
sb.append("</p><p>     "); |
|
sb.append(args[i]); |
|
sb.append("</p>"); |
|
} |
|
} |
|
} |
|
sb.append("){</div><body> </html>"); |
|
return sb.toString(); |
|
} |
|
|
|
private CompletionProvider createCompletionProvider() { |
|
|
|
DefaultCompletionProvider provider = new DefaultCompletionProvider(); |
|
|
|
for (String key : KeyWords.JAVASCRIPT) { |
|
provider.addCompletion(new BasicCompletion(provider, key)); |
|
} |
|
|
|
for (String[] key : KeyWords.JAVASCRIPT_SHORT) { |
|
provider.addCompletion(new ShorthandCompletion(provider, key[0], |
|
key[1], key[1])); |
|
} |
|
|
|
return provider; |
|
|
|
} |
|
|
|
protected boolean needAdvancedEditor() { |
|
return true; |
|
} |
|
} |