Add KeyStroke to JTextArea : Key Stroke « Swing JFC « Java






Add KeyStroke to JTextArea

 
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * TextAreaDemo.java requires no other files.
 */

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.GroupLayout;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.LayoutStyle;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;

public class TextAreaDemo extends JFrame implements DocumentListener {

  private JLabel jLabel1;
  private JScrollPane jScrollPane1;
  private JTextArea textArea;

  private static final String COMMIT_ACTION = "commit";

  private static enum Mode {
    INSERT, COMPLETION
  };

  private final List<String> words;
  private Mode mode = Mode.INSERT;

  public TextAreaDemo() {
    super("TextAreaDemo");
    initComponents();

    textArea.getDocument().addDocumentListener(this);

    InputMap im = textArea.getInputMap();
    ActionMap am = textArea.getActionMap();
    im.put(KeyStroke.getKeyStroke("ENTER"), COMMIT_ACTION);
    am.put(COMMIT_ACTION, new CommitAction());

    words = new ArrayList<String>(5);
    words.add("spark");
    words.add("special");
    words.add("spectacles");
    words.add("spectacular");
    words.add("swing");
  }

  private void initComponents() {
    jLabel1 = new JLabel("Try typing 'spectacular' or 'Swing'...");

    textArea = new JTextArea();
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    textArea.setColumns(20);
    textArea.setLineWrap(true);
    textArea.setRows(5);
    textArea.setWrapStyleWord(true);

    jScrollPane1 = new JScrollPane(textArea);

    GroupLayout layout = new GroupLayout(getContentPane());
    getContentPane().setLayout(layout);

    // Create a parallel group for the horizontal axis
    ParallelGroup hGroup = layout
        .createParallelGroup(GroupLayout.Alignment.LEADING);
    // Create a sequential and a parallel groups
    SequentialGroup h1 = layout.createSequentialGroup();
    ParallelGroup h2 = layout
        .createParallelGroup(GroupLayout.Alignment.TRAILING);
    // Add a scroll panel and a label to the parallel group h2
    h2.addComponent(jScrollPane1, GroupLayout.Alignment.LEADING,
        GroupLayout.DEFAULT_SIZE, 212, Short.MAX_VALUE);
    h2.addComponent(jLabel1, GroupLayout.Alignment.LEADING,
        GroupLayout.DEFAULT_SIZE, 212, Short.MAX_VALUE);

    // Add a container gap to the sequential group h1
    h1.addContainerGap();
    // Add the group h2 to the group h1
    h1.addGroup(h2);
    h1.addContainerGap();
    // Add the group h1 to hGroup
    hGroup.addGroup(Alignment.TRAILING, h1);
    // Create the horizontal group
    layout.setHorizontalGroup(hGroup);

    // Create a parallel group for the vertical axis
    ParallelGroup vGroup = layout
        .createParallelGroup(GroupLayout.Alignment.LEADING);
    // Create a sequential group
    SequentialGroup v1 = layout.createSequentialGroup();
    // Add a container gap to the sequential group v1
    v1.addContainerGap();
    // Add a label to the sequential group v1
    v1.addComponent(jLabel1);
    v1.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
    // Add scroll panel to the sequential group v1
    v1.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 100,
        Short.MAX_VALUE);
    v1.addContainerGap();
    // Add the group v1 to vGroup
    vGroup.addGroup(v1);
    // Create the vertical group
    layout.setVerticalGroup(vGroup);
    pack();

  }

  // Listener methods

  public void changedUpdate(DocumentEvent ev) {
  }

  public void removeUpdate(DocumentEvent ev) {
  }

  public void insertUpdate(DocumentEvent ev) {
    if (ev.getLength() != 1) {
      return;
    }

    int pos = ev.getOffset();
    String content = null;
    try {
      content = textArea.getText(0, pos + 1);
    } catch (BadLocationException e) {
      e.printStackTrace();
    }

    // Find where the word starts
    int w;
    for (w = pos; w >= 0; w--) {
      if (!Character.isLetter(content.charAt(w))) {
        break;
      }
    }
    if (pos - w < 2) {
      // Too few chars
      return;
    }

    String prefix = content.substring(w + 1).toLowerCase();
    int n = Collections.binarySearch(words, prefix);
    if (n < 0 && -n <= words.size()) {
      String match = words.get(-n - 1);
      if (match.startsWith(prefix)) {
        // A completion is found
        String completion = match.substring(pos - w);
        // We cannot modify Document from within notification,
        // so we submit a task that does the change later
        SwingUtilities.invokeLater(new CompletionTask(completion, pos + 1));
      }
    } else {
      // Nothing found
      mode = Mode.INSERT;
    }
  }

  private class CompletionTask implements Runnable {
    String completion;
    int position;

    CompletionTask(String completion, int position) {
      this.completion = completion;
      this.position = position;
    }

    public void run() {
      textArea.insert(completion, position);
      textArea.setCaretPosition(position + completion.length());
      textArea.moveCaretPosition(position);
      mode = Mode.COMPLETION;
    }
  }

  private class CommitAction extends AbstractAction {
    public void actionPerformed(ActionEvent ev) {
      if (mode == Mode.COMPLETION) {
        int pos = textArea.getSelectionEnd();
        textArea.insert(" ", pos);
        textArea.setCaretPosition(pos + 1);
        mode = Mode.INSERT;
      } else {
        textArea.replaceSelection("\n");
      }
    }
  }

  public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        // Turn off metal's use of bold fonts
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        new TextAreaDemo().setVisible(true);
      }
    });
  }

}

   
  








Related examples in the same category

1.Responding to KeystrokesResponding to Keystrokes
2.set Accelerator with KeyStroke
3.InputMap and KeyStrokeInputMap and KeyStroke
4.Overriding Many Default Typed Key Bindings in a JTextComponent
5.Install your own action to text component