2012-06-03 625 views
9

Necesito mostrar sugerencias (autocompletar) a medida que el usuario escribe en un JTextArea, algo así como el teléfono celular T9.¿Cómo mostrar autocompletar mientras escribo en JTextArea?

No sé cómo hacerlo en el evento myTextAreaKeyTyped().

Esta aplicación es un ayudante de mecanografía. Muestra variantes de caracteres no presentes en el teclado. E.G. Presiona 'A', muestra Â: 1, Á: 2, À: 3 ... 'A' será reemplazado si presiona 1,2 o 3. Ya está hecho, pero las variantes se muestran en un JLabel en el parte inferior de mi JFrame, porque no sé cómo hacer esto.

¿Pueden ayudarme? Gracias por adelantado.

+0

Buena pregunta, ¿Qué tienes hasta ahora? ¿Estamos usando un diccionario completo de inglés? O un subconjunto? – Coffee

+1

Sin duda no es exactamente lo que está buscando, pero eche un vistazo a la demostración "Autocompletar" de SwingLabs: http://swingx.java.net/ – Rekin

+0

Esta aplicación es un ayudante de mecanografía .. Muestra variantes de caracteres no- presente en el teclado .. EG Presiona A, muestra Â: 1, Á: 2, À: 3 ... 'A' será reemplazado si presiona 1,2 o 3 ... Ya está hecho, pero las sugerencias se muestran en un JLabel en la parte inferior de mi JFrame, porque IDK cómo hacerlo =/ –

Respuesta

11

Aquí hay un fragmento para inspirarte. Probablemente necesites reorganizar un poco el código para que sea más fácil de mantener, pero debería darte la esencia.

Básicamente, escuchamos los eventos clave (no me parece relevante escuchar eventos de documentos, por ejemplo, si el usuario pega algo de texto, no quiero que aparezca el panel de sugerencias), y cuando el cursor tiene al menos 2 caracteres detrás, hacemos algunas sugerencias, usando un menú emergente que contiene una lista J de sugerencias (aquí las sugerencias no son realmente significativas, pero no sería demasiado difícil vincular esto a un dictionario). En cuanto a los accesos directos que está mencionando, no debería ser demasiado difícil hacerlo.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Point; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JPopupMenu; 
import javax.swing.JTextArea; 
import javax.swing.ListSelectionModel; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.text.BadLocationException; 

public class Test { 

    public class SuggestionPanel { 
     private JList list; 
     private JPopupMenu popupMenu; 
     private String subWord; 
     private final int insertionPosition; 

     public SuggestionPanel(JTextArea textarea, int position, String subWord, Point location) { 
      this.insertionPosition = position; 
      this.subWord = subWord; 
      popupMenu = new JPopupMenu(); 
      popupMenu.removeAll(); 
      popupMenu.setOpaque(false); 
      popupMenu.setBorder(null); 
      popupMenu.add(list = createSuggestionList(position, subWord), BorderLayout.CENTER); 
      popupMenu.show(textarea, location.x, textarea.getBaseline(0, 0) + location.y); 
     } 

     public void hide() { 
      popupMenu.setVisible(false); 
      if (suggestion == this) { 
       suggestion = null; 
      } 
     } 

