diff --git a/src/net/java/sip/communicator/impl/gui/customcontrols/SmartComboBox.java b/src/net/java/sip/communicator/impl/gui/customcontrols/SIPCommSmartComboBox.java
similarity index 88%
rename from src/net/java/sip/communicator/impl/gui/customcontrols/SmartComboBox.java
rename to src/net/java/sip/communicator/impl/gui/customcontrols/SIPCommSmartComboBox.java
index 7bd6ff37d..25be007e9 100644
--- a/src/net/java/sip/communicator/impl/gui/customcontrols/SmartComboBox.java
+++ b/src/net/java/sip/communicator/impl/gui/customcontrols/SIPCommSmartComboBox.java
@@ -14,20 +14,22 @@
import javax.swing.*;
import javax.swing.event.*;
+import net.java.sip.communicator.impl.gui.lookandfeel.*;
+
/**
- * SmartComboBox is an editable combo box which selects an item
+ * SIPCommSmartComboBox is an editable combo box which selects an item
* according to user input.
*
* @author Yana Stamcheva
*/
-public class SmartComboBox extends JComboBox
+public class SIPCommSmartComboBox extends JComboBox
{
private ArrayList historyList = new ArrayList();
/**
- * Creates an instance of SmartComboBox.
+ * Creates an instance of SIPCommSmartComboBox.
*/
- public SmartComboBox()
+ public SIPCommSmartComboBox()
{
setModel(new FilterableComboBoxModel(historyList));
setEditor(new CallComboEditor());
@@ -50,75 +52,75 @@ public class FilterableComboBoxModel
private Object selectedItem;
public FilterableComboBoxModel(List items)
- {
+ {
this.items = new ArrayList(items);
filteredItems = new ArrayList(items.size());
- updateFilteredItems();
+ updateFilteredItems();
}
-
+
public boolean contains(Object obj)
{
return items.contains(obj);
}
-
+
public void addElement( Object obj )
{
items.add(obj);
updateFilteredItems();
}
-
+
public void removeElement( Object obj )
{
items.remove(obj);
updateFilteredItems();
}
-
+
public void removeElementAt(int index)
{
items.remove(index);
updateFilteredItems();
}
-
+
public void insertElementAt( Object obj, int index ) {
items.add(index, obj);
updateFilteredItems();
}
-
+
public void setFilter(Filter filter)
{
this.filter = filter;
updateFilteredItems();
}
-
+
protected void updateFilteredItems()
- {
+ {
fireIntervalRemoved(this, 0, filteredItems.size());
filteredItems.clear();
-
+
if (filter == null)
filteredItems.addAll(items);
else {
for (Iterator iterator = items.iterator(); iterator.hasNext();) {
Object item = iterator.next();
-
+
if (filter.accept(item))
filteredItems.add(item);
}
}
fireIntervalAdded(this, 0, filteredItems.size());
}
-
+
public int getSize()
{
return filteredItems.size();
}
-
+
public Object getElementAt(int index)
{
return filteredItems.get(index);
}
-
+
public Object getSelectedItem()
{
return selectedItem;
@@ -166,34 +168,42 @@ public boolean accept(Object o)
}
public class CallComboEditor
- implements ComboBoxEditor, DocumentListener
- {
+ implements ComboBoxEditor,
+ DocumentListener
+ {
private JTextField text;
private volatile boolean filtering = false;
private volatile boolean setting = false;
public CallComboEditor()
- {
+ {
text = new JTextField(15);
text.getDocument().addDocumentListener(this);
+
+ // Enable delete button from the UI.
+ if (text.getUI() instanceof SIPCommTextFieldUI)
+ {
+ ((SIPCommTextFieldUI) text.getUI())
+ .setDeleteButtonEnabled(true);
+ }
}
-
+
public Component getEditorComponent() { return text; }
-
+
public void setItem(Object item)
{
if(filtering)
return;
-
+
setting = true;
String newText = (item == null) ? "" : item.toString();
-
+
text.setText(newText);
setting = false;
}
public Object getItem()
- {
+ {
return text.getText();
}
@@ -222,7 +232,7 @@ protected void handleChange()
Filter filter = null;
if (text.getText().length() > 0) {
- filter = new StartsWithFilter(text.getText());
+ filter = new StartsWithFilter(text.getText());
}
((FilterableComboBoxModel) getModel()).setFilter(filter);
diff --git a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCallComboBoxUI.java b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCallComboBoxUI.java
index b2657587c..211a52418 100644
--- a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCallComboBoxUI.java
+++ b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommCallComboBoxUI.java
@@ -14,19 +14,22 @@
public class SIPCommCallComboBoxUI extends SIPCommComboBoxUI
{
- public static ComponentUI createUI(JComponent c) {
+ public static ComponentUI createUI(JComponent c)
+ {
return new SIPCommCallComboBoxUI();
}
-
+
/**
* Creates the popup portion of the combo box.
*
* @return an instance of ComboPopup
* @see ComboPopup
*/
- protected ComboPopup createPopup() {
+ protected ComboPopup createPopup()
+ {
SIPCommComboPopup popup = new SIPCommComboPopup( comboBox );
popup.getAccessibleContext().setAccessibleParent(comboBox);
+
return popup;
}
@@ -36,7 +39,7 @@ public SIPCommComboPopup(JComboBox combo)
{
super(combo);
}
-
+
/**
* Makes the popup visible if it is hidden and makes it hidden if it is
* visible.
diff --git a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommComboBoxUI.java b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommComboBoxUI.java
index 8bb85eb5d..f3df29fdd 100644
--- a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommComboBoxUI.java
+++ b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommComboBoxUI.java
@@ -1,8 +1,7 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.lookandfeel;
@@ -19,18 +18,22 @@
*
* @author Yana Stamcheva
*/
-public class SIPCommComboBoxUI extends MetalComboBoxUI {
-
- public static ComponentUI createUI(JComponent c) {
+public class SIPCommComboBoxUI
+ extends MetalComboBoxUI
+{
+ public static ComponentUI createUI(JComponent c)
+ {
return new SIPCommComboBoxUI();
}
-
- public void paint(Graphics g, JComponent c) {
+
+ public void paint(Graphics g, JComponent c)
+ {
AntialiasingManager.activateAntialiasing(g);
- super.paint(g, c);
+ super.paint(g, c);
}
-
- protected ComboBoxEditor createEditor() {
+
+ protected ComboBoxEditor createEditor()
+ {
return new SIPCommComboBoxEditor.UIResource();
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommTextFieldUI.java b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommTextFieldUI.java
index 305a58173..c1070c7c0 100644
--- a/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommTextFieldUI.java
+++ b/src/net/java/sip/communicator/impl/gui/lookandfeel/SIPCommTextFieldUI.java
@@ -1,17 +1,19 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.lookandfeel;
import java.awt.*;
+import java.awt.event.*;
+
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.plaf.metal.*;
import javax.swing.text.*;
+import net.java.sip.communicator.impl.gui.customcontrols.*;
import net.java.sip.communicator.impl.gui.utils.*;
/**
@@ -19,20 +21,254 @@
*
* @author Yana Stamcheva
*/
-public class SIPCommTextFieldUI extends MetalTextFieldUI {
+public class SIPCommTextFieldUI
+ extends MetalTextFieldUI
+{
+ private boolean mouseOver = false;
+
+ private boolean mousePressed = false;
+
+ private int buttonState;
+
+ private static int BUTTON_GAP = 5;
+
+ private Image deleteButtonImg;
+
+ private Image deleteButtonRolloverImg;
+
+ private boolean isDeleteButtonEnabled = false;
+
+ private SIPCommButton deleteButton;
+
+ /**
+ * Creates a SIPCommTextFieldUI.
+ */
+ public SIPCommTextFieldUI()
+ {
+ deleteButtonImg
+ = ImageLoader.getImage(ImageLoader.CLOSE_TAB_ICON);
+
+ deleteButtonRolloverImg
+ = ImageLoader.getImage(ImageLoader.CLOSE_ICON);
+
+ deleteButton = new SIPCommButton( deleteButtonImg,
+ deleteButtonRolloverImg);
+
+ deleteButton.setSize ( deleteButtonImg.getWidth(null),
+ deleteButtonImg.getHeight(null));
+ }
- public static ComponentUI createUI(JComponent c) {
+ /**
+ * Returns true if the delete buttons is enabled and false -
+ * otherwise.
+ * @return true if the delete buttons is enabled and false -
+ * otherwise
+ */
+ public boolean isDeleteButtonEnabled()
+ {
+ return isDeleteButtonEnabled;
+ }
+
+ /**
+ * Updates the isDeleteButtonEnabled field.
+ *
+ * @param isDeleteButtonEnabled indicates if the delete buttons is enabled
+ * or not
+ */
+ public void setDeleteButtonEnabled(boolean isDeleteButtonEnabled)
+ {
+ this.isDeleteButtonEnabled = isDeleteButtonEnabled;
+ }
+
+ /**
+ * 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());
+ }
+
+ /**
+ * Creates the UI.
+ *
+ * @param c the component associated with this UI implementation.
+ * @return an instance of this UI implementation
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
return new SIPCommTextFieldUI();
}
-
- protected void paintSafely(Graphics g) {
+
+ /**
+ * Implements parent paintSafely method and enables antialiasing.
+ */
+ protected void paintSafely(Graphics g)
+ {
AntialiasingManager.activateAntialiasing(g);
super.paintSafely(g);
}
-
- protected void paintBackground(Graphics g) {
+
+ /**
+ * Paints the background of the associated component.
+ */
+ protected void paintBackground(Graphics g)
+ {
+ AntialiasingManager.activateAntialiasing(g);
JTextComponent c = this.getComponent();
g.setColor(c.getBackground());
- g.fillRoundRect(1, 1, c.getWidth()-2, c.getHeight()-2, 5, 5);
+ g.fillRoundRect(1, 1, c.getWidth() - 2, c.getHeight() - 2, 5, 5);
+
+ int dx = c.getX() + c.getWidth() - deleteButton.getWidth() - BUTTON_GAP;
+ int dy = (c.getY() + c.getHeight()) / 2 - deleteButton.getHeight()/2;
+
+ if (c.getText() != null
+ && c.getText().length() > 0
+ && isDeleteButtonEnabled)
+ {
+ if (mouseOver)
+ g.drawImage(deleteButtonRolloverImg, dx, dy + 1, null);
+ else
+ g.drawImage(deleteButtonImg, dx, dy + 1, null);
+ }
+ }
+
+ /**
+ * 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 x the x coordinate of the mouse event
+ * @param y the y coordinate of the mouse event
+ */
+ protected void updateDeleteIcon(int x, int y)
+ {
+ if (!isDeleteButtonEnabled)
+ return;
+
+ Rectangle deleteRect = getDeleteButtonRect();
+
+ if (deleteRect.contains(x, y))
+ {
+ mouseOver = true;
+ getComponent().setCursor(Cursor.getDefaultCursor());
+
+ if (mousePressed)
+ getComponent().setText("");
+ }
+ else
+ {
+ mouseOver = false;
+ getComponent().setCursor(
+ Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+ }
+
+ getComponent().repaint();
+ }
+
+ /**
+ * Calculates the delete button rectangle.
+ *
+ * @return the delete button rectangle
+ */
+ protected Rectangle getDeleteButtonRect()
+ {
+ Rectangle rect = getVisibleEditorRect();
+
+ int dx = rect.x + rect.width;
+ int dy = (rect.y + rect.height) / 2 - deleteButton.getHeight()/2;
+
+ return new Rectangle( dx,
+ dy,
+ deleteButton.getWidth(),
+ deleteButton.getHeight());
+ }
+
+ /**
+ * 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.
+ */
+ protected Rectangle getVisibleEditorRect()
+ {
+ if (!isDeleteButtonEnabled)
+ {
+ return super.getVisibleEditorRect();
+ }
+
+ JTextComponent c = getComponent();
+
+ Rectangle alloc = c.getBounds();
+
+ if ((alloc.width > 0) && (alloc.height > 0))
+ {
+ alloc.x = alloc.y = 0;
+ Insets insets = c.getInsets();
+ alloc.x += insets.left;
+ alloc.y += insets.top;
+ alloc.width -= insets.left + insets.right
+ + deleteButton.getWidth();
+ alloc.height -= insets.top + insets.bottom;
+ return alloc;
+ }
+
+ return null;
+ }
+
+ /**
+ * The MouseListener that listens for mouse events in order to
+ * update the delete icon.
+ */
+ protected class TextFieldMouseListener implements MouseListener
+ {
+ public void mouseClicked(MouseEvent e)
+ {}
+
+ public void mouseEntered(MouseEvent e)
+ {
+ updateDeleteIcon(e.getX(), e.getY());
+ }
+
+ public void mouseExited(MouseEvent e)
+ {
+ updateDeleteIcon(e.getX(), e.getY());
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+ mousePressed = true;
+
+ updateDeleteIcon(e.getX(), e.getY());
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ mousePressed = false;
+
+ updateDeleteIcon(e.getX(), e.getY());
+ }
+ }
+
+ /**
+ * The MouseMotionListener that listens for mouse events in order
+ * to update the delete icon.
+ */
+ protected class TextFieldMouseMotionListener implements MouseMotionListener
+ {
+ public void mouseDragged(MouseEvent e)
+ {
+ updateDeleteIcon(e.getX(), e.getY());
+ }
+
+ public void mouseMoved(MouseEvent e)
+ {
+ updateDeleteIcon(e.getX(), e.getY());
+ }
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallComboBox.java b/src/net/java/sip/communicator/impl/gui/main/call/CallComboBox.java
index 7642a753c..5669dd09d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallComboBox.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallComboBox.java
@@ -1,8 +1,7 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.call;
@@ -15,42 +14,41 @@
import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.service.contactlist.*;
-
+
/**
- * The CallComboBox is a history editable combo box that is positioned
- * above call and hangup buttons and is used when writing a number or a contact
- * name in order to be called.
+ * The CallComboBox is a history editable combo box that is
+ * positioned above call and hangup buttons and is used when writing a number or
+ * a contact name in order to be called.
*
* @author Yana Stamcheva
*/
public class CallComboBox
- extends SmartComboBox
- implements ActionListener,
- DocumentListener
-{
-
+ extends SIPCommSmartComboBox
+ implements ActionListener, DocumentListener
+{
private CallManager callManager;
-
+
public final static int MAX_COMBO_SIZE = 10;
-
- public CallComboBox(CallManager callManager) {
-
+
+ public CallComboBox(CallManager callManager)
+ {
this.callManager = callManager;
-
+
this.setUI(new SIPCommCallComboBoxUI());
this.addActionListener(this);
-
- JTextField textField = (JTextField)this.getEditor().getEditorComponent();
-
+
+ JTextField textField =
+ (JTextField) this.getEditor().getEditorComponent();
+
textField.getDocument().addDocumentListener(this);
-
+
textField.getActionMap().put("createCall", new CreateCallAction());
textField.getInputMap().put(
- KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "createCall");
+ KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "createCall");
}
-
+
/**
- * Checks if this combo box editor field is empty. This will be the case if
+ * Checks if this combobox editor field is empty. This will be the case if
* the user hasn't selected an item from the combobox and hasn't written
* anything the field.
*
@@ -58,69 +56,86 @@ public CallComboBox(CallManager callManager) {
*/
public boolean isComboFieldEmpty()
{
- String item = ((CallComboEditor)this.getEditor()).getItem().toString();
-
- if(item.length() > 0)
+ String item = ((CallComboEditor) this.getEditor()).getItem().toString();
+
+ if (item.length() > 0)
return false;
else
return true;
}
-
+
/**
- * Handles events triggered by user selection. Enables the call button
- * when user selects something in the combo box.
+ * Handles events triggered by user selection. Enables the call button when
+ * user selects something in the combo box.
*/
public void actionPerformed(ActionEvent e)
- {
+ {
callManager.setCallMetaContact(false);
callManager.getCallButton().setEnabled(true);
}
- public void insertUpdate(DocumentEvent e) { handleChange(); }
- public void removeUpdate(DocumentEvent e) { handleChange(); }
- public void changedUpdate(DocumentEvent e) {}
-
+ public void insertUpdate(DocumentEvent e)
+ {
+ handleChange();
+ }
+
+ public void removeUpdate(DocumentEvent e)
+ {
+ handleChange();
+ }
+
+ public void changedUpdate(DocumentEvent e)
+ {
+ }
+
/**
- * Enables or disabled the call button according to the content in the
- * combo box editor field.
+ * Enables or disabled the call button according to the content in the combo
+ * box editor field.
*/
- protected void handleChange() {
- String item = ((CallComboEditor)this.getEditor()).getItem().toString();
-
- if (item.length() > 0) {
+ protected void handleChange()
+ {
+ String item = ((CallComboEditor) this.getEditor()).getItem().toString();
+
+ if (item.length() > 0)
+ {
callManager.setCallMetaContact(false);
- ContactList clist = this.callManager.getMainFrame()
- .getContactListPanel().getContactList();
-
- clist.removeSelectionInterval(
- clist.getSelectedIndex(), clist.getSelectedIndex());
-
+ ContactList clist =
+ this.callManager.getMainFrame().getContactListPanel()
+ .getContactList();
+
+ clist.removeSelectionInterval(clist.getSelectedIndex(), clist
+ .getSelectedIndex());
+
callManager.getCallButton().setEnabled(true);
}
- else {
- Object o = callManager.getMainFrame().getContactListPanel()
- .getContactList().getSelectedValue();
-
- if(o == null || !(o instanceof MetaContact))
+ else
+ {
+ Object o =
+ callManager.getMainFrame().getContactListPanel()
+ .getContactList().getSelectedValue();
+
+ if (o == null || !(o instanceof MetaContact))
callManager.getCallButton().setEnabled(false);
}
}
-
+
/**
- * Creates a call to the contact given by the string in the combo box
- * editor field.
+ * Creates a call to the contact given by the string in the combo box editor
+ * field.
*/
- private class CreateCallAction extends AbstractAction
+ private class CreateCallAction
+ extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
- String item = ((CallComboEditor)getEditor()).getItem().toString();
-
- if(item.length() > 0)
+ String item = ((CallComboEditor) getEditor()).getItem().toString();
+
+ if (item.length() > 0)
callManager.createCall(item);
- else {
- if(!isPopupVisible())
+ else
+ {
+ if (!isPopupVisible())
setPopupVisible(true);
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallListPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/CallListPanel.java
index bc2251574..c6f369923 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallListPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallListPanel.java
@@ -14,7 +14,7 @@
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.customcontrols.*;
-import net.java.sip.communicator.impl.gui.customcontrols.SmartComboBox.*;
+import net.java.sip.communicator.impl.gui.customcontrols.SIPCommSmartComboBox.*;
import net.java.sip.communicator.impl.gui.i18n.*;
import net.java.sip.communicator.impl.gui.main.*;
import net.java.sip.communicator.impl.gui.utils.*;
@@ -37,7 +37,7 @@ public class CallListPanel
private JLabel searchLabel = new JLabel(
Messages.getI18NString("search").getText() + ": ");
- private SmartComboBox searchComboBox = new SmartComboBox();
+ private SIPCommSmartComboBox searchComboBox = new SIPCommSmartComboBox();
private CallList callList = new CallList();