客户需要自己改发送邮件XML的内容。但是因为客户是小白,所以决定写一个编辑器出来。
能修改字体、字号、字体颜色、高亮显示、加粗、斜体、下划线、添加超链接这些功能。插入图片的功能因为客户不需要,所以没做。
为了美观使用到了开源的alloy.jar ,下载地址:http://download.csdn.net/detail/levelmini/7298205
/**之前的代码无法生成高亮代码,字号设置也有问题。今天更新了代码片。效果图就不更新了。
*去掉了字号设置。能正确换行。唯一的遗憾就是添加高亮和添加超链接功能需要先写好其他内容之后再进行,否则生成的html代码会有小bug。无法和编辑器上显示的一样。
*/
代码如下:
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import org.dom4j.CDATA;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.tree.DefaultDocument;
import org.dom4j.tree.FlyweightCDATA;
public class ModifyMail extends JFrame {
private static final long serialVersionUID = -4780581099315563633L;
private final int WIDTH = 550;
private final int HEIGHT = 370;
private static final Font FONT1 = new Font("宋体", Font.BOLD, 14);
private static final Font FONT2 = new Font("宋体", Font.PLAIN, 12);
private static JPanel panel ;
private JComboBox<String> cbFont,cb;
private JComboBox<Integer>cbSize;
private Color color = Color.BLACK;
JTextPane jtp;
JButton mail;
JDialog dialog;
public ModifyMail(JDialog d) {
if (d != null) {
d.setVisible(false);
dialog = d;
}
JLabel label1 = getJLabel("选择要修改的文件", FONT1);
String[] option = {"Trade","Medical","National-Trade","National-Medical"};
cb= new JComboBox<String>(option);
JButton refresh = getButton("刷新", refresh());
JPanel p1 = getJPanel(label1,cb,refresh);
Icon icon = getIcon("font_color.png");
JButton fontColor = getButton("", icon, "字体颜色",getFontColor());
icon = getIcon("highLight.png");
JButton heightLight = getButton("", icon, "高亮显示",getHighColor());
// GraphicsEnvironment是一个抽象类,不能实例化,只能用其中的静态方法获取一个实例
// GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
//字体选择
// String [] str = environment.getAvailableFontFamilyNames();// 获取系统字体
String [] str = {"Arial","微软雅黑","宋体"};
cbFont = new JComboBox<String>(str);
cbFont.setSelectedItem("宋体");//默认宋体
cbFont.setToolTipText("字体");
cbFont.addActionListener(getFontName());
//加粗
icon = getIcon("Bold.png");
JButton bold = getButton("", icon, "加粗", getBold());
//斜体
icon = getIcon("Italic.png");
JButton italic = getButton("", icon, "斜体", getItalic());
//下划线
icon = getIcon("Underline.png");
JButton underline = getButton("", icon, "下划线", getUnderLine());
icon = getIcon("link.png");
mail = getButton("", icon, "超链接", getHyperLink());
final JPanel functionPane = getJPanel(cbFont,fontColor,heightLight,bold,italic,underline,mail);
functionPane.setVisible(true);
jtp = new JTextPane();
jtp.setFont(FONT1);
jtp.setContentType("text/html");
jtp.setText("0123456789");
jtp.setCursor(new Cursor(Cursor.TEXT_CURSOR));
JScrollPane jsp = new JScrollPane(jtp);
jsp.setPreferredSize(new Dimension(530,200));
JPanel p3 = getJPanel(jsp);
JButton ok = getButton("保存",getSave());
JButton cancel = getButton("取消",new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
ModifyMail.this.dispose();
dialog.setVisible(true);
}
});
JPanel p4 = getJPanel(ok,cancel);
panel = getJPanel(p1,functionPane,p3,p4);
init();
this.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
super.windowClosed(e);
dialog.setVisible(true);
}
});
}
/**
* 获取文件中的文本
* @return
*/
private ActionListener refresh() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String file = cb.getSelectedItem().toString();
String node = "";
if (file.equals("National-Trade")) {
node = "deptTrade";
}
if (file.equals("National-Medical")) {
node = "deptMedical";
}
if (file.equals("Trade")) {
node = "areaTrade";
}
if (file.equals("Medical")) {
node = "areaMedical";
}
jtp.setText("");
HTMLEditorKit htmledit=new HTMLEditorKit();
HTMLDocument doc=(HTMLDocument) jtp.getDocument();
String html = read(node);
System.out.println(html);
try {
htmledit.insertHTML(doc, 0, html, 0, 0, null);
} catch (BadLocationException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
};
}
private ActionListener getSave() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//获取修改的文件
String file = cb.getSelectedItem().toString();
//获取内容
String content = jtp.getText();
//处理内容
content = content.split("<body>")[1];
content = content.split("</body>")[0];
//格式化内容
// content = format(content);
// System.out.println(content);
//使用dom4j对mailbody.xml进行修改
// "Trade","Medical","National-Trade","National-Medical"
String node = "";
if (file.equals("National-Trade")) {
node = "deptTrade";
}
if (file.equals("National-Medical")) {
node = "deptMedical";
}
if (file.equals("Trade")) {
node = "areaTrade";
}
if (file.equals("Medical")) {
node = "areaMedical";
}
save(node,content);
showMessage("修改" + file + "成功!", "修改成功", "ok.png");
}
};
}
private ActionListener getHyperLink() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
new inputWindow();
}
};
}
private ActionListener getUnderLine() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if (jtp != null) {
StyledEditorKit kit = getStyledEditorKit(jtp);
MutableAttributeSet attr = kit.getInputAttributes();
boolean underline = (StyleConstants.isUnderline(attr)) ? false : true;
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setUnderline(sas, underline);
setCharacterAttributes(jtp, sas, false);
jtp.grabFocus();
}
}
};
}
private ActionListener getFontColor() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("打开调色板 ...");
Color c = color;
color = JColorChooser.showDialog(panel, "选择颜色", Color.BLACK);
color = (color==null?c:color);//这句废话是为了保证没选择任何颜色关闭调色板后,能还原原来的颜色
if (jtp != null) {
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setForeground(attr, color);
setCharacterAttributes(jtp, attr, false);
}
jtp.grabFocus();
}
};
}
private ActionListener getFontName() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String fontName = cbFont.getSelectedItem().toString();
if (jtp != null) {
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setFontFamily(attr, fontName);
setCharacterAttributes(jtp, attr, false);
}
jtp.grabFocus();
}
};
}
/**
* 初始化界面
*/
void init() {
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setFontFamily(attr, "宋体");
StyleConstants.setFontSize(attr, 12);
jtp.getStyledDocument().setCharacterAttributes(0, 0, attr, false);
// 设置程序显示在屏幕中间
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
int w = size.width;
int h = size.height;
int x = (w - WIDTH) / 2;
int y = (h - HEIGHT) / 2;
this.add(panel);
this.setBounds(x, y, WIDTH, HEIGHT);
this.setResizable(false);
this.setTitle("Mailbody Editor");
this.setVisible(true);
this.setAlwaysOnTop(true);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
/**
* 加粗
* @return
*/
private ActionListener getBold(){
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if (jtp != null) {
StyledEditorKit kit = getStyledEditorKit((JEditorPane)jtp);
MutableAttributeSet attr = kit.getInputAttributes();
boolean bold = (StyleConstants.isBold(attr)) ? false : true;
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setBold(sas, bold);
setCharacterAttributes(jtp, sas, false);
}
jtp.grabFocus();
}
};
}
private ActionListener getItalic(){
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if (jtp != null) {
StyledEditorKit kit = getStyledEditorKit(jtp);
MutableAttributeSet attr = kit.getInputAttributes();
boolean italic = (StyleConstants.isItalic(attr)) ? false : true;
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setItalic(sas, italic);
setCharacterAttributes(jtp, sas, false);
}
jtp.grabFocus();
}
};
}
public JLabel getJLabel(String text, Font font) {
JLabel label = new JLabel(text);
label.setFont(font);
return label;
}
/**
* 设置高亮
* @return
*/
private ActionListener getHighColor(){
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("打开调色板 ...");
Color c = color;
color = JColorChooser.showDialog(panel, "选择颜色", Color.BLACK);
color = (color==null?c:color);//这句废话是为了保证没选择任何颜色关闭调色板后,能还原原来的颜色
//------------------------------------------------------------------
//使用HTMLEditorKit显示高亮
HTMLEditorKit htmledit=new HTMLEditorKit();
HTMLDocument doc = (HTMLDocument) jtp.getDocument();
//获取选择的内容
String cont = jtp.getSelectedText();
//获取选择的位置
int start = jtp.getSelectionStart();
int end = jtp.getSelectionEnd();
//设置内容
cont = new StringBuffer("<span style=\"background-color:rgb(")
.append(color.getRed()).append(",")
.append(color.getGreen()).append(",")
.append(color.getBlue()).append(")\">")
.append(cont)
.append("</span>")
.toString();
try {
//这里一定要先从end插入然后再删除,否则选中第一个字符高亮的时候会出问题
htmledit.insertHTML(doc, end, cont, 0, 0, HTML.Tag.SPAN);
doc.remove(start, end - start);
} catch (BadLocationException ex) {
ex.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
//---------------------------------------------------------------------
jtp.grabFocus();
}
};
}
/**
* 获取一个JTextField
*
* @param name
* 输入框的名字
* @param length
* 输入框长度
* @param editable
* 是否可编辑
* @param formatText
* 默认显示的内容
* @param toolTip
* 提示信息
* @return JTextField
*/
public JTextField getTextField(String name, int length, boolean editable,
String formatText, String toolTip) {
JTextField text = new JTextField(formatText, length);
text.setName(name);
text.setEditable(editable);
text.setToolTipText(toolTip);
text.setFont(FONT2);
return text;
}
/**
* 获取一个JTextField
*
* @param length
* 输入框长度
* @param editable
* 是否可编辑
* @return
*/
public JTextField getTextField(int length, boolean editable) {
return getTextField(null, length, editable, null, null);
}
/**
* 获取一个JTextField
*
* @param 输入框的名字
* @param length
* 输入框长度
* @param editable
* 是否可编辑
* @return
*/
public JTextField getTextField(String name, int length, boolean editable) {
return getTextField(name, length, editable, null, null);
}
/**
* 获取一个带有监听器的JButton
*
* @param text
* button上显示的内容
* @param name
* 按钮的名字
* @param l
* 监听器。传入NULL则点击按钮显示文件选择器
* @return JButton
*/
public JButton getButton(String text, Icon icon, String name, ActionListener l) {
final JButton button = new JButton(text);
button.setName(name);
button.setIcon(icon);
button.setToolTipText(name);
if (l != null) {
button.addActionListener(l);
} else {
button.addActionListener(null);
}
return button;
}
/**
* 获取一个带有监听器的JButton
*
* @param text
* button上显示的内容
* @param l
* 监听器。传入NULL则点击按钮显示文件选择器
* @return JButton
*/
public JButton getButton(String text, ActionListener l) {
return getButton(text, null,text, l);
}
/**
* 返回一个JPanel。如果传入组件,则将传入的组件添加到这个JPanel中再返回
*
* @param name
* 容器的名字
* @param component
* 任意多个JComponent类型组件,按照要添加的顺序传入
* @return JPanel
*/
public JPanel getJPanel(String name, JComponent... component) {
JPanel panel = new JPanel();
panel.setName(name);
if (component != null) {
for (JComponent c : component) {
panel.add(c);
}
}
panel.setBackground(new Color(241, 241, 241));
return panel;
}
/**
* 返回一个JPanel。如果传入组件,则将传入的组件添加到这个JPanel中再返回
*
* @param component
* 任意多个JComponent类型 组件
* @return JPanel
*/
public JPanel getJPanel(JComponent... component) {
return getJPanel(null, component);
}
/**
* 获取 Icon 图标
*
* @param path
* 图标名
* @return icon
*/
public static Icon getIcon(String name) {
return new ImageIcon(getImage(name));
}
/**
* 获取 Image 图像
*
* @param name
* 图像名
* @return Image
*/
public static Image getImage(String name) {
String path = "res/icon/";
path = path + name;
Image image = Toolkit.getDefaultToolkit().getImage(path);
return image;
}
protected static final StyledEditorKit getStyledEditorKit(JEditorPane e) {
EditorKit k = e.getEditorKit();
if (k instanceof StyledEditorKit) {
return (StyledEditorKit) k;
}
throw new IllegalArgumentException("EditorKit must be StyledEditorKit");
}
protected static final StyledDocument getStyledDocument(JEditorPane e) {
Document d = e.getDocument();
if (d instanceof StyledDocument) {
return (StyledDocument) d;
}
throw new IllegalArgumentException("document must be StyledDocument");
}
public static final void setCharacterAttributes(JEditorPane editor, AttributeSet attr, boolean replace) {
int p0 = editor.getSelectionStart();
int p1 = editor.getSelectionEnd();
if (p0 != p1) {
StyledDocument doc = getStyledDocument(editor);
doc.setCharacterAttributes(p0, p1 - p0, attr, replace);
}
StyledEditorKit k = getStyledEditorKit(editor);
MutableAttributeSet inputAttributes = k.getInputAttributes();
if (replace) {
inputAttributes.removeAttributes(inputAttributes);
}
inputAttributes.addAttributes(attr);
}
void showInfo(String message, String title, String icon) {
JOptionPane.showMessageDialog(panel, message, title,
JOptionPane.INFORMATION_MESSAGE, getIcon(icon));
}
/**
* 运行程序的主要方法。 主要功能:应用主题、创建面板
*/
public static void invokeApp(final JDialog g) {
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
UIManager
.setLookAndFeel("com.incors.plaf.alloy.AlloyLookAndFeel");
new ModifyMail(g).init();
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void setButtonsEnable(boolean enabled) {
Component[] component = ((JPanel) panel.getComponent(6))
.getComponents();
for (Component comp : component) {
comp.setEnabled(enabled);
}
}
private class inputWindow extends JWindow{
private static final long serialVersionUID = -8362686600399865786L;
JTextField content,link;
public inputWindow() {
super(ModifyMail.this);
Point p = mail.getLocationOnScreen();
setBounds(p.x-135,p.y+25,200,90);
JLabel c = getJLabel("文字:",FONT2);
content = getTextField(23, true);
content.setToolTipText("显示的文字");
JLabel l = getJLabel("链接:", FONT2);
link = getTextField(23, true);
link.setToolTipText("链接地址");
JButton add = getButton("添加", insertLink());
JButton cancel = getButton("取消",calcel());
JPanel panel = getJPanel(c,content,l,link,add,cancel);
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
panel.setBackground(Color.WHITE);
panel.setBorder(LineBorder.createBlackLineBorder());
super.add(panel);
setBackground(Color.WHITE);
setVisible(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
private ActionListener calcel() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
inputWindow.this.dispose();
jtp.grabFocus();
}
};
}
/**
* 插入链接
* @return
*/
private ActionListener insertLink() {
return new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//文字
String contentString = content.getText().trim();
//链接
String url = link.getText().trim();
//判断是否输入了文字
if (null == contentString || "".equals((contentString.trim()))) {
contentString = url;
}
//判断是超链接还是邮箱后拼接字符串
StringBuffer str = new StringBuffer("<a href=\"");
if (url.contains("@")) {
str.append("mailto:");
}
str.append(url).append("\">").append(contentString).append("</a>");
contentString = str.toString();
//获取光标位置
int pos = jtp.getSelectionStart();
int end = jtp.getSelectionEnd();
try {
//使用HTMLEditorKit插入超链接
HTMLEditorKit htmledit=new HTMLEditorKit();
HTMLDocument doc=(HTMLDocument) jtp.getDocument();
doc.remove(pos, end-pos);
htmledit.insertHTML(doc, pos, contentString, 0, 0, HTML.Tag.A);
htmledit.insertHTML(doc, pos, " ", 0, 0, HTML.Tag.SPAN);
} catch (BadLocationException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
inputWindow.this.dispose();
jtp.grabFocus();
}
};
}
}
/**
* 保存内容到mailbody.xml
*/
private void save(String nodeName,String content){
SAXReader reader = new SAXReader();
File file = new File("conf\\mailbody.xml");
org.dom4j.Document doc = null;
try {
doc = reader.read(file);
doc.setXMLEncoding("UTF-8");
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = doc.getRootElement();
Element node = root.element(nodeName);
// node.setText(content);
content = "<div style=\"font-size:11.0pt;font-family: \'微软雅黑\',\'sans-serif\'\">\r\n"+content+"\r\n</div>";
CDATA cdata = new FlyweightCDATA(content.trim());
// node.setText("");
node.clearContent();
node.add(cdata);
try {
//设置输出的XML的格式
OutputFormat out = OutputFormat.createPrettyPrint();
//设置输出的编码方式
out.setEncoding("UTF-8");
//去空格
out.setTrimText(true);
// 设置XML文档的位置
XMLWriter writer = new XMLWriter(new FileOutputStream(file),out);
file.delete();
// 向XML文档中写入数据
writer.write(doc);
// 关闭流
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private String read(String nodeName){
SAXReader reader = new SAXReader();
File file = new File("conf\\mailbody.xml");
org.dom4j.Document doc = null;
try {
doc = reader.read(file);
doc.setXMLEncoding("UTF-8");
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = doc.getRootElement();
Element node = root.element(nodeName);
return node.getText();
}
/**
* 显示提示信息
*
* @param message
* 提示信息
* @param title
* 提示信息框的标题
* @param icon
* 提示信息的图标
*/
private static void showMessage(String message, String title, String icon) {
JOptionPane.showMessageDialog(panel, message, title,
JOptionPane.INFORMATION_MESSAGE, getIcon(icon));
}
}
运行效果如下图:
已经写好了增强版,在我的另外一篇博客。地址:http://blog.csdn.net/levelmini/article/details/32318837