当前位置: 首页 > 面试题库 >

如何修改JTextArea中Tab键的行为?

谷良弼
2023-03-14
问题内容

我正在Java
Swing中创建一个表单,其中一个字段是JTextArea。当我Tab在所有其他字段上使用键时,它将焦点移至下一个小部件,但在中JTextArea,它将在文本中插入制表符(水平空格)。

如何修改此行为?


问题答案:
/*
    This is my understanding of how tabbing works. The focus manager
    recognizes the following default KeyStrokes for tabbing:

    forwards:  TAB or Ctrl-TAB
    backwards: Shift-TAB or Ctrl-Shift-TAB

    In the case of JTextArea, TAB and Shift-TAB have been removed from
    the defaults which means the KeyStroke is passed to the text area.
    The TAB KeyStroke inserts a tab into the Document. Shift-TAB seems
    to be ignored.

    This example shows different approaches for tabbing out of a JTextArea

    Also, a text area is typically added to a scroll pane. So when
    tabbing forward the vertical scroll bar would get focus by default.
    Each approach shows how to prevent the scrollbar from getting focus.
*/
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;

public class TextAreaTab extends JFrame
{
    public TextAreaTab()
    {
        Container contentPane = getContentPane();
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

        contentPane.add( nullTraversalKeys() );
        contentPane.add( writeYourOwnAction() );
        contentPane.add( useKeyListener() );
        contentPane.add( addTraversalKeys() );
    }

    //  Reset the text area to use the default tab keys.
    //  This is probably the best solution.

    private JComponent nullTraversalKeys()
    {
        JTextArea textArea = new JTextArea(3, 30);

        textArea.setText("Null Traversal Keys\n2\n3\n4\n5\n6\n7\n8\n9");
        JScrollPane scrollPane = new JScrollPane( textArea );
//        scrollPane.getVerticalScrollBar().setFocusable(false);

        textArea.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
        textArea.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);

