【问题标题】:How to make only the next line of JTextArea (+JScrollPane) editable如何仅使 JTextArea (+JScrollPane) 的下一行可编辑
【发布时间】:2014-10-06 16:52:12
【问题描述】:

所以我创建了一个服务器,效果很好,但是我有点卡在 GUI 上。你看,我希望它看起来像命令提示符,只有下一行是可编辑的,它不允许你删除任何其他文本。所以现在我有:

JTextArea ta = new JTextArea();
JScrollPane sp = new JScrollPane(ta);

然后是框架的东西......

    f.setTitle("Server");
    f.setBounds(ss.width - 600, 50, 550, 350);
    f.setResizable(false);
    f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//added window listener so closes socket connection first
    f.setAlwaysOnTop(true);

然后添加它:

    f.add(sc);
    jt.setBackground(Color.BLACK);
    jt.setForeground(Color.WHITE);
    //jt.setEditable(false);

最后,我用来输出到TextArea的方法:

public static void append(String text) {
    jt.append(text);
    jt.append("\n\n"+System.getProperty("user.name")+" / "+getIp()+" > ");
    jt.setCaretPosition(jt.getDocument().getLength());
}

现在我需要为用户在按下回车键后在 JTextArea 中键入的内容分配一个字符串:>?

jt.addActionListener(...{
    public void ActioEvent(ActionEvent e){
        String text = JTextArea.getLines().getLastLine().getText().replace(System.getProperty("user.name")+" / "+getIp()+"       > ", "");
    }
});

也许是这样的? 然后我需要它,以便只有“>”之后的部分是可编辑的?

【问题讨论】:

  • 在 JTextArea 下面使用一个 JTextField。
  • 但是,虽然这更容易,但这并不是我想要的真的
  • 怎么不是你想要的?除非我缺少某些要求,否则这正是您要寻找的。这是解决这个问题的标准方法。请注意,如果您担心的话,您可以修改文本组件的边框和其他内容,使它们看起来是一个组件。
  • 其实我猜你是对的,我只是认为在 JTextArea 本身会有一种方法。谢谢。
  • 只处理 JTextArea 中的事件,不允许对现有文本进行任何更改。应该很容易。

标签: java swing jscrollpane jtextarea


【解决方案1】:

执行此操作的方法是使用 DocumentFilter。这是 Java 中一个相当晦涩且很少使用的部分,而且远非易于使用。但是,它允许您在 UI(编辑富文本内容的地方)和底层模型(内容)之间插入 DocumentFilter。您通过过滤器传递所有“插入”和“删除”操作,过滤器可以接受、拒绝或修改它们。您可以对过滤器进行编码,使其仅允许修改命令行,而不允许修改提示。

正如我所说,这是一段相当困难的编码,而且 Document/DocumentFilter 结构具有很多复杂性,而您的特定应用程序并不需要这些复杂性。但是,它确实为您提供了所需的设施。

标准 Java 文档页面中有教程,但不是高级教程,而且我所知道的网络上的示例很少。

ProtectedTextComponent(感谢 camickr)提供了一个如何做类似事情的例子。

【讨论】:

  • this is a pretty hard piece of coding - 我同意 :) 如果您有兴趣,可以查看 Protected Text Component 为您处理此问题。
  • @camickr 这是一个很好的类,它简化了很多事情。介意我将它纳入我的答案吗?
  • 正如我在回答中所说,您将无法按原样使用该课程,但可以随意玩耍、定制和试验。
【解决方案2】:

使用CollectionJTextField
让用户键入JTextField,一旦按下enter,将控件移动到下一个JTextField,同时使上面的JTextField 不可编辑,并从中删除JScrollPane

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    我也同意 JTextArea/JTextField 方法是常见且更简单的方法。

    但是,如果您想稍微复杂一点,您可以查看Protected Text Component,它将为您完成大部分逻辑。

    ProtectedDocument 的当前实现只允许您为文档添加保护,而不是删除它,因此您需要做的第一件事是添加一个方法来“清除”所有受保护的文本片段。这很简单,您只需清除该类使用的 Map 中的条目即可。

    接下来,您需要替换 JTextPane 使用的默认“Enter”操作。您可以通过使用文本区域的Key Bindings 来做到这一点。有关一些基本信息,请参阅Key Bindings。在您的自定义操作中,您首先需要调用新创建的“clear(...)”方法。然后,您将文本添加到文本区域。最后,您将保护除最后“x”个字符之外的所有文本。

    【讨论】:

      猜你喜欢
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多