|
|
|
@ -1,31 +1,43 @@
|
|
|
|
|
package com.fr.design.mainframe.loghandler; |
|
|
|
|
|
|
|
|
|
import com.fr.base.BaseUtils; |
|
|
|
|
import com.fr.base.TRL; |
|
|
|
|
import com.fr.design.file.HistoryTemplateListCache; |
|
|
|
|
import com.fr.design.gui.icontainer.UIScrollPane; |
|
|
|
|
import com.fr.design.gui.imenu.UIMenuItem; |
|
|
|
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
|
|
|
import com.fr.design.mainframe.DesignerContext; |
|
|
|
|
import com.fr.design.mainframe.JTemplate; |
|
|
|
|
import com.fr.design.ui.util.UIUtil; |
|
|
|
|
import com.fr.file.FILEFactory; |
|
|
|
|
import com.fr.general.ComparatorUtils; |
|
|
|
|
import com.fr.general.log.Log4jConfig; |
|
|
|
|
import com.fr.log.FineLoggerFactory; |
|
|
|
|
import com.fr.stable.StringUtils; |
|
|
|
|
|
|
|
|
|
import com.fr.stable.project.ProjectConstants; |
|
|
|
|
import com.fr.third.apache.logging.log4j.Level; |
|
|
|
|
import com.fr.third.apache.logging.log4j.core.LogEvent; |
|
|
|
|
import org.jetbrains.annotations.Nullable; |
|
|
|
|
|
|
|
|
|
import javax.swing.AbstractAction; |
|
|
|
|
import javax.swing.ActionMap; |
|
|
|
|
import javax.swing.InputMap; |
|
|
|
|
import javax.swing.JCheckBoxMenuItem; |
|
|
|
|
import javax.swing.JComponent; |
|
|
|
|
import javax.swing.JEditorPane; |
|
|
|
|
import javax.swing.JPanel; |
|
|
|
|
import javax.swing.JPopupMenu; |
|
|
|
|
import javax.swing.JTextPane; |
|
|
|
|
import javax.swing.KeyStroke; |
|
|
|
|
import javax.swing.text.AttributeSet; |
|
|
|
|
import javax.swing.text.BadLocationException; |
|
|
|
|
import javax.swing.text.DefaultEditorKit; |
|
|
|
|
import javax.swing.text.Document; |
|
|
|
|
import javax.swing.text.Element; |
|
|
|
|
import javax.swing.text.SimpleAttributeSet; |
|
|
|
|
import javax.swing.text.StyleConstants; |
|
|
|
|
import javax.swing.text.html.HTML; |
|
|
|
|
import javax.swing.text.html.HTMLDocument; |
|
|
|
|
import java.awt.BorderLayout; |
|
|
|
|
import java.awt.Color; |
|
|
|
|
import java.awt.Dimension; |
|
|
|
@ -36,8 +48,14 @@ import java.awt.event.ItemListener;
|
|
|
|
|
import java.awt.event.KeyEvent; |
|
|
|
|
import java.awt.event.MouseAdapter; |
|
|
|
|
import java.awt.event.MouseEvent; |
|
|
|
|
import java.io.File; |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.Date; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.regex.Matcher; |
|
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; |
|
|
|
|
|
|
|
|
@ -61,6 +79,8 @@ public class DesignerLogHandler {
|
|
|
|
|
|
|
|
|
|
private static final String ACTION_MAP_KEY = "clear"; |
|
|
|
|
|
|
|
|
|
private static final Pattern pattern = Pattern.compile("\\([^(]*.(?>cpt|frm|cptx)[^)]*\\)"); |
|
|
|
|
|
|
|
|
|
public static DesignerLogHandler getInstance() { |
|
|
|
|
|
|
|
|
|
return HOLDER.singleton; |
|
|
|
@ -215,13 +235,61 @@ public class DesignerLogHandler {
|
|
|
|
|
popup.show(jTextArea, event.getX(), event.getY()); |
|
|
|
|
checkEnabled(); |
|
|
|
|
} |
|
|
|
|
if (event.getButton() == MouseEvent.BUTTON1) { |
|
|
|
|
String url = findTplLinkFromMouseEvent(event); |
|
|
|
|
if (StringUtils.isNotEmpty(url)) { |
|
|
|
|
navigate(url); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 将模板定位链接导航到指定的位置 |
|
|
|
|
* |
|
|
|
|
* @param href 模板定位链接 |
|
|
|
|
*/ |
|
|
|
|
private void navigate(String href) { |
|
|
|
|
if (!href.startsWith(TRL.PREFIX)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
TRL trl = new TRL(href); |
|
|
|
|
DesignerContext.getDesignerFrame().openTemplate(FILEFactory.createFILE(ProjectConstants.REPORTLETS_NAME + File.separator + trl.getTemplatePath())); |
|
|
|
|
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
|
|
|
|
if (currentEditingTemplate != null) { |
|
|
|
|
currentEditingTemplate.navigate(trl); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 鼠标事件中定位到模板链接 |
|
|
|
|
* |
|
|
|
|
* @param event 鼠标事件 |
|
|
|
|
* @return 模板链接 |
|
|
|
|
*/ |
|
|
|
|
private String findTplLinkFromMouseEvent(MouseEvent event) { |
|
|
|
|
JEditorPane editor = (JEditorPane) event.getSource(); |
|
|
|
|
int pos = editor.getUI().viewToModel(editor, event.getPoint()); |
|
|
|
|
if (pos >= 0 && editor.getDocument() instanceof HTMLDocument) { |
|
|
|
|
HTMLDocument hdoc = (HTMLDocument) editor.getDocument(); |
|
|
|
|
Element elem = hdoc.getCharacterElement(pos); |
|
|
|
|
Object a = elem.getAttributes().getAttribute(HTML.Tag.A); |
|
|
|
|
if (a instanceof AttributeSet) { |
|
|
|
|
AttributeSet set = (AttributeSet) a; |
|
|
|
|
String url = (String) set.getAttribute(HTML.Attribute.HREF); |
|
|
|
|
if (StringUtils.isNotEmpty(url)) { |
|
|
|
|
return url; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return StringUtils.EMPTY; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private JTextPane initLogJTextArea() { |
|
|
|
|
|
|
|
|
|
final JTextPane resultPane = new JTextPane(); |
|
|
|
|
resultPane.setContentType("text/html"); |
|
|
|
|
InputMap inputMap = resultPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); |
|
|
|
|
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); |
|
|
|
|
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); |
|
|
|
@ -294,6 +362,12 @@ public class DesignerLogHandler {
|
|
|
|
|
|
|
|
|
|
SimpleAttributeSet attrSet = new SimpleAttributeSet(); |
|
|
|
|
if (style == DesignerLogger.ERROR_INT) { |
|
|
|
|
String[] tplLink = tryFindTplLink(str); |
|
|
|
|
if (tplLink != null |
|
|
|
|
&& tplLink.length > 0 |
|
|
|
|
&& dealWithTplLink(str, tplLink)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
StyleConstants.setForeground(attrSet, Color.RED); |
|
|
|
|
StyleConstants.setBold(attrSet, true); |
|
|
|
|
} else if (style == DesignerLogger.WARN_INT) { |
|
|
|
@ -314,6 +388,62 @@ public class DesignerLogHandler {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 处理模板链接 |
|
|
|
|
* |
|
|
|
|
* @param s 含有模板链接 |
|
|
|
|
* @param tplLink 模板链接 |
|
|
|
|
* @return 是否处理成功 |
|
|
|
|
*/ |
|
|
|
|
private boolean dealWithTplLink(String s, String[] tplLink) { |
|
|
|
|
String afterBr = s.replaceAll("\\n", "<br/>"); |
|
|
|
|
String[] lineSeg = pattern.split(afterBr); |
|
|
|
|
StringBuilder sb = new StringBuilder("<span style=\"font-weight: bold;font-size:" + jTextArea.getFont().getSize() + "\">"); |
|
|
|
|
for(int i=0;i< tplLink.length;i++){ |
|
|
|
|
sb.append("<span style=\"color:red;\">") |
|
|
|
|
.append(lineSeg[i]) |
|
|
|
|
.append("</span><a href=\"tpl://") |
|
|
|
|
.append(tplLink[i], 1, tplLink[i].length() - 1) |
|
|
|
|
.append("\">") |
|
|
|
|
.append(tplLink[i]) |
|
|
|
|
.append("</a>"); |
|
|
|
|
} |
|
|
|
|
if (lineSeg.length > tplLink.length) { |
|
|
|
|
sb.append("<span style=\"color:red;\">").append(lineSeg[lineSeg.length-1]).append("</span>"); |
|
|
|
|
} |
|
|
|
|
sb.append("</span>"); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
Document doc = jTextArea.getStyledDocument(); |
|
|
|
|
HTMLDocument htmlDocument = (HTMLDocument) doc; |
|
|
|
|
htmlDocument.insertAfterEnd(htmlDocument.getCharacterElement(doc.getLength()), sb.toString()); |
|
|
|
|
} catch (BadLocationException | IOException ignored) { |
|
|
|
|
// 这里出问题不记录日志否则会导致死循环
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 尝试找到模板链接 |
|
|
|
|
* |
|
|
|
|
* @param s 可能含有模板链接的字符串 |
|
|
|
|
* @return 模板链接 |
|
|
|
|
*/ |
|
|
|
|
@Nullable |
|
|
|
|
private String[] tryFindTplLink(String s) { |
|
|
|
|
Document doc = jTextArea.getStyledDocument(); |
|
|
|
|
if (!(doc instanceof HTMLDocument)) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
Matcher matcher = pattern.matcher(s); |
|
|
|
|
List<String> list = new ArrayList<>(); |
|
|
|
|
while (matcher.find()) { |
|
|
|
|
list.add(matcher.group(0)); |
|
|
|
|
} |
|
|
|
|
return list.toArray(new String[0]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private String appendLocaleMark(String str, int style) { |
|
|
|
|
|
|
|
|
|
if (style == DesignerLogger.ERROR_INT) { |
|
|
|
|