如何在自动填充应用程序中创建建议列表?

时间:2011-10-25 03:48:37

标签: java swing autocomplete

我正在制作一个自动填充应用程序,我的单词列表来自我的数据库。我有一个文本字段,现在我想制作一个建议列表,每次输入内容时都会显示在字段下方。你能给我一些提示或想法怎么做吗?提前谢谢。

2 个答案:

答案 0 :(得分:1)

如果你使用JCombobox会更好,但如果你使用的是Jtextfield,我建议你使用Jlist并放入JWindow,因为你使用的是textfield,这就是我在Dictionary应用程序中尝试过的。

编辑:

public class MainMenu extends JPanel
{

private final Connection connection;

private final Application application;


private JTextField word = new JTextField(10);

private final JButton translate = new JButton();

private final JComboBox translators = new JComboBox();

private final JButton search = new JButton();
private JList speechPartAndDefinitionWidget;

private final DefaultListModel speechPartAndDefinitionWidgetModel = new DefaultListModel();

private Translator translator;
private Suggestor suggestor;

private DefaultListModel translatedWidgetModel;
private JList translatedWidget;

private final DefaultListModel suggestionWidgetModel = new DefaultListModel();
private final JList suggestionWidget = new JList(suggestionWidgetModel);

private JavaWindow javaWindow = new JavaWindow(suggestionWidget);

public MainMenu(Application application, Connection connection)
{

    word.getDocument().addDocumentListener(new DocumentListener()
    {
        public void insertUpdate(DocumentEvent e)
        {
            try
            {
                onWordUpdated(word.getText());
            }
            catch (ClassNotFoundException e1)
            {
                e1.printStackTrace();
            }
            catch (SQLException e1)
            {
                e1.printStackTrace();
            }
        }

        public void removeUpdate(DocumentEvent e)
        {
            try
            {
                onWordUpdated(word.getText());
            }
            catch (ClassNotFoundException e1)
            {
                e1.printStackTrace();
            }
            catch (SQLException e1)
            {
                e1.printStackTrace();
            }
        }

        public void changedUpdate(DocumentEvent e)
        {
            try
            {
                onWordUpdated(word.getText());
            }
            catch (ClassNotFoundException e1)
            {
                e1.printStackTrace();

            }
            catch (SQLException e1)
            {
                e1.printStackTrace();

            }
        }
    });


    this.application = application;
    this.connection = connection;

    translators.setFocusable(false);
    word.grabFocus();
    word.requestFocus();
    word.setFocusable(true);

    search.setText("<html><b><u>S</u>earch</b></html>");
    translate.setText("<html><b><u>T</u>ranslate</b></html>");

    translators.addItem(new EnglishBisayaTranslator(connection));
    setToolTipText("English-Bisaya");
    translators.addItem(new BisayaEnglishTranslator(connection));
    setToolTipText("Bisaya-English");

    setLayout(new BorderLayout());
    JPanel formX = new JPanel();
    formX.setLayout(new BorderLayout());

    JPanel header = new JPanel();
    header.setLayout(new GridBagLayout());
    header.add(translators);
    header.add(word);
    header.add(search);
    header.add(translate);

    translators.setBorder(BorderFactory.createEtchedBorder(1));
    translators.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
    word.setBorder(BorderFactory.createEtchedBorder());
    word.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
    word.setFont(new Font("Garamond", Font.BOLD, 17));
    suggestionWidget.setFont(new Font("Calibri", Font.BOLD, 17));
    header.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 8));


    formX.add(BorderLayout.PAGE_START, header);
    formX.setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 10));
    add(header, BorderLayout.NORTH);

    speechPartAndDefinitionWidget = new JList(speechPartAndDefinitionWidgetModel);
   speechPartAndDefinitionWidget.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    speechPartAndDefinitionWidget.addListSelectionListener(new ListSelectionListener()
    {
        public void valueChanged(ListSelectionEvent ev)
        {
            onDefinitionSelected(ev);
        }
    });

    JPanel formBottom = new JPanel();
    formBottom.setLayout(new GridBagLayout());
    add(formBottom, BorderLayout.CENTER);
    Component up = new JScrollPane(speechPartAndDefinitionWidget);
    formBottom.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 10));   speechPartAndDefinitionWidget.setBorder(BorderFactory.createLineBorder(Color.black,1));

    JPanel down = new JPanel();
    down.setLayout(new BorderLayout());
    down.setBorder(BorderFactory.createLineBorder(Color.black, 1));
    down.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));


    down.add(translatedWidget = new JList(translatedWidgetModel = new DefaultListModel()));
    add(down, BorderLayout.CENTER);
    translatedWidget.setBorder(BorderFactory.createLineBorder(Color.black, 1));
    translatedWidget.setFont(new Font("Calibri",Font.BOLD, 17));
     speechPartAndDefinitionWidget.setFont(new Font("Calibri", Font.BOLD, 17));
    add(BorderLayout.CENTER, new JSplitPane(JSplitPane.VERTICAL_SPLIT, up, down));

    word.addKeyListener(new KeyAdapter()
    {
        public void keyPressed(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
            {
                hideSuggestionWindowToBack();
            }
            else if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
                int selectedIndex = suggestionWidget.getSelectedIndex();

                if (selectedIndex == -1)
                {
                    onSearchClick();
                }
                else
                {
                    onSuggestionSelected(selectedIndex);

                }
            }
        }

        public void keyReleased(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
                hideSuggestionWindowToBack();
                onSearchClick();
            }
        }
    });

    translators.addActionListener(new

            ActionListener()
            {
                public void actionPerformed
                        (ActionEvent e)
                {
                    onTranslatorsClick();
                }
            }

    );

    word.addKeyListener(new

            KeyAdapter()
            {
                public void keyPressed
                        (KeyEvent
                                 e)
                {
                    if (suggestionWidgetModel.isEmpty())
                    {
                        return;
                    }

                    if (e.getKeyCode() == KeyEvent.VK_DOWN)
                    {
                        final Point location = word.getLocationOnScreen();
                        javaWindow.setLocation(location.x, location.y + word.getHeight());
                        showSuggestionWindowToBack();

                        int currentSelectedItemIndex = suggestionWidget.getSelectedIndex();
                        if (currentSelectedItemIndex == -1 || currentSelectedItemIndex == suggestionWidgetModel.size() - 1)
                        {
                            suggestionWidget.setSelectedIndex(0);

                        }
                        else if (currentSelectedItemIndex < suggestionWidgetModel.size() - 1)
                        {
                            suggestionWidget.setSelectedIndex(currentSelectedItemIndex + 1);
                        }
                    }
                    else if (e.getKeyCode() == KeyEvent.VK_UP)
                    {
                        int currentSelectedItemIndex = suggestionWidget.getSelectedIndex();
                        if (currentSelectedItemIndex == -1 || currentSelectedItemIndex == suggestionWidgetModel.size() + 1)
                        {
                            suggestionWidget.setSelectedIndex(0);
                        }
                        else if (currentSelectedItemIndex < suggestionWidgetModel.size() + 1)
                        {
                            suggestionWidget.setSelectedIndex(currentSelectedItemIndex - 1);

                        }
                    }
                }

            }
    );


    suggestionWidget.addMouseListener(new MouseAdapter()
    {
        @Override
        public void mousePressed(MouseEvent e)
        {
            int selectedIndex = suggestionWidget.getSelectedIndex();

            if (e.getClickCount() == 2)
            {
                if (selectedIndex < -1)
                {
                    onSearchClick();
                }
                else
                {
                    onSuggestionSelected(selectedIndex);
                    hideSuggestionWindowToBack();
                }
            }

        }

        public void mouseReleased(MouseEvent e)
        {
            if (e.getClickCount() == 2)
            {
                {
                    hideSuggestionWindowToBack();
                }
            }
        }
    });

    speechPartAndDefinitionWidget.addKeyListener(new

            KeyAdapter()
            {
                @Override
                public void keyPressed
                        (KeyEvent
                                 e)
                {
                    if (speechPartAndDefinitionWidgetModel.isEmpty())
                    {
                        return;
                    }

                    if (e.getKeyCode() == KeyEvent.VK_DOWN)
                    {

                        int currentSelectedItemIndex = speechPartAndDefinitionWidget.getSelectedIndex();
                        if (currentSelectedItemIndex == -1 || currentSelectedItemIndex == speechPartAndDefinitionWidgetModel.size() - 1)
                        {
                            speechPartAndDefinitionWidget.setSelectedIndex(0);

                        }
                        else if (currentSelectedItemIndex < speechPartAndDefinitionWidgetModel.size() - 1)
                        {
                            speechPartAndDefinitionWidget.setSelectedIndex(currentSelectedItemIndex + 1);
                            onTranslate();
                        }
                    }
                    else if (e.getKeyCode() == KeyEvent.VK_UP)
                    {
                        int currentSelectedItemIndex = speechPartAndDefinitionWidget.getSelectedIndex();
                        if (currentSelectedItemIndex == -1 || currentSelectedItemIndex == speechPartAndDefinitionWidgetModel.size() + 1)
                        {
                            speechPartAndDefinitionWidget.setSelectedIndex(0);
                        }
                        else if (currentSelectedItemIndex < speechPartAndDefinitionWidgetModel.size() + 1)
                        {
                            speechPartAndDefinitionWidget.setSelectedIndex(currentSelectedItemIndex - 1);
                        }
                    }

                }
            }
    );

    speechPartAndDefinitionWidget.addMouseMotionListener(new MouseMotionAdapter()
    {
        @Override
        public void mouseMoved(MouseEvent e)
        {
            final int x = e.getX();
            final int y = e.getY();


            final Rectangle cellBounds = speechPartAndDefinitionWidget.getCellBounds(0, speechPartAndDefinitionWidget.getModel().getSize() - 1);
            if (cellBounds != null && cellBounds.contains(x, y))
            {
                speechPartAndDefinitionWidget.setCursor(new Cursor(Cursor.HAND_CURSOR));
            }
            else
            {
                speechPartAndDefinitionWidget.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        }
    }
    );

    speechPartAndDefinitionWidget.setCellRenderer(new

            DefaultListCellRenderer()
            {
                @Override
                public Component getListCellRendererComponent
                        (JList
                                 list, Object
                                value, int index,
                         boolean isSelected,
                         boolean cellHasFocus)
                {
                    final String speechPart = ((DefinitionUiModel) value).getPart().getFriendlyName();
                    final String definition = ((DefinitionUiModel) value).getDefinition().toString();
                    Color bg = null;
                    Color fg = null;

                    final JLabel renderer = new JLabel(
                            "<html><font color=red>" + speechPart + "</font>) => <font color=black>" + definition + "</font></html>");
                    if (renderer.isEnabled())
                    {

                        if (isSelected)
                        {
                            renderer.setText("<html><font color=gray>" + speechPart + "</font><font color=blue><u><b>" + definition + "</b></u></font></html>");
                            renderer.setCursor(new Cursor(Cursor.HAND_CURSOR));
                        }

                        JList.DropLocation dropLocation = list.getDropLocation();
                        if (dropLocation != null
                                && !dropLocation.isInsert()
                                && dropLocation.getIndex() == index)
                        {

                            bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground");
                            fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground");

                            isSelected = true;
                        }

                        if (isSelected)
                        {
                            renderer.setBackground(bg == null ? list.getSelectionBackground() : bg);
                            renderer.setForeground(fg == null ? list.getSelectionForeground() : fg);
                        }

                        Border border = null;

                        if (cellHasFocus)
                        {

                            if (isSelected)
                            {
                                border = DefaultLookup.getBorder(this, ui, "List.focusSelectedCellHighlightBorder");
                            }
                            if (border == null)
                            {
                                border = DefaultLookup.getBorder(this, ui, "List.focusCellHighlightBorder");
                            }
                        }

                        else
                        {

                        }


                    }
                    return renderer;
                }
            }

    );


    translatedWidget.setForeground(Color.black);

    translate.addActionListener(new

            ActionListener()
            {
                public void actionPerformed
                        (ActionEvent
                                 e)
                {
                    onTranslate();
                }
            }

    );
    search.setToolTipText("find");
    search.addActionListener(new

            ActionListener()
            {
                public void actionPerformed
                        (ActionEvent
                                 e)
                {
                    onSearchClick();

                }

            }

    );
    translators.setSelectedIndex(0);

    suggestionWidget.setBorder(BorderFactory.createLineBorder(Color.gray, 1));

    onTranslatorsClick();

}

