package net.java.sip.communicator.plugin.accountinfo; /* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. See terms of license at gnu.org. */ import java.awt.*; import java.awt.event.*; import java.io.*; import java.text.*; import java.util.*; import javax.imageio.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.filechooser.FileFilter; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; import net.java.sip.communicator.util.*; /** * The right side panel of AccountDetailsDialog. Shows one tab of a summary of * contact information for the selected subcontact, and has an extended tab * listing all of the details. * * @author Yana Stamcheva */ public class AccountDetailsPanel extends JPanel { private Logger logger = Logger.getLogger(AccountDetailsPanel.class); /** * The operation set giving access to the server stored account details. */ private OperationSetServerStoredAccountInfo accountInfoOpSet; /** * The protocol provider. */ private ProtocolProviderService protocolProvider; private JTextField firstNameField = new JTextField(); private JTextField middleNameField = new JTextField(); private JTextField lastNameField = new JTextField(); private JTextField genderField = new JTextField(); private JTextField ageField = new JTextField(); private JTextField birthdayField = new JTextField(); private JTextField emailField = new JTextField(); private JTextField phoneField = new JTextField(); private JLabel avatarLabel = new JLabel(); private JButton applyButton = new JButton(Resources.getString("apply")); private JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); private JPanel mainPanel = new JPanel(new BorderLayout()); private JScrollPane mainScrollPane = new JScrollPane(); private boolean isDataLoaded = false; private FirstNameDetail firstNameDetail; private MiddleNameDetail middleNameDetail; private LastNameDetail lastNameDetail; private GenderDetail genderDetail; private BirthDateDetail birthDateDetail; private EmailAddressDetail emailDetail; private PhoneNumberDetail phoneDetail; private BinaryDetail avatarDetail; private byte[] newAvatarImage; /** * The last avatar file directory open. */ private File lastAvatarDir; /** * Construct a panel containing all account details for the given protocol * provider. * * @param protocolProvider the protocol provider service */ public AccountDetailsPanel(ProtocolProviderService protocolProvider) { super(new BorderLayout()); this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // this.setPreferredSize(new Dimension(500, 400)); accountInfoOpSet = (OperationSetServerStoredAccountInfo) protocolProvider .getOperationSet(OperationSetServerStoredAccountInfo.class); this.protocolProvider = protocolProvider; if (accountInfoOpSet == null) { initUnsupportedPanel(); } else { this.initSummaryPanel(); if (protocolProvider.isRegistered()) { loadDetails(); } } } private void initSummaryPanel() { JPanel summaryPanel = new JPanel(new BorderLayout(10, 10)); summaryPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); summaryPanel.setSize(this.getWidth(), this.getHeight()); // Create the avatar panel. JPanel leftPanel = new JPanel(new BorderLayout()); JPanel avatarPanel = new JPanel(new BorderLayout()); JButton changeAvatarButton = new JButton(Resources.getString("change")); JPanel changeButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); changeAvatarButton.addActionListener(new ChangeAvatarActionListener()); avatarLabel.setIcon(Resources.getImage("accountInfoDefaultPersonIcon")); changeButtonPanel.add(changeAvatarButton); avatarPanel.add(avatarLabel, BorderLayout.CENTER); avatarPanel.add(changeButtonPanel, BorderLayout.SOUTH); leftPanel.add(avatarPanel, BorderLayout.NORTH); summaryPanel.add(leftPanel, BorderLayout.WEST); // Create the summary details panel. JPanel detailsPanel = new JPanel(new BorderLayout(10, 10)); detailsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); summaryPanel.add(detailsPanel, BorderLayout.CENTER); // Labels panel. JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 5, 5)); labelsPanel.add(new JLabel(Resources.getString("firstNameNS"))); // labelsPanel.add(new JLabel(Resources.getString("middleNameNS"))); labelsPanel.add(new JLabel(Resources.getString("lastNameNS"))); labelsPanel.add(new JLabel(Resources.getString("genderNS"))); labelsPanel.add(new JLabel(Resources.getString("ageNS"))); labelsPanel.add(new JLabel(Resources.getString("bdayNS"))); labelsPanel.add(new JLabel(Resources.getString("emailNS"))); labelsPanel.add(new JLabel(Resources.getString("phoneNS"))); detailsPanel.add(labelsPanel, BorderLayout.WEST); // Values panel. JPanel valuesPanel = new JPanel(new GridLayout(0, 1, 5, 5)); valuesPanel.add(firstNameField); // valuesPanel.add(middleNameField); valuesPanel.add(lastNameField); valuesPanel.add(genderField); valuesPanel.add(ageField); valuesPanel.add(birthdayField); valuesPanel.add(emailField); valuesPanel.add(phoneField); detailsPanel.add(valuesPanel, BorderLayout.CENTER); this.mainScrollPane.getViewport().add(summaryPanel); this.add(mainScrollPane, BorderLayout.NORTH); this.applyButton.addActionListener(new SubmitActionListener()); this.buttonPanel.add(applyButton); this.add(buttonPanel, BorderLayout.SOUTH); } /** * Loads details for */ public void loadDetails() { this.loadSummaryDetails(); this.isDataLoaded = true; } /** * Creates the panel that indicates to the user that the currently selected * contact does not support server stored contact info. * * @return the panel that is added and shows a message that the selected * sub-contact does not have the operation set for server stored * contact info supported. */ private void initUnsupportedPanel() { JTextArea unsupportedTextArea = new JTextArea(Resources.getString("notSupported")); unsupportedTextArea.setEditable(false); unsupportedTextArea.setLineWrap(true); JPanel unsupportedPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); unsupportedTextArea.setPreferredSize(new Dimension(200, 200)); unsupportedPanel.setBorder( BorderFactory.createEmptyBorder(50, 20, 50, 20)); unsupportedPanel.add(unsupportedTextArea); this.add(unsupportedPanel); } /** * Creates a panel that can be added as the summary tab that displays the * following details: - *
* Avatar(Contact image) - FirstNameDetail - MiddleNameDetail -
* LastNameDetail - BirthdateDetail (and calculate age) - GenderDetail -
* EmailAddressDetail - PhoneNumberDetail. All other details will be* added
* to our list of extended details.
*
* @return the panel that will be added as the summary tab.
*/
private void loadSummaryDetails()
{
Iterator contactDetails;
// Avatar details.
contactDetails
= accountInfoOpSet.getDetails(BinaryDetail.class);
byte[] avatarImage = null;
if (contactDetails.hasNext())
{
avatarDetail = (BinaryDetail) contactDetails.next();
avatarImage = avatarDetail.getBytes();
}
if (avatarImage != null && avatarImage.length > 0)
avatarLabel.setIcon(new ImageIcon(
getScaledImageInstance(avatarImage)));
// First name details.
contactDetails =
accountInfoOpSet.getDetails(FirstNameDetail.class);
String firstNameDetailString = "";
while (contactDetails.hasNext())
{
firstNameDetail = (FirstNameDetail) contactDetails.next();
firstNameDetailString =
firstNameDetailString + " " + firstNameDetail.getDetailValue();
}
firstNameField.setText(firstNameDetailString);
// Middle name details.
contactDetails =
accountInfoOpSet.getDetails(MiddleNameDetail.class);
String middleNameDetailString = "";
while (contactDetails.hasNext())
{
middleNameDetail = (MiddleNameDetail) contactDetails.next();
middleNameDetailString =
middleNameDetailString + " " + middleNameDetail.getDetailValue();
}
middleNameField.setText(middleNameDetailString);
// Last name details.
contactDetails =
accountInfoOpSet.getDetails(LastNameDetail.class);
String lastNameDetailString = "";
while (contactDetails.hasNext())
{
lastNameDetail = (LastNameDetail) contactDetails.next();
lastNameDetailString =
lastNameDetailString + " " + lastNameDetail.getDetailValue();
}
lastNameField.setText(lastNameDetailString);
// Gender details.
contactDetails =
accountInfoOpSet.getDetails(GenderDetail.class);
String genderDetailString = "";
while (contactDetails.hasNext())
{
genderDetail = (GenderDetail) contactDetails.next();
genderDetailString = genderDetailString + " "
+ genderDetail.getDetailValue();
}
genderField.setText(genderDetailString);
// Birthday details.
contactDetails =
accountInfoOpSet.getDetails(BirthDateDetail.class);
String birthDateDetailString = "";
String ageDetail = "";
if (contactDetails.hasNext())
{
birthDateDetail = (BirthDateDetail) contactDetails.next();
Calendar calendarDetail =
(Calendar) birthDateDetail.getDetailValue();
Date birthDate = calendarDetail.getTime();
DateFormat dateFormat = DateFormat.getDateInstance();
birthDateDetailString = dateFormat.format(birthDate).trim();
Calendar c = Calendar.getInstance();
int age = c.get(Calendar.YEAR) - calendarDetail.get(Calendar.YEAR);
if (c.get(Calendar.MONTH) < calendarDetail.get(Calendar.MONTH))
age--;
ageDetail = new Integer(age).toString().trim();
}
birthdayField.setText(birthDateDetailString);
ageField.setText(ageDetail);
// Email details.
contactDetails =
accountInfoOpSet.getDetails(EmailAddressDetail.class);
String emailDetailString = "";
while (contactDetails.hasNext())
{
emailDetail = (EmailAddressDetail) contactDetails.next();
emailDetailString = emailDetailString + " "
+ emailDetail.getDetailValue();
}
emailField.setText(emailDetailString);
// Phone number details.
contactDetails =
accountInfoOpSet.getDetails(PhoneNumberDetail.class);
String phoneNumberDetailString = "";
while (contactDetails.hasNext())
{
phoneDetail = (PhoneNumberDetail) contactDetails.next();
phoneNumberDetailString =
phoneNumberDetailString + " " + phoneDetail.getDetailValue();
}
phoneField.setText(phoneNumberDetailString);
}
/**
* A panel that displays all of the details retrieved from the opSet.
*/
private void initExtendedPanel()
{
JPanel mainExtendedPanel = new JPanel(new BorderLayout());
JPanel extendedPanel = new JPanel();
extendedPanel.setLayout(new BoxLayout(extendedPanel, BoxLayout.Y_AXIS));
JPanel imagePanel = new JPanel();
// The imagePanel will be used for any BinaryDetails and will be added at
// the bottom so we don't disrupt the standard look of the other details
imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.LINE_AXIS));
imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
.createTitledBorder(Resources.getString("userPictures")),
BorderFactory.createEmptyBorder(0, 5, 5, 5)));
// Obtain all the details for a contact.
Iterator iter = accountInfoOpSet.getAllAvailableDetails();
GenericDetail detail;
JLabel detailLabel;
JTextArea detailValueArea;
JPanel detailPanel;
while (iter.hasNext())
{
detail = (GenericDetail) iter.next();
if (detail.getDetailValue().toString().equals(""))
continue;
detailLabel = new JLabel();
detailValueArea = new JTextArea();
detailPanel = new JPanel(new BorderLayout(10, 10));
detailValueArea.setAlignmentX(JTextArea.CENTER_ALIGNMENT);
detailValueArea.setLineWrap(true);
detailValueArea.setEditable(true);
detailPanel.add(detailLabel, BorderLayout.WEST);
detailPanel.add(detailValueArea, BorderLayout.CENTER);
detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
extendedPanel.add(detailPanel);
if (detail instanceof BinaryDetail)
{
JLabel imageLabel =
new JLabel(new ImageIcon((byte[]) detail
.getDetailValue()));
imagePanel.add(imageLabel);
}
else if (detail instanceof CalendarDetail)
{
detailLabel.setText(detail.getDetailDisplayName() + ": ");
Date detailDate =
((Calendar) detail.getDetailValue()).getTime();
DateFormat df = DateFormat.getDateInstance();
detailValueArea.setText(df.format(detailDate).trim());
}
else if (detail instanceof LocaleDetail)
{
detailLabel.setText(detail.getDetailDisplayName() + ": ");
detailValueArea.setText(((Locale) detail.getDetailValue())
.getDisplayName().trim());
}
else if (detail instanceof TimeZoneDetail)
{
detailLabel.setText(detail.getDetailDisplayName() + ": ");
detailValueArea.setText(((TimeZone) detail.getDetailValue())
.getDisplayName().trim());
}
else
{
detailLabel.setText(detail.getDetailDisplayName() + ": ");
detailValueArea.setText(
detail.getDetailValue().toString().trim());
}
}
// If the contact's protocol supports web info, give them a button to
// get it
if (protocolProvider.getOperationSet(
OperationSetWebContactInfo.class) != null)
{
final String urlString
= ((OperationSetWebContactInfo) protocolProvider
.getOperationSet(OperationSetWebContactInfo.class))
.getWebContactInfo(
protocolProvider.getAccountID().getAccountAddress())
.toString();
JLabel webInfoLabel = new JLabel("Click to see web info: ");
JEditorPane webInfoValue = new JEditorPane();
JPanel webInfoPanel = new JPanel(new BorderLayout());
webInfoPanel.add(webInfoLabel, BorderLayout.WEST);
webInfoPanel.add(webInfoValue, BorderLayout.CENTER);
extendedPanel.add(webInfoPanel);
webInfoValue.setOpaque(false);
webInfoValue.setContentType("text/html");
webInfoValue.setEditable(false);
webInfoValue.setText( ""
+ protocolProvider.getAccountID().getUserID()
+ " web info");
webInfoValue.addHyperlinkListener(new HyperlinkListener()
{
public void hyperlinkUpdate(HyperlinkEvent e)
{
if (e.getEventType()
.equals(HyperlinkEvent.EventType.ACTIVATED))
{
AccountInfoActivator
.getBrowserLauncher().openURL(urlString);
}
}
});
}
if (imagePanel.getComponentCount() > 0)
mainExtendedPanel.add(imagePanel, BorderLayout.CENTER);
mainExtendedPanel.add(extendedPanel, BorderLayout.NORTH);
this.mainPanel.add(mainExtendedPanel);
this.mainPanel.revalidate();
this.mainPanel.repaint();
}
private class SubmitActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String firstName = firstNameField.getText();
String middleName = middleNameField.getText();
String lastName = lastNameField.getText();
String gender = genderField.getText();
String email = emailField.getText();
String phoneNumber = phoneField.getText();
Icon avatar = avatarLabel.getIcon();
Calendar birthDateCalendar = Calendar.getInstance();
if(birthdayField.getText() != null
&& birthdayField.getText().length() > 0)
{
try
{
DateFormat dateFormat
= DateFormat.getDateInstance(DateFormat.DEFAULT);
Date birthDate = dateFormat.parse(birthdayField.getText());
birthDateCalendar.setTime(birthDate);
}
catch (ParseException e2)
{
logger.error("Failed to parse birth date.", e2);
}
}
try
{
FirstNameDetail newFirstNameDetail
= new ServerStoredDetails.FirstNameDetail(firstName);
if (firstNameDetail == null)
accountInfoOpSet.addDetail(newFirstNameDetail);
else
accountInfoOpSet.replaceDetail( firstNameDetail,
newFirstNameDetail);
// MiddleNameDetail newMiddleNameDetail
// = new ServerStoredDetails.MiddleNameDetail(middleName);
//
// if (middleNameDetail == null)
// accountInfoOpSet.addDetail(newMiddleNameDetail);
// else
// accountInfoOpSet.replaceDetail( middleNameDetail,
// newMiddleNameDetail);
LastNameDetail newLastNameDetail
= new ServerStoredDetails.LastNameDetail(lastName);
if (lastNameDetail == null)
accountInfoOpSet.addDetail(newLastNameDetail);
else
accountInfoOpSet.replaceDetail( lastNameDetail,
newLastNameDetail);
GenderDetail newGenderDetail
= new ServerStoredDetails.GenderDetail(gender);
if (genderDetail == null)
accountInfoOpSet.addDetail(newGenderDetail);
else
accountInfoOpSet.replaceDetail( genderDetail,
newGenderDetail);
BirthDateDetail newBirthDateDetail
= new ServerStoredDetails.BirthDateDetail(birthDateCalendar);
if (birthDateDetail == null)
accountInfoOpSet.addDetail(newBirthDateDetail);
else
accountInfoOpSet.replaceDetail( birthDateDetail,
newBirthDateDetail);
EmailAddressDetail newEmailDetail
= new ServerStoredDetails.EmailAddressDetail(email);
if (emailDetail == null)
accountInfoOpSet.addDetail(newEmailDetail);
else
accountInfoOpSet.replaceDetail( emailDetail,
newEmailDetail);
PhoneNumberDetail newPhoneDetail
= new ServerStoredDetails.PhoneNumberDetail(phoneNumber);
if (phoneDetail == null)
accountInfoOpSet.addDetail(newPhoneDetail);
else
accountInfoOpSet.replaceDetail( phoneDetail,
newPhoneDetail);
BinaryDetail newAvatarDetail
= new ServerStoredDetails.BinaryDetail(
"Avatar",
newAvatarImage);
if (avatarDetail == null)
accountInfoOpSet.addDetail(newAvatarDetail);
else
accountInfoOpSet.replaceDetail( avatarDetail,
newAvatarDetail);
}
catch (ClassCastException e1)
{
logger.error("Failed to update account details.", e1);
}
catch (OperationFailedException e1)
{
logger.error("Failed to update account details.", e1);
}
}
}
private class ChangeAvatarActionListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JFileChooser chooser = new JFileChooser(lastAvatarDir);
chooser.addChoosableFileFilter(new ImageFilter());
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION)
{
try
{
File file = chooser.getSelectedFile();
lastAvatarDir = file.getParentFile();
FileInputStream in = new FileInputStream(file);
byte buffer[] = new byte[in.available()];
in.read(buffer);
if (buffer == null || buffer.length <= 0)
return;
newAvatarImage = buffer;
avatarLabel.setIcon(new ImageIcon(
getScaledImageInstance(newAvatarImage)));
}
catch (IOException ex)
{
logger.error("Failed to load image.", ex);
}
}
}
}
/**
* A custom filter that would accept only image files.
*/
private class ImageFilter extends FileFilter
{
/**
* Accept all directories and all gif, jpg, tiff, or png files.
*/
public boolean accept(File f)
{
if (f.isDirectory())
{
return true;
}
String extension = getExtension(f);
if (extension != null)
{
if (extension.equals("tiff") ||
extension.equals("tif") ||
extension.equals("gif") ||
extension.equals("jpeg") ||
extension.equals("jpg") ||
extension.equals("png"))
{
return true;
}
else
{
return false;
}
}
return false;
}
/**
* Get the extension of a file.
*/
public String getExtension(File f)
{
String ext = null;
String s = f.getName();
int i = s.lastIndexOf('.');
if (i > 0 && i < s.length() - 1) {
ext = s.substring(i+1).toLowerCase();
}
return ext;
}
/**
* The description of this filter.
*/
public String getDescription()
{
return Resources.getString("onlyMessages");
}
}
/**
* Returns a scaled Image instance of the given byte image.
*
* @param image the image in bytes
* @return a scaled Image instance of the given byte image.
*/
private Image getScaledImageInstance(byte[] image)
{
Image resultImage = null;
try
{
resultImage = ImageIO.read(
new ByteArrayInputStream(image));
}
catch (Exception e)
{
logger.error("Failed to convert bytes to image.", e);
}
if(resultImage == null)
return null;
return resultImage.getScaledInstance(
avatarLabel.getWidth(),
avatarLabel.getHeight(),
Image.SCALE_SMOOTH);
}
/**
* Returns true
if the account details are loaded,
* false
- otherwise.
*
* @return true
if the account details are loaded,
* false
- otherwise
*/
public boolean isDataLoaded()
{
return isDataLoaded;
}
}