/** * 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); } } }