private void onSuggestionSelected(int selectedIndex)
{
    String hold = (String) suggestionWidgetModel.getElementAt(selectedIndex);
    word.setText(hold);
    hideSuggestionWindowToBack();
    suggestionWidgetModel.clear();


    if (javaWindow == null)
    {
        javaWindow.dispose();
        javaWindow = null;

    }


}

public void onWordUpdated(final String toComplete) throws ClassNotFoundException, SQLException
{
    new Thread(new Runnable()
    {
        public void run()
        {
            try
            {
                final List<Suggestion> suggestions = suggestor.getSuggestions(toComplete);

                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        speechPartAndDefinitionWidgetModel.clear();
                        translatedWidgetModel.clear();
                        suggestionWidgetModel.clear();
                        try
                        {
                            for (Suggestion suggestion : suggestions)
                            {
                                suggestionWidgetModel.addElement(suggestion.getCaption());
                            }
                            if (!suggestions.isEmpty())
                            {
                                suggestionWidget.setSelectedIndex(0);

                                if (javaWindow == null)
                                {
                                    javaWindow = new JavaWindow(suggestionWidget);
                                }
                                else
                                {
                                    final Point location = word.getLocationOnScreen();
                                    javaWindow.setLocation(location.x, location.y + word.getHeight());
                                }
                                showSuggestionWindowToBack();
                            }
                            else
                            {
                                hideSuggestionWindowToBack();
                            }
                        }
                        catch (Exception exception)
                        {
                            exception.printStackTrace();
                        }
                    }
                });
            }
            catch (SQLException e)

            {
                onSqlError(e);
            }
        }
    }
            , "onWordUpdated").

            start();

}