        return scrollPane;
    }

    //  Replace the Tab Actions. A little more complicated but this is the
    //  only solution that will place focus on the component, not the
    //  vertical scroll bar, when tabbing backwards (unless of course you
    //  have manually prevented the scroll bar from getting focus).

    private JComponent writeYourOwnAction()
    {
        JTextArea textArea = new JTextArea(3, 30);
        textArea.setText("Write Your Own Tab Actions\n2\n3\n4\n5\n6\n7\n8\n9");
        JScrollPane scrollPane = new JScrollPane( textArea );

        InputMap im = textArea.getInputMap();
        KeyStroke tab = KeyStroke.getKeyStroke("TAB");
        textArea.getActionMap().put(im.get(tab), new TabAction(true));
        KeyStroke shiftTab = KeyStroke.getKeyStroke("shift TAB");
        im.put(shiftTab, shiftTab);
        textArea.getActionMap().put(im.get(shiftTab), new TabAction(false));

        return scrollPane;
    }

    //  Use a KeyListener

    private JComponent useKeyListener()
    {
        JTextArea textArea = new JTextArea(3, 30);
        textArea.setText("Use Key Listener\n2\n3\n4\n5\n6\n7\n8\n9");
        JScrollPane scrollPane = new JScrollPane( textArea );
        scrollPane.getVerticalScrollBar().setFocusable(false);

        textArea.addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e)
            {
                if (e.getKeyCode() == KeyEvent.VK_TAB)
                {
                    e.consume();
                    KeyboardFocusManager.
                        getCurrentKeyboardFocusManager().focusNextComponent();
                }

                if (e.getKeyCode() == KeyEvent.VK_TAB
                &&  e.isShiftDown())
                {
                    e.consume();
                    KeyboardFocusManager.
                        getCurrentKeyboardFocusManager().focusPreviousComponent();
                }
            }
        });

        return scrollPane;
    }

    //  Add Tab and Shift-Tab KeyStrokes back as focus traversal keys.
    //  Seems more complicated then just using null, but at least
    //  it shows how to add a KeyStroke as a focus traversal key.

    private JComponent addTraversalKeys()
    {
        JTextArea textArea = new JTextArea(3, 30);
        textArea.setText("Add Traversal Keys\n2\n3\n4\n5\n6\n7\n8\n9");
        JScrollPane scrollPane = new JScrollPane( textArea );
        scrollPane.getVerticalScrollBar().setFocusable(false);

        Set set = new HashSet( textArea.getFocusTraversalKeys(
            KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS ) );
        set.add( KeyStroke.getKeyStroke( "TAB" ) );
        textArea.setFocusTraversalKeys(
            KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set );

        set = new HashSet( textArea.getFocusTraversalKeys(
            KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS ) );
        set.add( KeyStroke.getKeyStroke( "shift TAB" ) );
        textArea.setFocusTraversalKeys(
            KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, set );

        return scrollPane;
    }

    class TabAction extends AbstractAction
    {
        private boolean forward;

        public TabAction(boolean forward)
        {
            this.forward = forward;
        }

        public void actionPerformed(ActionEvent e)
        {
            if (forward)
                tabForward();
            else
                tabBackward();
        }

        private void tabForward()
        {
            final KeyboardFocusManager manager =
                KeyboardFocusManager.getCurrentKeyboardFocusManager();
            manager.focusNextComponent();

            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    if (manager.getFocusOwner() instanceof JScrollBar)
                        manager.focusNextComponent();
                }
            });
        }

        private void tabBackward()
        {
            final KeyboardFocusManager manager =
                KeyboardFocusManager.getCurrentKeyboardFocusManager();
            manager.focusPreviousComponent();

            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    if (manager.getFocusOwner() instanceof JScrollBar)
                        manager.focusPreviousComponent();
                }
            });
        }
    }

    public static void main(String[] args)
    {
        TextAreaTab frame = new TextAreaTab();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}


 类似资料:
  • 问题内容: 如前所述,我想更改内的默认TAB行为(以使其充当类似或类似的组件) 这是事件动作 这是听众 我也尝试过evt.KEY_TYPED,没有任何喜悦。 有任何想法吗? 快速编辑:我也尝试代替 问题答案: 根据此类: 请注意,可以更短,根据[约书亚·戈德堡的意见,因为我们的目标是获得通过重写回默认行为: 这用于问题“ 我如何修改标签中的Tab键的行为JTextArea? ” 在以前的实现确实是

  • 问题内容: 是否有可能改变的,从命令行JSON文件? 例如,在package.json中: 更改 至 问题答案: 一种实现方法是使用“ json” npm软件包,例如: 另一种方法是使用jq CLI,例如:

  • 我正在尝试为一个服务制作一个GUI,它有一个JTextArea来查看消息,每条消息都写在一行上,如果需要的话还会进行文字包装。 消息通过一个套接字到达,所以我只使用一个.append(消息)来更新JTextArea,我需要将这些行限制为50或100,我不需要限制每行的字符数。 编辑 问题是每个客户端可以发送无限行,所有这些行都必须是可读的,所以这不是简单地检查JTextArea中的行数。我需要删除

  • 问题内容: 我一直在尝试为我的文本更改事件处理机制。就我的目的而言,只要。的文本发生更改,就必须触发一个事件。我尝试使用该接口,这是我的代码。 当文本区域的文本与硬编码的文本匹配时,什么也没发生。如何为此更改事件。 可以通过实现目标吗?如果可以,那怎么办? 问题答案: 我将通过(实际上是一个PlainDocument)获得JTextArea的文档,并使用DocumentListener来侦听更改。

  • 问题内容: 在不使用焦点侦听技术的情况下,java gui中捕获Tab键的最简单方法是什么? 问题答案: VK_TAB 是制表符常量。 然而: 请参阅:http : //docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html 要解决此问题,请将以下内容应用于触发关键事件的组件(例如,TextArea): 使用此方法,然后必须显

  • 问题内容: 有没有一种可靠的方法来计算字符串如何在JTextArea中划分为行? 我有一个固定宽度的JTextArea,当它被填充时,会添加一个新行并垂直扩展。 现在,我需要确切地知道哪一行中的字符。我可以使用字体指标来计算单个字符的宽度,但是我不知道这是否可靠,或者是否有更好的方法。 字体指标是“绝招”吗? 问题答案: 所有JTextComponent都具有和可以提供帮助的方法,但也许更好的是j