java-org.hwo.ui/src/org/hwo/ui/JSearchTextField.java

325 lines
6.8 KiB
Java

package org.hwo.ui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SingleSelectionModel;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.hwo.datetime.JTimeOfDay;
import org.hwo.models.TableMapper.TableMapper;
import org.hwo.ui.wellknown.WellKnown;
import org.hwo.ui.wellknown.WellKnownClass;
import org.hwo.ui.wellknown.WellKnownSearch;
public class JSearchTextField extends JTextField implements FocusListener {
private Class<?> searchClazz;
private JTable tResults;
private TableMapper tmResults;
private JPopupMenu popupList;
private Timer searchTimer;
private WellKnownClass wellKnownClass;
private WellKnownSearch wellKnownSearch;
private Object selectedObject;
private List<ActionListener> actionListeners;
public JSearchTextField()
{
actionListeners = new LinkedList<ActionListener>();
setPreferredSize(new Dimension(120, 24));
searchClazz = null;
popupList = new JPopupMenu();
popupList.setFocusable(false);
JScrollPane scrollPane = new JScrollPane();
tResults = new JTable();
tResults.setCellSelectionEnabled(false);
tResults.setColumnSelectionAllowed(false);
tResults.setRowSelectionAllowed(true);
scrollPane.setViewportView(tResults);
popupList.add(scrollPane);
addFocusListener(this);
getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent arg0) {
}
@Override
public void insertUpdate(DocumentEvent arg0) {
searchTimer.stop();
searchTimer.start();
showPopup();
}
@Override
public void changedUpdate(DocumentEvent arg0) {
//showPopup();
}
});
KeyStrokeHelper helper = new KeyStrokeHelper(this);
helper.registerKeyStrokeListener(new KeyStrokeListener() {
@Override
public void keyStroke(KeyStrokeParameters parameters) {
switch (parameters.getKeyCode())
{
case KeyEvent.VK_ESCAPE:
popupList.setVisible(false);
break;
case KeyEvent.VK_UP:
selectionUp();
break;
case KeyEvent.VK_DOWN:
selectionDown();
break;
case KeyEvent.VK_ENTER:
selectObject();
break;
}
}
});
helper.addKeyCode(KeyEvent.VK_ESCAPE)
.addKeyCode(KeyEvent.VK_UP)
.addKeyCode(KeyEvent.VK_DOWN)
.addKeyCode(KeyEvent.VK_ENTER);
searchTimer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
search();
}
});
searchTimer.setRepeats(false);
}
@Override
public synchronized void addActionListener(ActionListener l) {
actionListeners.add(l);
}
@Override
public synchronized void removeActionListener(ActionListener l) {
actionListeners.remove(l);
}
protected void fireNewActionPerformed()
{
for (ActionListener l:actionListeners)
l.actionPerformed(new ActionEvent(this, 0, ""));
}
private void selectObject()
{
if (!popupList.isVisible())
return;
Object o = tmResults.getSelectedRow();
if (o != null)
{
setSelectedObject(o);
fireNewActionPerformed();
transferFocus();
}
}
private void search()
{
System.err.println("searching...");
if (wellKnownSearch != null)
{
List<Object> l = wellKnownSearch.keywordSearch(searchClazz, getText());
tmResults.setRows(l);
}
}
private void selectionDown()
{
if (!popupList.isVisible())
showPopup();
if (tResults.getSelectedRow()!=-1)
{
if (tResults.getSelectedRow() < tmResults.getRowCount() - 1)
{
tResults.setRowSelectionInterval(tResults.getSelectedRow() + 1,tResults.getSelectedRow() + 1);
System.err.println("down");
}
} else
{
System.err.println("Select first");
tResults.setRowSelectionInterval(0, 0);
}
selectedObject = null;
}
private void selectionUp()
{
if (!popupList.isVisible())
return;
if (tResults.getSelectedRow()!=-1)
{
if (tResults.getSelectedRow() > 0)
{
tResults.setRowSelectionInterval(tResults.getSelectedRow()-1,tResults.getSelectedRow()-1);
System.err.println("up");
}
} else
{
System.err.println("Select last");
tResults.setRowSelectionInterval(tmResults.getRowCount() - 1, tmResults.getRowCount() - 1);
}
selectedObject = null;
}
private void showPopup()
{
if (searchClazz == null)
return;
if (!popupList.isVisible())
{
popupList.setPopupSize(getSize().width, 250);
popupList.show(this, 0, getHeight());
popupList.setVisible(true);
grabFocus();
}
}
@Override
public void focusGained(FocusEvent arg0) {
if (selectedObject != null)
selectAll();
}
@Override
public void focusLost(FocusEvent arg0) {
if (popupList.isVisible())
popupList.setVisible(false);
}
public Class<?> getSearchClazz() {
return searchClazz;
}
public void setSearchClazz(Class<?> searchClazz) {
this.searchClazz = searchClazz;
tmResults = new TableMapper(searchClazz, tResults);
tmResults.setReadOnly(true);
tmResults.setEditorEnabled(false);
tResults.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2))
{
Object so = tmResults.getSelectedRow();
if (so != null)
{
setSelectedObject(so);
}
}
}
});
wellKnownClass = WellKnown.getWellKnownClass(searchClazz);
if (wellKnownClass != null)
{
if (wellKnownClass.search() != null)
{
Class<? extends WellKnownSearch> clazz = wellKnownClass.search();
try {
wellKnownSearch = clazz.newInstance();
wellKnownSearch.setClazz(searchClazz);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
public void setMaxPopupHeight(int maxPopupHeight)
{
Dimension dim = popupList.getMaximumSize();
dim.height = maxPopupHeight;
popupList.setMaximumSize(dim);
}
public int getMaxPopupHeight()
{
return (int)popupList.getMaximumSize().getHeight();
}
public Object getSelectedObject() {
return selectedObject;
}
public void setSelectedObject(Object selectedObject) {
this.selectedObject = selectedObject;
if (selectedObject == null)
{
setText("");
} else
{
setText(WellKnown.getDisplayLabel(selectedObject));
}
popupList.setVisible(false);
fireNewActionPerformed();
}
}