将表插入到html文件java swing中

时间:2015-07-20 11:48:26

标签: java html swing

我有一个带有两个JTextPanes的简单swing应用程序。在第一个我写一个HTML代码,在第二个我得到这个HTML定义的外观。我想要一个允许我在文档中插入表格的按钮。 这是我的代码:

public class TestEditor extends JFrame {
public TestEditor(){
    createConnection();
    createGUI();
}
private void createGUI(){
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    JScrollPane scroll1=new JScrollPane(text);
    JScrollPane scroll2=new JScrollPane(html);
    JSplitPane split=new JSplitPane();
    split.setLeftComponent(scroll1);
    split.setRightComponent(scroll2);
    split.setDividerLocation(0.5);
    split.setResizeWeight(0.5);
    getContentPane().add(split);
    table=new JButton("Insert table");
    table.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            StringBuilder builder=new StringBuilder("<table border=1>\n");
            for(int i=0;i<4;i++){
                builder.append("<tr>");
                for(int j=0;j<4;j++){
                    builder.append("<td></td>");
                }
            builder.append("</tr>\n");
            }
            builder.append("</table>\n");
            try{
                text.getStyledDocument().insertString(text.getCaretPosition(), builder.toString(), null);
            }catch(BadLocationException ex){
                ex.printStackTrace();
            }
        }
    });
    getContentPane().add(table, BorderLayout.SOUTH);
    setTitle("Test");
    setPreferredSize(new Dimension(600,300));
    pack();
}
private void createConnection(){
    text=new JTextPane();
    html=new JTextPane();
    html.setContentType("text/html");
    html.getStyledDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent e) {
            update();
        }
        @Override
        public void removeUpdate(DocumentEvent e) {
            update();
        }
        @Override
        public void changedUpdate(DocumentEvent e) {
            update();
        }
        private void update(){
            if(fromText) return;
            fromHtml=true;
            text.setText(html.getText());
            fromHtml=false;
        }
    });
    text.getStyledDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent e) {
            update();
        }
        @Override
        public void removeUpdate(DocumentEvent e) {
            update();
        }
        @Override
        public void changedUpdate(DocumentEvent e) {
            update();
        }
        private void update(){
            if(fromHtml) return;
            fromText=true;
            html.setText(text.getText());
            fromText=false;
        }
    });
}

public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new TestEditor().setVisible(true);
        }
    });
}
private JTextPane text;
private JTextPane html;
private boolean fromHtml, fromText;
private JButton table;

}

但是,这会将表格插入错误的位置,通常在结束标记&lt; / html&gt;之后。我的目标是将表插入到右侧编辑器中插入符号的位置。 我该怎么办?如何检测正确的位置?

1 个答案:

答案 0 :(得分:1)

我测试了您的代码,在编辑样式文档时它失败了,但是在编辑文本文档时它可以正常工作。原因很简单:当调用update()时,使用setText()将插入符号放在文档的末尾。然后在最后自然插入html代码。

理想情况下,您需要跟踪插入位置并在setText()之后巧妙地更新它。但这并不容易:如何管理插入或删除的文本?

所以这是一个提议:当单击“添加表”按钮时,检测哪个编辑器具有焦点(=插入位置相关的位置),并将html代码插入相应的编辑器中。

但是,在样式化文档中插入html代码的方式略有不同(以避免被转义):

HTMLEditorKit kit = (HTMLEditorKit) html.getEditorKit();
HTMLDocument doc = (HTMLDocument) html.getStyledDocument();
kit.insertHTML(doc, html.getCaretPosition(), builder.toString(), 0, 0, null);

所以你应该得到类似的东西:

Component c = getFocusOwner();
if(c==html){
    HTMLEditorKit kit = (HTMLEditorKit) html.getEditorKit();
    HTMLDocument doc = (HTMLDocument) html.getStyledDocument();
    kit.insertHTML(doc, html.getCaretPosition(), builder.toString(), 0, 0, null);
}else if(c==text){
    text.getStyledDocument().insertString(text.getCaretPosition(), builder.toString(), null);
}

此外,使按钮无法聚焦以避免getFocusOwner()检测按钮点击:

table.setFocusable(false);