// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.gui;
import java.awt.BorderLayout;
import java.awt.event.MouseListener;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.infinity.util.Misc;
import org.infinity.util.SimpleListModel;
public final class TextListPanel extends JPanel implements DocumentListener, ListSelectionListener
{
private boolean sortValues = true;
private final SimpleListModel<Object> listmodel = new SimpleListModel<Object>();
private final JList<Object> list;
private final JTextField tfield = new JTextField(10);
public TextListPanel(List<? extends Object> values)
{
this(values, true);
}
public TextListPanel(List<? extends Object> values, boolean sortValues)
{
this.sortValues = sortValues;
setValues(values);
list = new JList<>(listmodel);
list.setSelectedIndex(0);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addListSelectionListener(this);
list.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
tfield.getDocument().addDocumentListener(this);
setLayout(new BorderLayout());
add(tfield, BorderLayout.NORTH);
add(new JScrollPane(list), BorderLayout.CENTER);
}
// --------------------- Begin Interface DocumentListener ---------------------
@Override
public void insertUpdate(DocumentEvent event)
{
if (tfield.hasFocus())
selectClosest(tfield.getText());
}
@Override
public void removeUpdate(DocumentEvent event)
{
if (tfield.hasFocus())
selectClosest(tfield.getText());
}
@Override
public void changedUpdate(DocumentEvent event)
{
}
// --------------------- End Interface DocumentListener ---------------------
// --------------------- Begin Interface ListSelectionListener ---------------------
@Override
public void valueChanged(ListSelectionEvent event)
{
if (list.hasFocus() && list.getSelectedValue() != null) {
tfield.setText(list.getSelectedValue().toString());
}
}
// --------------------- End Interface ListSelectionListener ---------------------
@Override
public synchronized void addMouseListener(MouseListener listener)
{
list.addMouseListener(listener);
}
@Override
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
list.setEnabled(enabled);
tfield.setEditable(enabled);
}
public void addListSelectionListener(ListSelectionListener listener)
{
list.addListSelectionListener(listener);
}
public void removeListSelectionListener(ListSelectionListener listener)
{
list.removeListSelectionListener(listener);
}
public void ensureIndexIsVisible(int i)
{
list.ensureIndexIsVisible(i);
}
public ListModel<Object> getModel()
{
return listmodel;
}
public int getSelectedIndex()
{
return list.getSelectedIndex();
}
public Object getSelectedValue()
{
return list.getSelectedValue();
}
public void setSelectedIndex(int index)
{
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
tfield.setText(list.getSelectedValue().toString());
}
public void setSelectedValue(Object value, boolean shouldScroll)
{
list.setSelectedValue(value, shouldScroll);
tfield.setText(value.toString());
}
public void setValues(List<? extends Object> values)
{
if (this.sortValues) {
Collections.sort(values, Misc.getIgnoreCaseComparator());
}
listmodel.clear();
for (int i = 0; i < values.size(); i++) {
listmodel.addElement(values.get(i));
}
tfield.setText("");
if (list != null) {
list.setSelectedIndex(0);
list.ensureIndexIsVisible(0);
}
}
private void selectClosest(String text)
{
int selected = 0;
if (!text.isEmpty()) {
text = text.toUpperCase(Locale.ENGLISH);
for (int size = listmodel.getSize(); selected < size; selected++) {
final String s = listmodel.getElementAt(selected).toString().toUpperCase(Locale.ENGLISH);
if (s.startsWith(text)) {
break;
}
}
}
if (selected < listmodel.getSize()) {
list.setSelectedIndex(selected);
list.ensureIndexIsVisible(selected);
}
}
}