【问题标题】:Using JTextArea to simulate a text console使用 JTextArea 模拟文本控制台
【发布时间】:2010-10-07 22:59:54
【问题描述】:

我的目标是在 Java 中获得一个类似控制台的组件,不一定在 JTextArea 中,但这似乎是首先尝试的合乎逻辑的事情。输出很简单,使用 JTextArea 提供的方法,但输入是另一回事。我想截取输入,然后逐个字符地对其采取行动。我找到了一些使用 DocumentListener 处理模糊相关内容的示例,但它似乎不允许我轻松检查刚刚输入的内容,这是我需要决定如何对其采取行动的内容。

我这样做对吗?有没有更好的方法呢?

我附上了我的应用程序代码的相关部分。

public class MyFrame extends JFrame {
    public MyFrame() {
        Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize=new Dimension((int)(screenSize.width/2),(int)(screenSize.height/2));
        int x=(int)(frameSize.width/2);
        int y=(int)(frameSize.height/2);
        setBounds(x,y,frameSize.width,frameSize.height);


        console = new JTextArea("",25,80);
        console.setLineWrap(true);
        console.setFont(new Font("Monospaced",Font.PLAIN,15));
        console.setBackground(Color.BLACK);
        console.setForeground(Color.LIGHT_GRAY);
        console.getDocument().addDocumentListener(new MyDocumentListener());

        this.add(console);

    }

    JTextArea console;

}

class MyDocumentListener implements DocumentListener
{
    public void insertUpdate(DocumentEvent e)
    {
        textChanged("inserted into");
    }
    public void removeUpdate(DocumentEvent e)
    {
        textChanged("removed from");
    }
    public void changedUpdate(DocumentEvent e)
    {
        textChanged("changed");
    }
    public void textChanged(String action)
    {
        System.out.println(action);
    }
}

感谢您的帮助。

EDIT1:我尝试使用带有 DocumentFilter 的 JTextPane 来执行此操作,但是当我输入某些内容时,DocumentFilter 中的方法没有运行。我附上修改后的代码:

public class MyFrame extends JFrame {
    public MyFrame() {
        Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize=new Dimension((int)(screenSize.width/2),(int)(screenSize.height/2));
        int x=(int)(frameSize.width/2);
        int y=(int)(frameSize.height/2);
        setBounds(x,y,frameSize.width,frameSize.height);

        console = new JTextPane();
        //console.setLineWrap(true);
        console.setFont(new Font("Monospaced",Font.PLAIN,15));
        console.setBackground(Color.BLACK);
        console.setForeground(Color.LIGHT_GRAY);
        StyledDocument styledDoc = console.getStyledDocument();
            if (styledDoc instanceof AbstractDocument) {
            doc = (AbstractDocument)styledDoc;
            doc.setDocumentFilter(new DocumentSizeFilter());
        }

        this.add(console);

    }

    JTextPane console;
    AbstractDocument doc;

}

class DocumentSizeFilter extends DocumentFilter {

        public DocumentSizeFilter() {

    }

    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {
        System.out.println(str);
        if (str.equals("y")) {
            System.out.println("You have pressed y.");
        }
    }

    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)  throws BadLocationException {

    }

}

【问题讨论】:

    标签: java swing console jtextarea


    【解决方案1】:

    我想拦截输入并采取行动 它

    那么您可能应该使用 DocumentFilter。请参阅Implementing a Document Filter 了解更多信息。

    【讨论】:

    • 我已经尝试过了,但由于某种原因,结果并不令人满意。我已将新方法编辑到我的帖子中。
    • @abu dhabi,您是否复制了教程中的完整示例?我没有看到您的 replace() 方法代码。这是通过 GUI 编辑文本组件时调用的方法。当您使用 Document.insertString() 方法直接在程序中更新 Document 时,将调用 insertString() 方法。
    • 我将代码复制到了 replace() 方法,但也没有从那里调用。
    • 你真的复制教程中的代码并测试了吗?
    【解决方案2】:

    似乎有很多不同的方法可以自定义 Swing 文本组件。当我做与您类似的事情时,我在自定义文档方面取得了成功:

    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.PlainDocument;
    
    public class CustomDocument extends PlainDocument {
        @Override
        public void insertString(int offset, String string, AttributeSet attributeSet) throws BadLocationException {
            // Parse input - in this case convert everything to upper case
            string = string.toUpperCase();
            super.insertString(offset, string, attributeSet);
        }
    }
    

    这是一个能够测试代码的主要方法:

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 300, 300);
        frame.add(new JTextArea(new CustomDocument()));
        frame.setVisible(true);
    }
    

    【讨论】:

    • 这种方法似乎行不通;我在@Override 处收到一条错误下划线,表示我没有覆盖或重放任何方法。我还在attributeSet 变量处得到一个错误,这似乎对这个方法无效——但是,在super.insertString() 方法的调用中放置一个null 使它可以编译。我还遇到了一个运行时异常,它应该是 StyledDocument 而不是 PlainDocument,但通过改回 JTextArea 解决了这个问题。最后,当我在 //parse input 部分之后输入任何内容时,它不会被调用。
    • 我添加了导入和主要方法来演示用法。如果您需要 StyledDocument,则扩展 DefaultStyledDocument 或 HTMLDocument 而不是 PlainDocument。
    【解决方案3】:

    我在我构建的应用程序中使用文本区域作为控制台,该应用程序将签署 jar 文件。 JTextArea 有一个 append() 方法。

    JTextArea console=new JTextArea();
    console.append("Insert console text here \n") \\  \n for new line
    

    【讨论】:

      猜你喜欢
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多