我有一个带有两个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;之后。我的目标是将表插入到右侧编辑器中插入符号的位置。 我该怎么办?如何检测正确的位置?
答案 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);