2015-07-20 32 views
0

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

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; 

}

然而,这种插入表错了地方,最常见的结束标记</HTML >后。我的目标是将插入的表插入右侧编辑器中的插入符号的位置。 我该怎么办?如何检测正确的位置?

回答

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