/**
* Copyright 1999-2009 The Pegadi Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pegadi.artis.text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.QuadCurve2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ResourceBundle;
public class PersonInText extends JComponent implements LocalComponent {
JTextField textField;
JLabel label;
JLabel personIcon;
Popup popup;
String addString;
DefaultListModel model = new DefaultListModel();
private JList resultList;
private JScrollPane resultScroll;
private boolean editable;
public static PersonResolver resolver = new DefaultPersonResolver();
private PersonInfo person = null;
MouseListener ml;
private final Logger log = LoggerFactory.getLogger(getClass());
public PersonInText(PersonInfo personInfo) {
ResourceBundle strings = ResourceBundle.getBundle("org.pegadi.artis.text.PersonInTextStrings");
addString = strings.getString("addPerson");
person = personInfo;
model.addElement("Ingen resultater..");
resultList = new JList(model);
resultList.setBackground(Color.decode("#aaaaff"));
resultScroll = new JScrollPane(resultList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
resultScroll.setBorder(BorderFactory.createLineBorder(Color.BLACK));
resultList.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
resultList_mousePressed(e);
}
});
Border emptyBorder = new EmptyBorder(0, 0, 0, 0);
this.setBorder(emptyBorder);
textField = new JTextField();
textField.setText(person.getName());
textField.setMinimumSize(new Dimension(300,10));
textField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
textChanged();
}
public void changedUpdate(DocumentEvent e) {
textChanged();
}
public void removeUpdate(DocumentEvent e) {
textChanged();
}
});
setAlignmentY((float) 0.79);
label = new JLabel();
label.setBorder(emptyBorder);
label.setForeground(Color.BLUE);
label.setFont(label.getFont().deriveFont(Font.BOLD));
textField.setRequestFocusEnabled(true);
BorderLayout layout = new BorderLayout();
layout.setVgap(0);
setLayout(layout);
personIcon = new JLabel();
personIcon.setIcon(new ImageIcon(getClass().getResource("/images/texteditor/personintext.png")));
personIcon.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
add(label, BorderLayout.CENTER);
add(personIcon, BorderLayout.EAST);
ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
label_mousePressed();
}
public void mouseEntered(MouseEvent e) {
label_mouseEntered();
}
public void mouseExited(MouseEvent e) {
label_mouseExited();
}
};
label.addMouseListener(ml);
FocusListener fl = new FocusAdapter() {
public void focusLost(FocusEvent e) {
textField_focusLost(e);
}
};
textField.addFocusListener(fl);
textField.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
textField_keyPressed(e);
}
});
editable = true;
setEditable(false);
}
private void resultList_mousePressed(MouseEvent e) {
if (e.getClickCount() == 2) {
if(resultList.locationToIndex(e.getPoint()) == 0) {
PersonInfo p = resolver.addPerson(textField.getText(), this);
if(p != null) {
setPerson(p);
}
} else {
textField.setText(resultList.getSelectedValue().toString());
setEditable(false);
}
}
}
private void textField_keyPressed(KeyEvent e) {
log.debug("textField_keyPressed");
int selectedIndex = resultList.getSelectedIndex();
int size = resultList.getModel().getSize();
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
if(selectedIndex < size -1) {
resultList.setSelectedIndex(selectedIndex+1);
} else {
resultList.setSelectedIndex(0);
}
resultList.scrollRectToVisible(resultList.getCellBounds(resultList.getSelectedIndex(), resultList.getSelectedIndex()));
e.consume();
}
else if(e.getKeyCode() == KeyEvent.VK_UP) {
if(selectedIndex > 0) {
resultList.setSelectedIndex(selectedIndex-1);
} else {
resultList.setSelectedIndex(size-1);
}
resultList.scrollRectToVisible(resultList.getCellBounds(resultList.getSelectedIndex(), resultList.getSelectedIndex()));
e.consume() ;
} else if(e.getKeyCode() == KeyEvent.VK_ENTER) {
if(resultList.getSelectedValue() == addString) {
PersonInfo person;
person = resolver.addPerson(textField.getText(), this);
if(person != null) {
setPerson(person);
setEditable(false);
}
} else {
PersonInfo person = (PersonInfo) resultList.getSelectedValue();
setPerson(person);
setEditable(false);
}
e.consume();
}
}
private void textChanged() {
String text = textField.getText().toLowerCase();
model.clear();
model.addElement(addString);
if (resolver == null) {
log.error("Search not configured!");
} else {
if (text.length() > 2) {
java.util.List<PersonInfo> res = PersonInText.resolver.search(text);
for (PersonInfo re : res) {
model.addElement(re);
}
if (model.getSize() > 1) {
resultList.setSelectedIndex(1);
} else {
resultList.setSelectedIndex(0);
}
if (popup == null) {
PopupFactory fac = PopupFactory.getSharedInstance();
popup = fac.getPopup(null, resultScroll,
(int) (textField.getLocationOnScreen().getX()),
(int) (textField.getLocationOnScreen().getY() + textField.getSize().getHeight() + 5));
}
popup.show();
} else {
if(popup != null) {
popup.hide();
popup = null;
}
}
}
}
public String getPersonName() {
return textField.getText();
}
public void label_mousePressed() {
setEditable(true);
}
public void setEditable(boolean editable) {
if((isEditable() && editable) || (!isEditable() && !editable)) {
return;
}
this.editable = editable;
if(editable) {
remove(label);
personIcon.removeMouseListener(ml);
add(textField, BorderLayout.CENTER);
revalidate();
textField.selectAll();
textField.requestFocus();
} else {
remove(textField);
personIcon.addMouseListener(ml);
add(label, BorderLayout.CENTER);
add(personIcon, BorderLayout.EAST);
label.setText(textField.getText());
if (popup != null) {
popup.hide();
}
popup = null;
}
}
private boolean isEditable() {
return editable;
}
public void label_mouseEntered() {
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
public void label_mouseExited() {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
public void textField_focusLost(FocusEvent e) {
log.debug("combobox_focuslost");
setEditable(false);
}
public void setOpaque(boolean opaque) {
textField.setOpaque(opaque);
super.setOpaque(opaque);
}
public PersonInfo getPerson() {
return person;
}
public void setPerson(PersonInfo person) {
this.person = person;
label.setText(person.getName());
textField.setText(person.getName());
}
public void changedUpdate(Element e) {
AttributeSet a = ((DefaultStyledDocument)e.getDocument()).getParagraphElement(e.getStartOffset()).getAttributes();
setAttributes(a);
}
public void setAttributes(AttributeSet a) {
String fontFamily = StyleConstants.getFontFamily(a);
int size = StyleConstants.getFontSize(a);
Font f = new Font(fontFamily, Font.PLAIN, size);
if(StyleConstants.isBold(a)) {
f = f.deriveFont(Font.BOLD);
}
if(StyleConstants.isItalic(a)) {
f = f.deriveFont(Font.ITALIC);
}
label.setFont(f);
textField.setFont(f);
}
private static class DefaultPersonResolver implements PersonResolver {
static ArrayList persons = new ArrayList();
static {
persons.add("Erlend Langeland Haugen");
persons.add("Erlend Engh Brekke");
persons.add("Erle Katina Fossum");
persons.add("Marvin Wiseth");
persons.add("Trond Andresen");
persons.add("Gunnar Evensen");
persons.add("Kjell Andersen");
persons.add("Magnar Guldbrandsen");
persons.add("Anders Hanevik");
persons.add("Einar Korneliusen");
}
public java.util.List<PersonInfo> search(String text) {
ArrayList res = new ArrayList();
Iterator i = persons.iterator();
int c = 0;
while(i.hasNext()) {
String person = (String) i.next();
if (person.toLowerCase().indexOf(text.toLowerCase()) >= 0) {
res.add(new PersonInfo(Integer.toString(c), person, "Default"));
}
c++;
}
return res;
}
public PersonInfo addPerson(String person, PersonInText personInText) {
PersonInfo personInfo = new PersonInfo("1", person, "");
personInText.setPerson(personInfo);
personInText.setEditable(false);
persons.add(person);
return personInfo;
}
}
class Face extends JComponent {
int mood;
boolean anonymous;
QuadCurve2D moodCurve = new QuadCurve2D.Double();
public Face() {
mood = 50;
}
public Face(int mood, boolean anonymous) {
this.mood = mood;
this.anonymous = anonymous;
}
public void setMood(int mood) {
this.mood = mood;
}
public void setAnonymous(boolean anonymous) {
this.anonymous = anonymous;
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int w = (int) getSize().getWidth();
int h = (int) getSize().getHeight();
//g2.drawLine(0,0,w,h);
//g2.drawLine(0,h,w,0);
// Diameter of head
int d = (int) (Math.min(w, h) * 0.90);
// Fill head
g2.setColor(Color.WHITE);
g2.fillOval((w - d) / 2, 0, d, d);
g2.setColor(Color.BLACK);
// Draw head
g2.drawOval((w - d) / 2, 0, d, d);
//Draw eyes
if (anonymous) {
g2.fillRect(w / 2 - d / 5 - d / 12, d / 3, d / 5, d / 8);
g2.fillRect(w / 2 + d / 5 - d / 12, d / 3, d / 5, d / 8);
double rad = 2 * Math.PI * 24 / 360;
int sin = (int) (d / 2 * Math.sin(rad));
int cos = (int) (d / 2 * Math.cos(rad));
g2.drawLine(w / 2 - d / 5 - d / 12, d / 3, w / 2 - cos, d / 2 - sin);
g2.drawLine(w / 2 + d / 5 - d / 12 + d / 5, d / 3, w / 2 + cos, d / 2 - sin);
g2.drawLine(w / 2 - d / 5 - d / 12 + d / 5,
d / 3 + d / 20,
w / 2 + d / 5 - d / 12,
d / 3 + d / 20);
} else {
g2.fillOval(w / 2 - d / 5 - d / 12, d / 3, d / 8, d / 8);
g2.fillOval(w / 2 + d / 5 - d / 12, d / 3, d / 8, d / 8);
}
moodCurve.setCurve(w / 2 - d / 4,
d * 3 / 4,
w / 2,
d / 2 + mood * d / 200 + d / 12,
w / 2 + d / 4,
d * 3 / 4);
g2.draw(moodCurve);
}
public Dimension getPreferredSize() {
return new Dimension(15, 15);
}
}
}