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
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); |
|
} |
|
} |
|
} |
|
|
|
}
|
|
|