【问题标题】:Make JTextArea scroll so caret position is always displayed as user types more text使 JTextArea 滚动,以便在用户键入更多文本时始终显示插入符号位置
【发布时间】:2013-07-10 21:24:36
【问题描述】:

如何让JTextArea 滚动,以便在用户键入更多文本时始终显示插入符号的位置?

这对我来说似乎是一个愚蠢的问题,我觉得以前一定有人问过这个问题,但我已经搜索并找不到答案。

我有一个多行文本区域,嵌入在 JScrollPane 中。如果用户一直打字直到填满文本区域,最终插入符号会变得不可见(在显示的区域下方)并且用户无法看到他正在输入的内容。这似乎是默认行为,这似乎很奇怪。我需要做些什么来确保文本区域始终滚动到插入符号所在的行。

我应该提到在文本区域中启用了换行。

【问题讨论】:

  • 你能发一个SSCCE你试过的东西吗?
  • 您要求的实际上是默认行为 :-) 您一定在代码中做错了 :-) 我的猜测是,您必须在代码中使用 setBounds()/setXxXSize() 方法。看看这个code example,看看这是否不是默认行为。
  • 不发布源代码,因为它是我继承的一团糟。谢谢好牛!我希望有人会告诉我,我想要的行为是默认行为。在您的代码示例中,我看到: notesArea = new JTextArea(10, 10); notesScroller = new JScrollPane(); ... notesScroller.setViewportView(notesArea);通过调用 setViewportView(textArea) 将文本区域与滚动条关联或将文本区域传递给构造函数之间有区别吗?
  • @SteveCohen :请注意,我是如何向您发送此消息的,带有@符号和您的姓名,以前无法收到您的消息,因为没有相同的,只需访问此页面偶然地 :-)。实际上这两个东西之间没有区别,我想,它们都是一样的,我只是更喜欢setViewportView(...),来做我的事情:-)。是的,对于 cmets 中的代码,您可以将内容包含在 Acute 键之间(在 Escape 下,不按 Shift(使用 Shift 变为波浪号)),就像这个灰色区域 I AM CODE :-)。其余的你最欢迎并保持微笑:-)
  • @nIcEcOw - 再次感谢您,nIcEcOw。 setRows(), pack() 谁会喜欢它。我们也没有打电话。如果您将其放在答案中,我很乐意为此给予您信任。问题解决了!

标签: java swing scroll jscrollpane jtextarea


【解决方案1】:

在我看来,setXxXSize() 方法应与有限数量的组件一起使用,并牢记后面使用的 Layout,这取决于 Layout Manager 尊重程序员提供的大小提示。

因此对于像JTextArea 这样的组件,其RowsColumns 足以为Layout 关注点提供提示以计算其大小,不应与硬编码大小相关联,使用尽量多一些setXxXSize()方法。

这里我提供了相同的示例代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.EventHandler;
import javax.swing.*;

public class DialogWithScroller
{
    private JFrame frame;
    private JButton showButton;
    private MyDialog myDialog;

    private void displayGUI()
    {
        frame = new JFrame("Dialog ScrollPane Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel(new BorderLayout(5, 5));
        showButton = new JButton("Show Dialog");
        showButton.addActionListener((ActionListener)
                EventHandler.create(ActionListener.class,
                        DialogWithScroller.this, "buttonActions", ""));     
        contentPane.add(showButton);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }   

    public void buttonActions(ActionEvent ae)
    {
        myDialog = new MyDialog(frame
                , "TextArea with ScrollPane", true);
    }

    public static void main(String[] args)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                new DialogWithScroller().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class MyDialog extends JDialog
{
    private JTextArea tArea;
    private JButton hideButton;

    private ActionListener buttonActions =
                            new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent ae)
        {
            MyDialog.this.dispose();
        }
    };

    public MyDialog()
    {}

    public MyDialog(Frame owner, String title, boolean modal)
    {
        super(owner, title, modal);
        displayGUI();
    }

    private void displayGUI()
    {
        JPanel contentPane = new JPanel(
                        new BorderLayout(5, 5));
        contentPane.setBorder(
                BorderFactory.createTitledBorder(
                            "My Personal Text Area"));
        /*
         * Here one can simply initialize the
         * JTextArea like this too, using the
         * constructor itself for specifying
         * the Rows and Columns, which will
         * help the layout concern to determine
         * its size
         */
        tArea = new JTextArea(20, 20);
        tArea.setLineWrap(true);
        tArea.setWrapStyleWord(true);
        JScrollPane textScroller = new JScrollPane(tArea);
        //textScroller.setViewportView(tArea);

        hideButton = new JButton("Hide Dialog");
        hideButton.addActionListener(buttonActions);

        contentPane.add(textScroller, BorderLayout.CENTER);
        contentPane.add(hideButton, BorderLayout.PAGE_END);
        setContentPane(contentPane);
        pack();
        setLocationByPlatform(true);
        setVisible(true);
    }   
}

在容器上调用Window.pack() 始终被认为是一种明智的做法,这会调整此窗口的大小以适应其子组件的首选大小和布局。虽然像这样的调用,必须在程序员完成将所有组件添加到容器之后并且在将容器设置为可见状态之前进行

【讨论】:

    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2011-06-05
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    相关资源
    最近更新 更多