3

我有一个在特定设置下不可编辑的 JTextArea。但是,在此设置下,用户仍然可以使用空格键和退格键。为了容纳空间,我有以下代码,

if (e.getKeyChar() == KeyEvent.VK_SPACE) {
    editor.insert(" ", editor.getCaretPosition());
}

不过,我遇到了退格问题。这个我试过了

if (e.getKeyChar() == KeyEvent.VK_BACK_SPACE) {
    editor.insert("\b", editor.getCaretPosition());
}

当按下退格键时,这似乎增加了一个很小的空间。没有空格那么大,按一次几乎看不出来。但这绝对不是退格键。更糟糕的情况是,我必须将所有字符复制到插入符号位置 - 1 并将它们附加到插入符号位置之后的所有字符,但我不喜欢这种解决方案。

4

1 回答 1

3

使用键绑定允许空格键和退格键具有关联的操作,然后在按下退格键时从 JTextArea 的文档中删除一个字符。

例如,

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

@SuppressWarnings("serial")
public class TextAreaFun extends JPanel {
   public static final String SPACE = "space";
   public static final String BACK_SPACE = "back space";
   private JTextArea textArea = new JTextArea(15, 50);

   public TextAreaFun() {
      // create our key bindings
      // only allow key presses to initiate an action if the JTextArea has focus
      int condition = JComponent.WHEN_FOCUSED;
      InputMap taInputMap = textArea.getInputMap(condition);
      ActionMap taActionMap = textArea.getActionMap();

      taInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), SPACE);
      taInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0),
            BACK_SPACE);
      taActionMap.put(SPACE, new KeyAction(textArea, SPACE));
      taActionMap.put(BACK_SPACE, new KeyAction(textArea, BACK_SPACE));

      // checkbox that stops all editing except for that specified in the 
      // key bindings above
      JCheckBox chkBox = new JCheckBox(new AbstractAction("Prevent Editing") {
         {
            putValue(SELECTED_KEY, Boolean.FALSE); // default to unchecked
            putValue(MNEMONIC_KEY, KeyEvent.VK_P);
         }

         @Override
         public void actionPerformed(ActionEvent evt) {
            boolean selection = (Boolean) getValue(SELECTED_KEY);
            textArea.setEditable(!selection);
         }
      });
      JPanel bottomPanel = new JPanel();
      bottomPanel.add(chkBox);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(new JScrollPane(textArea));
      add(Box.createVerticalStrut(10));
      add(bottomPanel);
   }

   private static void createAndShowGui() {
      TextAreaFun mainPanel = new TextAreaFun();

      JFrame frame = new JFrame("TextAreaFun");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
// action to be initiated by key bindings
class KeyAction extends AbstractAction {
   private PlainDocument textAreaDocument;
   private String title;

   public KeyAction(JTextArea textArea, String title) {
      this.textAreaDocument = (PlainDocument) textArea.getDocument();
      this.title = title;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      if (title.equals(TextAreaFun.SPACE)) {
         try {
            textAreaDocument.insertString(textAreaDocument.getLength(), " ",
                  null);
         } catch (BadLocationException e1) {
            e1.printStackTrace();
         }
      } else if (title.equals(TextAreaFun.BACK_SPACE)) {
         if (textAreaDocument.getLength() == 0) {
            return;
         }
         try {
            textAreaDocument.remove(textAreaDocument.getLength() - 1, 1);
         } catch (BadLocationException e1) {
            e1.printStackTrace();
         }
      }
   }
}
于 2012-04-22T01:06:14.320 回答