帆软报表设计器源代码。
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.
 
 
 
 

251 lines
8.6 KiB

package com.fr.design.dialog;
import com.fr.base.GraphHelper;
import com.fr.design.dialog.link.MessageWithLink;
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.i18n.Toolkit;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* 带链接的错误详情弹窗
*
* @author hades
* @version 10.0
* Created by hades on 2021/8/2
*/
public class UIDetailErrorLinkDialog extends UIDialog {
private static final Color LINK_COLOR = new Color(51, 152, 253);
private static final int GAP_5 = 5;
private static final int GAP_10 = 10;
private static final String TAG_A_START = "<a>";
private static final String TAG_A_END = "</a>";
private static final double SCALE = 1.2;
private final Dimension dimension = new Dimension(300, 180);
public static Builder newBuilder() {
return new Builder();
}
private UIDetailErrorLinkDialog(Frame parent, Builder builder) {
super(parent);
init(builder);
}
private UIDetailErrorLinkDialog(Dialog parent, Builder builder) {
super(parent);
init(builder);
}
private void init(Builder builder) {
this.setTitle(builder.title);
// 顶部 图标和提示
UILabel errorIcon = new UILabel(IOUtils.readIcon("com/fr/design/images/lookandfeel/Information_Icon_Error_32x32.png"));
UILabel errorInfo= new UILabel(builder.reason);
JPanel topPane = new JPanel(new FlowLayout(FlowLayout.LEFT, GAP_10, GAP_5));
topPane.add(errorIcon);
topPane.add(errorInfo);
// 中部 详细内容
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(BorderFactory.createEmptyBorder(0, GAP_5,0,0));
UILabel errorCodeLabel = new UILabel(Toolkit.i18nText("Fine_Design_Basic_Error_Code", builder.errorCode));
UILabel link = new UILabel(Toolkit.i18nText("Fine_Design_Basic_Show_Error_Stack"));
link.setForeground(LINK_COLOR);
link.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
StringWriter stackTraceWriter = new StringWriter();
builder.throwable.printStackTrace(new PrintWriter(stackTraceWriter));
StackPane stackPane = new StackPane(stackTraceWriter.toString());
BasicDialog dialog = stackPane.showLargeWindow(UIDetailErrorLinkDialog.this, null);
dialog.setVisible(true);
}
});
contentPane.add(errorCodeLabel, BorderLayout.NORTH);
contentPane.add(createComponent(builder), BorderLayout.CENTER);
contentPane.add(link, BorderLayout.SOUTH);
// 确定 + 取消
JPanel actionPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, GAP_10, GAP_5));
actionPane.add(createButton(Toolkit.i18nText("Fine-Design_Report_OK")));
actionPane.add(createButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")));
this.getContentPane().add(topPane, BorderLayout.NORTH);
this.getContentPane().add(contentPane, BorderLayout.CENTER);
this.getContentPane().add(actionPane, BorderLayout.SOUTH);
this.setSize(dimension);
this.setResizable(false);
this.setModal(true);
GUICoreUtils.centerWindow(this);
}
private UIButton createButton(String content) {
UIButton button = new UIButton(content);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
UIDetailErrorLinkDialog.this.dispose();
}
});
return button;
}
private JComponent createComponent(Builder builder) {
JPanel panel = new JPanel(new BorderLayout());
boolean existDetailReason = StringUtils.isNotEmpty(builder.detailReason);
int maxWidth = dimension.width;
if (existDetailReason) {
String message = Toolkit.i18nText("Fine_Design_Basic_Detail_Error_Info", builder.detailReason);
UILabel label = new UILabel(message);
maxWidth = Math.max(maxWidth, GraphHelper.getWidth(message, label.getFont()));
panel.add(label, BorderLayout.NORTH);
}
String solution = existDetailReason ? builder.solution : Toolkit.i18nText("Fine_Design_Basic_Detail_Error_Info", builder.solution);
if (builder.solution.contains(TAG_A_START)) {
String[] solutionP1 = solution.split(TAG_A_START);
String[] solutionP2 = solutionP1[1].split(TAG_A_END);
MessageWithLink messageWithLink;
if (solutionP2.length == 2) {
messageWithLink = new MessageWithLink(solutionP1[0], solutionP2[0], builder.link, solutionP2[1]);
} else {
messageWithLink = new MessageWithLink(solutionP1[0], solutionP2[0], builder.link);
}
panel.add(messageWithLink, BorderLayout.CENTER);
} else {
UILabel solutionLabel = new UILabel(solution);
panel.add(solutionLabel, BorderLayout.CENTER);
}
dimension.width = getMaxDimensionWidth(maxWidth, solution);
return panel;
}
private int getMaxDimensionWidth(int width, String solution) {
int maxWidth = GraphHelper.getWidth(solution, DesignUtils.getDefaultGUIFont());
if (maxWidth >= width) {
maxWidth = (int) (SCALE * maxWidth);
} else {
maxWidth = width;
}
return maxWidth;
}
@Override
public void checkValid() throws Exception {
// do nothing
}
class StackPane extends BasicPane {
public StackPane(String stack) {
setLayout(new BorderLayout());
UITextArea textArea = new UITextArea();
textArea.setEditable(false);
textArea.setText(stack);
UIScrollPane scrollPane = new UIScrollPane(textArea);
add(scrollPane);
// 滚动条默认在顶部
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
scrollPane.getViewport().setViewPosition(new Point(0, 0));
}
});
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine_Design_Basic_Error_Stack");
}
}
public static class Builder {
private Window window;
private String title;
private String reason;
private String errorCode;
private String detailReason;
private String solution;
private String link;
private Throwable throwable;
private Builder() {
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setReason(String reason) {
this.reason = reason;
return this;
}
public Builder setErrorCode(String errorCode) {
this.errorCode = errorCode;
return this;
}
public Builder setSolution(String solution) {
this.solution = solution;
return this;
}
public Builder setDetailReason(String detailReason) {
this.detailReason = detailReason;
return this;
}
public Builder setThrowable(Throwable throwable) {
this.throwable = throwable;
return this;
}
public Builder setWindow(Window window) {
this.window = window;
return this;
}
public Builder setLink(String link) {
this.link = link;
return this;
}
public UIDetailErrorLinkDialog build() {
if (this.window instanceof Frame) {
return new UIDetailErrorLinkDialog((Frame) window, this);
} else {
return new UIDetailErrorLinkDialog((Dialog) window, this);
}
}
}
}