private void onTranslate()
{
    try
    {
        translatedWidgetModel.clear();

        String lookupWord = word.getText();
        if (lookupWord != null)
        {
            Collection<String> bisayaWords = this.translator.translateSimple(lookupWord);

            for (String bisayaWord : bisayaWords)
            {
                translatedWidgetModel.addElement(bisayaWord.toUpperCase());

            }
        }
    }
    catch (SQLException ex)
    {
        onSqlError(ex);
    }
}

private void onSqlError(SQLException ex)
{
    JOptionPane.showMessageDialog(null, "SQL Error! :" + ex.getMessage());
}


private void onDefinitionSelected(ListSelectionEvent ev)
{
    if (!ev.getValueIsAdjusting())
    {
        int selectedIndex = speechPartAndDefinitionWidget.getSelectedIndex();

        if (selectedIndex != -1)
        {
            final DefinitionUiModel definitionUiModel = (DefinitionUiModel) speechPartAndDefinitionWidgetModel.get(selectedIndex);
            translate(definitionUiModel.getDefinition());
        }
    }
}

private void translate(Definition definition)
{
    try
    {
        translatedWidgetModel.clear();

        Map<String, String> map = new HashMap<String, String>();
        int definitionId = definition.getId();
        String definitionName = definition.getValue();


        int nameId = translator.getFromDictionary().getNameIdForDefinitionId(definitionId);

        if (nameId > -1)
        {
            final Collection<String> translation = translator.translateSimple(nameId);
            for (String transWord : translation)
            {
                map.put(transWord, definitionName);

                for (Map.Entry<String, String> entry : map.entrySet())
                {

                    String myValue = entry.getKey().toUpperCase() + " -- " + entry.getValue();
                    translatedWidgetModel.addElement(myValue);
                }
            }
        }
    }
    catch (SQLException ex)
    {
        onSqlError(ex);
    }
}


