package org.chartsy.chatsy.chat.component;
import org.chartsy.chatsy.chat.ui.ContactItem;
import org.chartsy.chatsy.chat.util.ModelUtil;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.ListCellRenderer;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
public class JContactItemField extends JPanel
{
private JTextField textField = new JTextField();
private DefaultListModel model = new DefaultListModel();
private JList list;
private JWindow popup;
private List<ContactItem> items;
public JContactItemField(List<ContactItem> items)
{
setLayout(new BorderLayout());
list = new JList(model)
{
public String getToolTipText(MouseEvent e)
{
int row = locationToIndex(e.getPoint());
final ContactItem item = (ContactItem)getModel().getElementAt(row);
if (item != null)
return item.getJID();
return null;
}
};
this.items = items;
add(textField, BorderLayout.CENTER);
textField.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent keyEvent)
{
char ch = keyEvent.getKeyChar();
if (validateChar(ch))
showPopupMenu();
if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER)
{
int index = list.getSelectedIndex();
if (index >= 0)
{
ContactItem selection = (ContactItem)list.getSelectedValue();
textField.setText(selection.getDisplayName());
popup.setVisible(false);
}
}
if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE)
popup.setVisible(false);
dispatchEvent(keyEvent);
}
public void keyPressed(KeyEvent e)
{
if (isArrowKey(e))
list.dispatchEvent(e);
}
});
textField.addFocusListener(new FocusListener()
{
public void focusGained(FocusEvent e)
{
}
public void focusLost(FocusEvent e)
{
textField.requestFocusInWindow();
}
});
popup = new JWindow();
popup.getContentPane().add(new JScrollPane(list));
popup.setAlwaysOnTop(true);
list.setCellRenderer(new PopupRenderer());
list.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 2)
{
int index = list.getSelectedIndex();
if (index >= 0)
{
ContactItem selection = (ContactItem)list.getSelectedValue();
textField.setText(selection.getDisplayName());
popup.setVisible(false);
}
}
}
});
}
public void dispose()
{
popup.dispose();
}
public void setItems(List<ContactItem> list)
{
this.items = list;
}
public JList getList()
{
return list;
}
private void showPopupMenu()
{
model.removeAllElements();
String typedItem = textField.getText();
final List<ContactItem> validItems = new ArrayList<ContactItem>();
for (ContactItem contactItem : items)
{
String nickname = contactItem.getDisplayName().toLowerCase();
if (nickname.startsWith(typedItem.toLowerCase()))
validItems.add(contactItem);
}
if (validItems.size() > 0)
for (final ContactItem label : validItems)
model.addElement(label);
if (!validItems.isEmpty() && !popup.isVisible())
{
popup.pack();
popup.setSize(textField.getWidth(), 200);
Point pt = textField.getLocationOnScreen();
pt.translate(0, textField.getHeight());
popup.setLocation(pt);
popup.toFront();
popup.setVisible(true);
}
if (validItems.size() > 0)
list.setSelectedIndex(0);
}
public boolean validateChars(String text)
{
if (!ModelUtil.hasLength(text))
return false;
for (int i = 0; i < text.length(); i++)
{
char ch = text.charAt(i);
if (!Character.isLetterOrDigit(ch)
&& ch != '@'
&& ch != '-'
&& ch != '_'
&& ch != '.'
&& ch != ','
&& ch != ' ')
return false;
}
return true;
}
public boolean validateChar(char ch)
{
if (!Character.isLetterOrDigit(ch)
&& ch != '@'
&& ch != '-'
&& ch != '_'
&& ch != '.'
&& ch != ','
&& ch != ' '
&& ch != KeyEvent.VK_BACK_SPACE
&& ch != KeyEvent.CTRL_DOWN_MASK
&& ch != KeyEvent.CTRL_MASK)
return false;
return true;
}
public boolean isArrowKey(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_UP
|| e.getKeyCode() == KeyEvent.VK_DOWN)
return true;
return false;
}
public String getText()
{
return textField.getText();
}
public ContactItem getSelectedContactItem()
{
return (ContactItem)list.getSelectedValue();
}
public void setText(String text)
{
textField.setText(text);
}
public void focus()
{
textField.requestFocus();
}
public JTextField getTextField()
{
return textField;
}
public JWindow getPopup()
{
return popup;
}
class PopupRenderer extends JLabel implements ListCellRenderer
{
public PopupRenderer()
{
setOpaque(true);
this.setHorizontalTextPosition(JLabel.RIGHT);
this.setHorizontalAlignment(JLabel.LEFT);
}
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected, boolean cellHasFocus)
{
if (isSelected)
{
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else
{
setBackground(list.getBackground());
setForeground(list.getForeground());
}
ContactItem contactItem = (ContactItem)value;
setText(contactItem.getDisplayName());
if (contactItem.getIcon() != null)
setIcon(contactItem.getIcon());
setFont(contactItem.getNicknameLabel().getFont());
setForeground(contactItem.getForeground());
return this;
}
}
public boolean canClose()
{
return !textField.hasFocus();
}
}