Mega Code Archive

 
Categories / Java / Swing JFC
 

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);       }     });   } }