private void onSearchClick()
{
    search.setEnabled(true);
    hideSuggestionWindowToBack();
    speechPartAndDefinitionWidgetModel.clear();
    translatedWidgetModel.clear();

    try
    {
        final String lookupWord = word.getText();

        if (lookupWord != null)
        {
            final Dictionary fromDictionary = translator.getFromDictionary();

            final WordDefinitions definitions = fromDictionary.getWordDefinitions(lookupWord);

            final Iterator<Map.Entry<SpeechPart, List<Definition>>> items = definitions.iterator();

            while (items.hasNext())
            {
                final Map.Entry<SpeechPart, List<Definition>> item = items.next();

                for (Definition definition : item.getValue())
                {
                    speechPartAndDefinitionWidgetModel.addElement(new DefinitionUiModel(item.getKey(), definition));
                }
            }
        }
    }
    catch (SQLException ex)
    {
        onSqlError(ex);
    }
}

private void onTranslatorsClick()
{
    translator = (Translator) translators.getSelectedItem();
    suggestor = new Suggestor(translator.getFromDictionary(), 10);
    word.setEnabled(true);

    application.setTitle(translator.toString());

    translators.setToolTipText("tooltip : " + translator.toString());

    speechPartAndDefinitionWidgetModel.clear();
}

private void hideSuggestionWindowToBack()
{
    if (javaWindow == null)
    {
        return;
    }

    javaWindow.setVisible(false);
    javaWindow.toBack();
}

private void showSuggestionWindowToBack()
{
    if (javaWindow == null)
    {
        return;
    }

    javaWindow.setVisible(true);
    javaWindow.toFront();
}

}

答案 1 :(得分:0)

建议列表后面的算法(我知道)是:Longest common substring problem。如果您以trie的形式将字符串存储在数据库中,则问题非常简单。然后,当前前缀的建议列表将是以当前输入的字符串开头的所有字符串。如果你看看Trie数据结构,你会理解我的意思。