     private JList createSuggestionList(final int position, final String subWord) { 
      Object[] data = new Object[10]; 
      for (int i = 0; i < data.length; i++) { 
       data[i] = subWord + i; 
      } 
      JList list = new JList(data); 
      list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1)); 
      list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
      list.setSelectedIndex(0); 
      list.addMouseListener(new MouseAdapter() { 
       @Override 
       public void mouseClicked(MouseEvent e) { 
        if (e.getClickCount() == 2) { 
         insertSelection(); 
        } 
       } 
      }); 
      return list; 
     } 

     public boolean insertSelection() { 
      if (list.getSelectedValue() != null) { 
       try { 
        final String selectedSuggestion = ((String) list.getSelectedValue()).substring(subWord.length()); 
        textarea.getDocument().insertString(insertionPosition, selectedSuggestion, null); 
        return true; 
       } catch (BadLocationException e1) { 
        e1.printStackTrace(); 
       } 
       hideSuggestion(); 
      } 
      return false; 
     } 

     public void moveUp() { 
      int index = Math.min(list.getSelectedIndex() - 1, 0); 
      selectIndex(index); 
     } 

     public void moveDown() { 
      int index = Math.min(list.getSelectedIndex() + 1, list.getModel().getSize() - 1); 
      selectIndex(index); 
     } 

     private void selectIndex(int index) { 
      final int position = textarea.getCaretPosition(); 
      list.setSelectedIndex(index); 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        textarea.setCaretPosition(position); 
       }; 
      }); 
     } 
    } 

    private SuggestionPanel suggestion; 
    private JTextArea textarea; 

    protected void showSuggestionLater() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       showSuggestion(); 
      } 

     }); 
    } 

    protected void showSuggestion() { 
     hideSuggestion(); 
     final int position = textarea.getCaretPosition(); 
     Point location; 
     try { 
      location = textarea.modelToView(position).getLocation(); 
     } catch (BadLocationException e2) { 
      e2.printStackTrace(); 
      return; 
     } 
     String text = textarea.getText(); 
     int start = Math.max(0, position - 1); 
     while (start > 0) { 
      if (!Character.isWhitespace(text.charAt(start))) { 
       start--; 
      } else { 
       start++; 
       break; 
      } 
     } 
     if (start > position) { 
      return; 
     } 
     final String subWord = text.substring(start, position); 
     if (subWord.length() < 2) { 
      return; 
     } 
     suggestion = new SuggestionPanel(textarea, position, subWord, location); 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       textarea.requestFocusInWindow(); 
      } 
     }); 
    } 

    private void hideSuggestion() { 
     if (suggestion != null) { 
      suggestion.hide(); 
     } 
    } 

    protected void initUI() { 
     final JFrame frame = new JFrame(); 
     frame.setTitle("Test frame on two screens"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JPanel panel = new JPanel(new BorderLayout()); 
     textarea = new JTextArea(24, 80); 
     textarea.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1)); 
     textarea.addKeyListener(new KeyListener() { 

      @Override 
      public void keyTyped(KeyEvent e) { 
       if (e.getKeyChar() == KeyEvent.VK_ENTER) { 
        if (suggestion != null) { 
         if (suggestion.insertSelection()) { 
          e.consume(); 
          final int position = textarea.getCaretPosition(); 
          SwingUtilities.invokeLater(new Runnable() { 
           @Override 
           public void run() { 
            try { 
             textarea.getDocument().remove(position - 1, 1); 
            } catch (BadLocationException e) { 
             e.printStackTrace(); 
            } 
           } 
          }); 
         } 
        } 
       } 
      } 

      @Override 
      public void keyReleased(KeyEvent e) { 
       if (e.getKeyCode() == KeyEvent.VK_DOWN && suggestion != null) { 
        suggestion.moveDown(); 
       } else if (e.getKeyCode() == KeyEvent.VK_UP && suggestion != null) { 
        suggestion.moveUp(); 
       } else if (Character.isLetterOrDigit(e.getKeyChar())) { 
        showSuggestionLater(); 
       } else if (Character.isWhitespace(e.getKeyChar())) { 
        hideSuggestion(); 
       } 
      } 

      @Override 
      public void keyPressed(KeyEvent e) { 

      } 
     }); 
     panel.add(textarea, BorderLayout.CENTER); 
     frame.add(panel); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     try { 
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (InstantiationException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } catch (UnsupportedLookAndFeelException e) { 
      e.printStackTrace(); 
     } 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new Test().initUI(); 
      } 
     }); 
    } 

} 
+0

Esto funcionó para mí .. Muchas gracias ..: D –

Cuestiones relacionadas