/*
* SimplyHTML, a word processor based on Java, HTML and CSS
* Copyright (C) 2002 Ulrich Hilger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package nu.fw.jeti.plugins.xhtml.fontchooser;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.CaretEvent;
import java.awt.event.FocusListener;
import java.awt.event.FocusEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
import java.awt.BorderLayout;
import java.util.Vector;
import java.util.EventObject;
import java.util.EventListener;
import java.util.Enumeration;
/**
* A pick list typically being used in font dialogs, consisting
* of a list title, a text field for the currently selected
* value and the actual pick list containing all possible values.
*
* As three different lists are needed in our font panel for
* family, style and size, its quite handy to have the code
* making up such a component in a separate class only once.
*
* As well in a separate class it is easier to implement the
* special 'behaviour', i.e. when list is clicked, the value
* of the text field is set accordingly and when a value is
* typed in the text field, the value in the list changes
* accordingly.
*
* @author Ulrich Hilger
* @author Light Development
* @author http://www.lightdev.com
* @author info@lightdev.com
* @author published under the terms and conditions of the
* GNU General Public License,
* for details see file gpl.txt in the distribution
* package of this software
*
* @version stage 9, release 4, January 12, 2003
*/
class TitledPickList extends JPanel
implements ListSelectionListener, CaretListener, FocusListener, KeyListener
{
/** the chosen list entry */
private JTextField choice;
boolean ignoreTextChanges = false;
/** the list having all possible entries */
private JList optionsList;
/**
* constructor
*
* @param options the options to be selectable in this list
* @param titleText the title for the pick list
*/
public TitledPickList(String[] options, String titleText) {
super(new BorderLayout());
choice = new JTextField();
choice.addCaretListener(this);
choice.addFocusListener(this);
choice.addKeyListener(this);
optionsList = new JList(options);
optionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
optionsList.addListSelectionListener(this);
JScrollPane scrollableList = new JScrollPane(optionsList);
JPanel pickListPanel = new JPanel(new BorderLayout());
pickListPanel.add(choice, BorderLayout.NORTH);
pickListPanel.add(scrollableList, BorderLayout.CENTER);
JLabel title = new JLabel();
title.setText(titleText);
add(title, BorderLayout.NORTH);
add(pickListPanel, BorderLayout.CENTER);
}
/**
* if the caret was updated, i.e. the user typed into
* the text field, try to find a font family name starting
* with what was typed so far, set the list to that family
*/
public void caretUpdate(CaretEvent ce) {
if(!ignoreTextChanges) {
if(choice.hasFocus()) {
ListModel model = optionsList.getModel();
String key = choice.getText().toLowerCase();
if(key != null) {
int i = 0;
int modelSize = model.getSize();
String listEntry = (String) model.getElementAt(i);
while(++i < modelSize && !listEntry.toLowerCase().startsWith(key)) {
listEntry = (String) model.getElementAt(i);
}
if(i < modelSize) {
optionsList.setSelectedValue(listEntry, true);
}
}
}
}
}
/** for FocusListener implementation, but unused here */
public void focusGained(FocusEvent e) {
}
/**
* put the currently selected value in the list
* into the text field when user leaves field
*/
public void focusLost(FocusEvent e) {
updateTextFromList();
}
/**
* put the currently selected value in the list
* into the text field when user pressed enter in field
*/
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
updateTextFromList();
}
}
/** for KeyListener implementation, but unused here */
public void keyReleased(KeyEvent e) {
}
/** for KeyListener implementation, but unused here */
public void keyTyped(KeyEvent e) {
}
/** put selected value into text field */
private void updateTextFromList() {
Object value = optionsList.getSelectedValue();
if(value != null) {
choice.setText(value.toString());
}
}
/**
* get the value selected from the pick list
*
* @return the selected value or null if nothing is selected
*/
public Object getSelection() {
return optionsList.getSelectedValue();
}
/**
* set the value selected in the pick list
*
* @param value the value to be selected in the list
*/
public void setSelection(Object value) {
optionsList.setSelectedValue(value.toString(), true);
updateTextFromList();
}
/**
* set the selected index in the pick list
*
* @param index the index of the value to be selected in the list
*/
public void setSelection(int index) {
optionsList.setSelectedIndex(index);
updateTextFromList();
}
/**
* get the index of the value selected in the pick list
*
* @return the index of the selected value or -1 if none is selected
*/
public int getIndex() {
return optionsList.getSelectedIndex();
}
/**
* if another value was picked from the list, set the
* textfield according to the choice and update the
* sample
*/
public void valueChanged(ListSelectionEvent e) {
if(optionsList.hasFocus()) {
updateTextFromList();
}
fireValueChanged();
}
/* ------------- event handling start ------------ */
/** the listeners for TitledPickkListEvents */
private Vector listeners = new Vector(0);
/**
* add an event listener.
*
* @param listener the event listener to add
*/
public void addTitledPickListListener(TitledPickListListener listener) {
listeners.addElement(listener);
}
/**
* remove an event listener.
*
* @param listener the event listener to remove
*/
public void removeTitledPickListListener(TitledPickListListener listener) {
listeners.removeElement(listener);
}
/** fire a value changed event to all registered listeners */
void fireValueChanged() {
Enumeration listenerList = listeners.elements();
while(listenerList.hasMoreElements()) {
((TitledPickListListener) listenerList.nextElement()).valueChanged(
new TitledPickListEvent(this));
}
}
/** the event object definition for ColorPanels */
static class TitledPickListEvent extends EventObject {
public TitledPickListEvent(Object source) {
super(source);
}
}
/** the event listener definition for ColorPanels */
interface TitledPickListListener extends EventListener {
public void valueChanged(TitledPickListEvent e);
}
/* ------------- event handling end ------------ */
}
/*
* Overrides for emacs
* Local variables:
* tab-width: 4
* End:
*/