java - 两个 swing 文档之间的双向连接

标签 java swing

我正在编写一个简单的 Java swing 应用程序。我有两个 JTextPanes。在第一个上我可以编写 html 代码,在第二个上我可以看到代码定义的外观。我的目标是在此文本 Pane 之间提供双向连接,这样,如果我在一个 Pane 中键入一些字符,我就会在第二个 Pane 中看到更改。这必须以两种方式起作用:我可以在代码 Pane 和内容 Pane 中键入内容,并且更改应该自动应用到另一个 Pane 。

我尝试使用两个 DocumentListener 对象来处理 DocumentEvents,但是如果我更改一个 Pane 的内容,它会触发一个事件,而第二个 Pane 正在修改并也会触发一个事件,并且它一直在重复,所以这不是一个好方法。在两个文本 Pane 上设置相同的文档实例也不起作用。

我该怎么办?这是我的代码。我现在有一个异常 IllegalStateException。

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);
    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) {
            text.setText(html.getText());
        }
        @Override
        public void removeUpdate(DocumentEvent e) {
            text.setText(html.getText());            
        }
        @Override
        public void changedUpdate(DocumentEvent e) {
            text.setText(html.getText());
        }
    });
    text.getStyledDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent e) {
            html.setText(text.getText());
        }
        @Override
        public void removeUpdate(DocumentEvent e) {
            html.setText(text.getText());
        }
        @Override
        public void changedUpdate(DocumentEvent e) {
            html.setText(text.getText());
        }
    });
}
/**
 * @param args the command line arguments
 */
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;

}

最佳答案

试试这个

import javax.swing.JTextPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JSplitPane;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import javax.swing.text.html.HTMLDocument;
import java.awt.event.FocusListener;
import java.awt.event.FocusEvent;

public final class TwoWayEditor extends JFrame{

    private JTextPane  textPane;
    private JTextPane  viewPane;    
    private JSplitPane contentPane;
    private static DocumentListener textPaneDocumentListener;
    private static DocumentListener viewPaneDocumentListener;

    @Override
    protected void frameInit(){
        super.frameInit();      
        this.setVisible(true);
        this.setBounds(0,0,500,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.selfInitialize();
    }

    private void selfInitialize(){  

        textPane    = new JTextPane();
        textPane.setContentType("text/plain");
        textPane.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent e){ textPane.getStyledDocument().addDocumentListener(textPaneDocumentListener);}
            @Override
            public void focusLost(FocusEvent e){ textPane.getStyledDocument().removeDocumentListener(textPaneDocumentListener); }
        });


        viewPane    = new JTextPane();
        viewPane.setContentType("text/html");       
        viewPane.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent e){viewPane.getStyledDocument().addDocumentListener(viewPaneDocumentListener);}
            @Override
            public void focusLost(FocusEvent e){viewPane.getStyledDocument().removeDocumentListener(viewPaneDocumentListener);}
        });

        viewPaneDocumentListener = new DocumentListener(){
            @Override
            public void changedUpdate(DocumentEvent e){
                textPane.setText(viewPane.getText());
            }
            @Override
            public void insertUpdate(DocumentEvent e){ textPane.setText(viewPane.getText());}
            @Override
            public void removeUpdate(DocumentEvent e){ textPane.setText(viewPane.getText());}
        };
        textPaneDocumentListener = new DocumentListener(){
            @Override
            public void changedUpdate(DocumentEvent e){
                viewPane.setText(textPane.getText());
            }
            @Override
            public void insertUpdate(DocumentEvent e){ viewPane.setText(textPane.getText()); }
            @Override
            public void removeUpdate(DocumentEvent e){ viewPane.setText(textPane.getText()); }
        };

        contentPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,textPane,viewPane);
        this.setContentPane(contentPane);

        contentPane.setDividerLocation(this.getWidth()/2);
    }

    public static void main(final String [] args){
        SwingUtilities.invokeLater(()->{ TwoWayEditor editor = new TwoWayEditor(); });
    }
}

关于java - 两个 swing 文档之间的双向连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31424899/

相关文章:

java - 有没有办法仅通过 key 对获取对和值映射的值?

Java 图标不会显示两次

java - 如何为图像添加聚光灯

java - 在构造函数中关闭 Jform

java - 如何使 JFileChooser 仅显示具有某些特定名称 Java 的文件夹

java - 为什么静态初始化程序允许在 Java 中重新初始化静态变量?

java - JNA:如何将指针传递给局部变量?

java - JTextPane 的轻量级替代品?

java - 将 JTable 编辑保存到二维数组

java - 尝试清空 JTable 时出现 ArrayIndexOutOfBoundsException