Как я могу реализовать автозаполнение с помощью Swing?

Я заинтересован в предоставлении поля автозаполнения в JFrame. Механизм срабатывания будет основан на мнемонике (я думаю), но я не совсем уверен, что использовать для «поля автозаполнения» (я бы хотел, чтобы результаты фильтровались, когда пользователь нажимает клавиши).

Как бы вы это реализовали? Какой-то JFrame или JPopupMenu?

Я хотел бы знать, как это реализовано, поэтому, пожалуйста, не размещайте ссылки на доступные компоненты [J].


person Geo    schedule 27.01.2009    source источник
comment
Пожалуйста, опубликуйте свое решение, когда вы его получите.   -  person OscarRyz    schedule 29.01.2009
comment
Также см. этот аналогичный ответ   -  person David Kroukamp    schedule 06.03.2013


Ответы (8)


Пример автозаполнения для текстовой области приведен по адресу
Учебники Sun "Использование компонентов Swing".

Это сделано в стиле текстовых процессоров (без всплывающих окон, но
предлагаемый текст набирается перед курсором).

Просто прокрутите вниз до пункта Другой пример: TextAreaDemo"
и нажмите кнопку "Запустить"!

person ivan_ivanovich_ivanoff    schedule 14.06.2009
comment
Ссылка на сегодняшний день битая. - person davorb; 26.08.2011
comment
Ссылка снова работает. Я думаю, что Oracle отменила решение о прекращении переадресации с URL-адресов sun.com. - person Rörd; 22.03.2012

Возможно, вы захотите попробовать бесплатный компонент AutoComplete в SwingLabs.

http://swinglabs.org

Изменить: этот сайт, похоже, переместился на http://java.net/projects/swinglabs.

Есть пример реализации этого кода по адресу:

http://download.java.net/javadesktop/swinglabs/releases/0.8/docs/api/org/jdesktop/swingx/autocomplete/package-summary.html

person Geekygecko    schedule 27.01.2009
comment
Обратите внимание, что сайт swinglabs теперь выглядит пустым. Однако есть swinglabs.dev.java.net, дающий доступ к исходникам. Кроме того, проект, по-видимому, доступен через maven, например mvnbrowser.com/ указывает. - person Riduidel; 04.11.2009
comment
Он также доступен в поиске Maven Central. maven.org/ - person ftraian; 26.06.2014

Вот пример со всплывающим окном, как вы просили. Вы можете запустить этот пример внизу страницы.

Вот мой упрощенный пример. К сожалению, вам нужно сначала щелкнуть текстовое поле, прежде чем начать печатать, иначе вы получите исключения. Если кто-нибудь может понять, почему, сообщите мне/обновите этот ответ.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class _Autocompleter {

  private final static JPopupMenu textPopupMenu
      = new JPopupMenu("MENU") {

    {
      add(new JMenuItem("item 1"));
      add(new JMenuItem("item 2"));
      setFocusable(false);
    }

  };

  private final static KeyListener textInputListener
      = new KeyAdapter() {

    @Override
    public void keyTyped(KeyEvent e) {
      Point p = textInput.getCaret().getMagicCaretPosition();
      if (textPopupMenu.isVisible()) {
        SwingUtilities.convertPointToScreen(p, textInput);
        textPopupMenu.setLocation(p.x, p.y + 20);
      } else {
        textPopupMenu.show(textInput, p.x, p.y + 20);
      }
    }

  };

  private final static JTextArea textInput
      = new JTextArea("type something") {

    {
      addKeyListener(textInputListener);
      setCaretPosition(getText().length());
    }

  };

  private final static JFrame f = new JFrame("TEST") {

    {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      add(textInput);

      setSize(400, 60);
      setLocationRelativeTo(null);
      setVisible(true);
    }

  };

  public static void main(String[] args)
      throws Exception {
        // YES, IT'S EMPTY !!!
        // It'll start anyway because of static initializers
  }

}
person ivan_ivanovich_ivanoff    schedule 14.06.2009
comment
Ах! Я понял, что не так! 1) Просто игнорируйте положение курсора, когда текстовое поле пусто! 2) Использовать вместо KeyListener что-то типа UndoableEditListener. - person ivan_ivanovich_ivanoff; 23.06.2009

Вот отличная статья, в которой используется несколько библиотек: Добавление поддержки автозаполнения в поля со списком Swing @Java.net

person pek    schedule 26.08.2010
comment
ссылка битая! - person prasad nikumbh; 09.08.2020

Вы можете использовать эту библиотеку: http://fifesoft.com/autocomplete/

person Maciej Modelski    schedule 21.09.2010

Вы можете использовать текстовое поле JEdit со встроенной системой автодополнения и подсветки синтаксиса.

Более тяжеловесное решение (хорошее в долгосрочной перспективе) — использовать платформу NetBeans.

person Hendy Irawan    schedule 11.03.2010

Я бы добавил actionListener, чтобы вы могли получать каждую клавишу по мере ее нажатия.

Затем вы можете выполнить поиск в фоновом режиме (другая тема)

person Peter Lawrey    schedule 27.01.2009
comment
Но к какому компоненту вы бы добавили ActionListener? - person Geo; 28.01.2009
comment
Компонент, для которого вы будете предоставлять автозаполнение. - person Peter Lawrey; 29.01.2009
comment
DocumentListener лучше подходит для автозаполнения JTextField. - person Eng.Fouad; 14.02.2013

Использовать это

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Autocompleter2
{
    //~ Methods ------------------------------------------------------------------------------------

    public static void main(String[] args)
      throws Exception
    {
        // YES, IT'S EMPTY !!!
        // It'll start anyway because of static initializers
        SwingUtilities.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    final JPopupMenu textPopupMenu = new JPopupMenu("MENU")
                    {

                        {
                            add(new JMenuItem("item 1"));
                            add(new JMenuItem("item 2"));
                            setFocusable(false);
                        }
                    };

                    final JTextArea textInput = new JTextArea("type something la")
                    {

                        {
                            setCaretPosition(getText().length());
                        }
                    };

                    KeyListener textInputListener = new KeyAdapter()
                    {
                        @Override
                        public void keyTyped(KeyEvent e)
                        {
                            Point p = textInput.getCaret().getMagicCaretPosition();

                            if (textPopupMenu.isVisible())
                            {
                                SwingUtilities.convertPointToScreen(p, textInput);
                                textPopupMenu.setLocation(p.x, p.y + 20);
                            }
                            else
                            {
                                textPopupMenu.show(textInput, p.x, p.y + 20);
                            }
                        }
                    };

                    textInput.addKeyListener(textInputListener);
                    new JFrame("TEST")
                        {

                            {
                                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                add(textInput);
                                setSize(400, 60);
                                setLocationRelativeTo(null);
                                setVisible(true);
                            }
                        };
                }
                ;
            });
    }
}
person Community    schedule 21.08.2009