package net.java.sip.communicator.impl.gui.main.contactlist; import java.awt.*; import java.awt.event.*; import java.util.List; import javax.swing.*; import javax.swing.text.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.call.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.swing.*; import net.java.sip.communicator.util.swing.plaf.*; /** * The SearchTextFieldUI is the one responsible for the search field * look & feel. It draws a search icon inside the field and adjusts the bounds * of the editor rectangle according to it. * * @author Yana Stamcheva */ public class SearchFieldUI extends SIPCommTextFieldUI { /** * The icon indicating that this is a search field. */ private ImageIcon searchIcon; /** * The default icon of the call button. */ private Image callIcon; /** * The roll over icon of the call button. */ private Image callRolloverIcon; /** * Indicates if the mouse is currently over the call button. */ private boolean isCallMouseOver = false; /** * The call button tool tip string. */ private final String callString = GuiActivator.getResources().getI18NString("service.gui.CALL"); /** * Indicates if the call icon is currently visible. */ private boolean isCallIconVisible = false; /** * Creates a SIPCommTextFieldUI. */ public SearchFieldUI() { searchIcon = UtilActivator.getResources() .getImage("service.gui.icons.SEARCH_ICON"); callIcon = UtilActivator.getResources() .getImage("service.gui.buttons.SEARCH_CALL_ICON").getImage(); callRolloverIcon = UtilActivator.getResources() .getImage("service.gui.buttons.SEARCH_CALL_ROLLOVER_ICON") .getImage(); } /** * Adds the custom mouse listeners defined in this class to the installed * listeners. */ protected void installListeners() { super.installListeners(); getComponent().addMouseListener( new TextFieldMouseListener()); getComponent().addMouseMotionListener( new TextFieldMouseMotionListener()); } /** * Implements parent paintSafely method and enables antialiasing. * @param g the Graphics object that notified us */ protected void paintSafely(Graphics g) { customPaintBackground(g); super.paintSafely(g); } /** * Paints the background of the associated component. * @param g the Graphics object used for painting */ protected void customPaintBackground(Graphics g) { Graphics2D g2 = (Graphics2D) g.create(); try { AntialiasingManager.activateAntialiasing(g2); super.customPaintBackground(g2); JTextComponent c = this.getComponent(); int dy = (c.getY() + c.getHeight()) / 2 - searchIcon.getIconHeight()/2; g2.drawImage(searchIcon.getImage(), c.getX(), dy + 1, null); // Paint call button. Rectangle callRect = getCallButtonRect(); int dx = callRect.x; dy = callRect.y; if (c.getText() != null && c.getText().length() > 0 && CallManager.getTelephonyProviders().size() > 0) { if (isCallMouseOver) g2.drawImage(callRolloverIcon, dx, dy, null); else g2.drawImage(callIcon, dx, dy, null); isCallIconVisible = true; } else isCallIconVisible = false; } finally { g2.dispose(); } } /** * If we are in the case of disabled delete button, we simply call the * parent implementation of this method, otherwise we recalculate the editor * rectangle in order to leave place for the delete button. * @return the visible editor rectangle */ protected Rectangle getVisibleEditorRect() { Rectangle rect = super.getVisibleEditorRect(); if ((rect.width > 0) && (rect.height > 0)) { rect.x += searchIcon.getIconWidth() + 8; rect.width -= searchIcon.getIconWidth() + callRolloverIcon.getWidth(null) + 15; return rect; } return null; } /** * The MouseListener that listens for mouse events in order to * update the delete icon. */ protected class TextFieldMouseListener implements MouseListener { /** * Updates the call button when the mouse was clicked. * @param e the MouseEvent that notified us of the click */ public void mouseClicked(MouseEvent e) { updateCallIcon(e); } /** * Updates the call button when the mouse is enters the component area. * @param e the MouseEvent that notified us */ public void mouseEntered(MouseEvent e) { updateCallIcon(e); } /** * Updates the call button when the mouse exits the component area. * @param e the MouseEvent that notified us */ public void mouseExited(MouseEvent e) { updateCallIcon(e); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} } /** * The MouseMotionListener that listens for mouse events in order * to update the delete icon. */ protected class TextFieldMouseMotionListener implements MouseMotionListener { /** * Updates the delete icon when the mouse is dragged over. * @param e the MouseEvent that notified us */ public void mouseDragged(MouseEvent e) { updateCallIcon(e); } /** * Updates the delete icon when the mouse is moved over. * @param e the MouseEvent that notified us */ public void mouseMoved(MouseEvent e) { updateCallIcon(e); } } /** * Updates the delete icon, changes the cursor and deletes the content of * the associated text component when the mouse is pressed over the delete * icon. * * @param evt the mouse event that has prompted us to update the delete * icon. */ private void updateCallIcon(MouseEvent evt) { int x = evt.getX(); int y = evt.getY(); Rectangle callButtonRect = getCallButtonRect(); if (isCallIconVisible && callButtonRect.contains(x, y)) { JTextComponent c = getComponent(); String searchText = c.getText(); if (searchText == null) return; // Show a tool tip over the call button. getComponent().setToolTipText(callString + " " + searchText); ToolTipManager.sharedInstance().mouseEntered( new MouseEvent(getComponent(), 0, x, y, x, y, // X-Y of the mouse for the tool tip 0, false)); // Update the default cursor. isCallMouseOver = true; getComponent().setCursor(Cursor.getDefaultCursor()); // Perform call action when the call button is clicked. if (evt.getID() == MouseEvent.MOUSE_CLICKED) { List telephonyProviders = CallManager.getTelephonyProviders(); if (telephonyProviders.size() == 1) { CallManager.createCall( telephonyProviders.get(0), searchText); } else if (telephonyProviders.size() > 1) { ChooseCallAccountPopupMenu chooseAccountDialog = new ChooseCallAccountPopupMenu( c, searchText, telephonyProviders); chooseAccountDialog .setLocation(getCallButtonRect().getLocation()); chooseAccountDialog.showPopupMenu(); } } } else { // Remove the call button tool tip when the mouse exits the call // button area. getComponent().setToolTipText(""); ToolTipManager.sharedInstance().mouseExited( new MouseEvent(getComponent(), 0, x, y, x, y, // X-Y of the mouse for the tool tip 0, false)); isCallMouseOver = false; } getComponent().repaint(); } /** * Calculates the call button rectangle. * * @return the call button rectangle */ protected Rectangle getCallButtonRect() { Component c = getComponent(); Rectangle rect = c.getBounds(); int dx = getDeleteButtonRect().x - callRolloverIcon.getWidth(null) - 2; int dy = (rect.y + rect.height) / 2 - callRolloverIcon.getHeight(null)/2; return new Rectangle( dx, dy, callRolloverIcon.getWidth(null), callRolloverIcon.getHeight(null)); } }