Update the gui for avatar choosing, add some javadocs.

cusax-fix
Damian Minkov 15 years ago
parent 4876c2b79c
commit 398249470e

@ -182,6 +182,7 @@ service.gui.buttons.SEARCH_CALL_ICON=resources/images/impl/gui/buttons/searchCal
service.gui.buttons.SEARCH_CALL_ROLLOVER_ICON=resources/images/impl/gui/buttons/searchCallRolloverIcon.png
service.gui.buttons.ZOOM_OUT=resources/images/impl/gui/buttons/magnifier_zoom_out.png
service.gui.buttons.ZOOM_IN=resources/images/impl/gui/buttons/magnifier_zoom_in.png
service.gui.buttons.RESET=resources/images/impl/gui/buttons/reset.png
# Sound level icons
service.gui.soundlevel.SOUND_LEVEL_ACTIVE=resources/images/impl/gui/common/soundlevel/soundActive.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

@ -289,15 +289,19 @@ public Component getTableCellRendererComponent(
this.setText(pps.getAccountID().getDisplayName());
byte[] protocolStatusImage = presence.getPresenceStatus().getStatusIcon();
if(protocolStatusImage != null)
{
this.setIcon(new ImageIcon(protocolStatusImage));
}
else
if(presence.getPresenceStatus() != null)
{
this.setIcon(null);
byte[] protocolStatusImage =
presence.getPresenceStatus().getStatusIcon();
if(protocolStatusImage != null)
{
this.setIcon(new ImageIcon(protocolStatusImage));
}
else
{
this.setIcon(null);
}
}
if(isSelected)

@ -7,6 +7,7 @@
package net.java.sip.communicator.impl.gui.main.presence.avatar.imagepicker;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
@ -24,12 +25,13 @@
*/
public class EditPanel
extends TransparentPanel
implements ChangeListener
implements ChangeListener,
ActionListener
{
private ImageClipper imageClipper;
private BufferedImage image;
private JSlider imageSizeSlider;
private JLabel zoomIn, zoomOut;
private JButton zoomIn, zoomOut, reset;
private boolean resizeOnWidth = true;
private boolean smallImage = false;
@ -52,11 +54,17 @@ public EditPanel(int clippingZoneWidth, int clippingZoneHeight)
this.clippingZoneWidth = clippingZoneWidth;
this.clippingZoneHeight = clippingZoneHeight;
this.zoomOut = new JLabel(GuiActivator.getResources()
this.zoomOut = new JButton(GuiActivator.getResources()
.getImage("service.gui.buttons.ZOOM_OUT"));
this.zoomIn = new JLabel(GuiActivator.getResources()
this.zoomOut.addActionListener(this);
this.zoomIn = new JButton(GuiActivator.getResources()
.getImage("service.gui.buttons.ZOOM_IN"));
this.zoomIn.addActionListener(this);
this.reset = new JButton(GuiActivator.getResources()
.getImage("service.gui.buttons.RESET"));
this.reset.setToolTipText(GuiActivator.getResources()
.getI18NString("service.gui.avatar.imagepicker.RESET"));
this.reset.addActionListener(this);
imageSizeSlider = new JSlider(clippingZoneWidth, clippingZoneWidth,
clippingZoneWidth);
@ -66,9 +74,10 @@ public EditPanel(int clippingZoneWidth, int clippingZoneHeight)
.getI18NString("service.gui.avatar.imagepicker.IMAGE_SIZE"));
TransparentPanel sliderPanel = new TransparentPanel();
sliderPanel.add(this.zoomOut);
sliderPanel.add(zoomOut);
sliderPanel.add(this.imageSizeSlider);
sliderPanel.add(this.zoomIn);
sliderPanel.add(this.reset);
this.imageClipper = new ImageClipper(this.clippingZoneWidth,
this.clippingZoneHeight);
@ -153,7 +162,7 @@ public byte[] getClippedImage()
BufferedImage fullImage = getResizedImage(true);
Rectangle clipping = this.imageClipper.getClipping();
Rectangle clipping = this.imageClipper.getCroppedArea();
BufferedImage subImage = fullImage.getSubimage(clipping.x, clipping.y,
clipping.width, clipping.height);
@ -193,6 +202,9 @@ private BufferedImage getResizedImage(boolean hq)
return i;
}
/**
* Draw the image.
*/
private void drawImage()
{
// Use high quality scalling when the image is smaller than the clipper
@ -204,11 +216,43 @@ private void enableSlider(boolean enabled)
this.imageSizeSlider.setEnabled(enabled);
this.zoomIn.setEnabled(enabled);
this.zoomOut.setEnabled(enabled);
this.reset.setEnabled(enabled);
}
/**
* New size image selected update the clipper.
* @param e the event.
*/
public void stateChanged(ChangeEvent e)
{
// New size selected update the clipper
drawImage();
}
/**
* Listens for button actions.
* @param e
*/
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals(zoomIn))
{
if(imageSizeSlider.getValue() < imageSizeSlider.getMaximum())
{
imageSizeSlider.setValue(imageSizeSlider.getValue() + 1);
drawImage();
}
}
else if(e.getSource().equals(zoomOut))
{
if(imageSizeSlider.getValue() > imageSizeSlider.getMinimum())
{
imageSizeSlider.setValue(imageSizeSlider.getValue() - 1);
drawImage();
}
}
else if(e.getSource().equals(reset))
{
reset();
}
}
}

@ -15,160 +15,195 @@
import net.java.sip.communicator.util.swing.*;
/**
* Component allowing the user to easily clip an image
* Component allowing the user to easily crop an image
*
* @author Damien Roth
* @author Damian Minkov
*/
public class ImageClipper
extends JComponent
implements MouseListener, MouseMotionListener
implements MouseListener,
MouseMotionListener
{
private static final int CLIP_PANEL_WIDTH = 320;
private static final int CLIP_PANEL_HEIGHT = 240;
/**
* Border of the image.
*/
private static final Color IMAGE_BORDER_COLOR
= new Color(174, 189, 215);
/**
* Image overlay color.
*/
private static final Color IMAGE_OVERLAY_COLOR
= new Color(1.0f, 1.0f, 1.0f, 0.4f);
/**
* The last remembered component width, to see when component is resized.
*/
private int lastComponentWidth = 0;
/**
* The last remembered component height, to see when component is resized.
*/
private int lastComponentHeight = 0;
/**
* The image that we will crop.
*/
private BufferedImage image = null;
private Rectangle imageRect;
private Point imageBottomRight;
private Rectangle clippingZoneRect;
private Point clippingZoneBottomRight;
/**
* The rectangle in which we are currently drawing the image.
*/
private Rectangle imageRect = new Rectangle();
/**
* The zone that we will crop later from the image.
*/
private Rectangle cropZoneRect;
// Mouse drag vars
/**
* Used for mouse dragging.
* This is every time the initial X coordinate of the mouse
* and the coordinates are according the image.
*/
private int mouseStartX;
/**
* Used for mouse dragging.
* This is every time the initial Y coordinate of the mouse
* and the coordinates are according the image.
*/
private int mouseStartY;
private int xInit;
private int yInit;
/**
* Construct an new image clipper
* Construct an new image cropper
*
* @param cropZoneWidth the width of the clip zone
* @param cropZoneHeight the height of the clip zone
* @param cropZoneWidth the width of the crop zone
* @param cropZoneHeight the height of the crop zone
*/
public ImageClipper(int cropZoneWidth, int cropZoneHeight)
{
Dimension d = new Dimension(CLIP_PANEL_WIDTH, CLIP_PANEL_HEIGHT);
this.cropZoneRect = new Rectangle(cropZoneWidth, cropZoneHeight);
updateCropZone();
Dimension d = new Dimension(320, 240);
this.setSize(d);
this.setMaximumSize(d);
this.setMinimumSize(d);
this.setPreferredSize(d);
this.initClippingZone(cropZoneWidth, cropZoneHeight);
this.imageRect = new Rectangle(this.clippingZoneRect.getLocation());
this.imageBottomRight = new Point(0,0);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
/**
* Compute static values of the clipping zone
*
* @param width the width of the clipping zone
* @param height the height of the clipping zone
* Compute static values of the cropping zone
*/
private void initClippingZone(int width, int height)
private void updateCropZone()
{
this.clippingZoneRect = new Rectangle(width, height);
this.clippingZoneRect.x = (CLIP_PANEL_WIDTH / 2) - (width / 2);
this.clippingZoneRect.y = (CLIP_PANEL_HEIGHT / 2) - (height / 2);
this.clippingZoneBottomRight = new Point(
this.clippingZoneRect.x + this.clippingZoneRect.width,
this.clippingZoneRect.y + this.clippingZoneRect.height
);
this.cropZoneRect.x =
(this.getWidth() / 2) - (this.cropZoneRect.width / 2);
this.cropZoneRect.y =
(this.getHeight() / 2) - (this.cropZoneRect.height / 2);
}
/**
* Defines the image to be clipped
* Defines the image to be cropped
*
* @param image the image to be clipped
* @param image the image to be cropped
*/
public void setImage(BufferedImage image)
{
boolean updated = false;
this.image = image;
this.imageRect.width = image.getWidth(this);
this.imageRect.height = image.getHeight(this);
// put the image in the center
this.imageRect.x = (this.getWidth() - this.imageRect.width)/2;
this.imageRect.y = (this.getHeight() - this.imageRect.height)/2;
// set the initial values
this.lastComponentHeight = this.getHeight();
this.lastComponentWidth = this.getWidth();
updateImagePoints();
this.imageBottomRight.x = this.imageRect.x + this.imageRect.width;
this.imageBottomRight.y = this.imageRect.y + this.imageRect.height;
if (this.imageBottomRight.x < this.clippingZoneBottomRight.x)
{
this.imageRect.x +=
this.clippingZoneBottomRight.x - this.imageBottomRight.x;
updated = true;
}
if (this.imageBottomRight.y < this.clippingZoneBottomRight.y)
this.repaint();
}
/**
* Update image points if needed, when component is resized.
*/
private void updateImagePoints()
{
if(lastComponentWidth != this.getWidth())
{
this.imageRect.y +=
this.clippingZoneBottomRight.y - this.imageBottomRight.y;
updated = true;
this.imageRect.x += (this.getWidth() - lastComponentWidth)/2;
lastComponentWidth = this.getWidth();
}
if (updated)
if(lastComponentHeight != this.getHeight())
{
this.imageBottomRight.x = this.imageRect.x + this.imageRect.width;
this.imageBottomRight.y = this.imageRect.y + this.imageRect.height;
this.imageRect.y += (this.getHeight() - lastComponentHeight)/2;
lastComponentHeight = this.getHeight();
}
this.repaint();
}
/**
* Returns the clipped area of the image
* Returns the cropped area of the image
*
* @return the clipped area
* @return the cropped area
*/
public Rectangle getClipping()
public Rectangle getCroppedArea()
{
Rectangle clipping = new Rectangle();
Rectangle croppedArea = new Rectangle();
clipping.setSize(this.clippingZoneRect.getSize());
clipping.x = this.clippingZoneRect.x - this.imageRect.x;
clipping.y = this.clippingZoneRect.y - this.imageRect.y;
croppedArea.setSize(this.cropZoneRect.getSize());
croppedArea.x = this.cropZoneRect.x - this.imageRect.x;
croppedArea.y = this.cropZoneRect.y - this.imageRect.y;
return clipping;
return croppedArea;
}
/**
* Paint the component with the image we have and the settings
* we have for it.
* @param g the graphics to draw.
*/
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g = g.create();
AntialiasingManager.activateAntialiasing(g);
// Draw image
updateImagePoints();
g.drawImage(this.image, this.imageRect.x, this.imageRect.y,
this.imageRect.width, this.imageRect.height, this);
// Select rect
updateCropZone();
g.setColor(Color.BLACK);
g.drawRect(this.cropZoneRect.x, this.cropZoneRect.y,
this.cropZoneRect.width, this.cropZoneRect.height);
// Image overlay
drawImageOverlay(g);
// Image border
g.setColor(ImageClipper.IMAGE_BORDER_COLOR);
g.setColor(IMAGE_BORDER_COLOR);
g.drawRoundRect(this.imageRect.x-2, this.imageRect.y-2,
this.imageRect.width+3, this.imageRect.height+3, 2, 2);
g.drawRoundRect(this.imageRect.x-1, this.imageRect.y-1,
this.imageRect.width+1, this.imageRect.height+1, 2, 2);
// Select rect
g.setColor(Color.BLACK);
g.drawRect(this.clippingZoneRect.x, this.clippingZoneRect.y,
this.clippingZoneRect.width, this.clippingZoneRect.height);
}
/**
* Draw an overlay over the parts of the images which are not in the clip zone
* Draw an overlay over the parts of the images
* which are not in the crop zone
*
* @param g the Graphics used to draw
*/
@ -176,67 +211,116 @@ private void drawImageOverlay(Graphics g)
{
int width, height;
g.setColor(ImageClipper.IMAGE_OVERLAY_COLOR);
width = this.clippingZoneRect.x - this.imageRect.x;
g.setColor(IMAGE_OVERLAY_COLOR);
// left vertical non cropped part
width = this.cropZoneRect.x - this.imageRect.x;
if (width > 0)
{
g.fillRect(this.imageRect.x, this.imageRect.y,
width, this.imageRect.height);
}
// right vertical non cropped
width = this.imageRect.x + this.imageRect.width
- this.clippingZoneBottomRight.x;
- (this.cropZoneRect.x + this.cropZoneRect.width);
if (width > 0)
g.fillRect(this.clippingZoneBottomRight.x, this.imageRect.y,
width, this.imageRect.height);
// Top
height = this.clippingZoneRect.y - this.imageRect.y;
{
g.fillRect(
this.cropZoneRect.x + this.cropZoneRect.width,
this.imageRect.y,
width,
this.imageRect.height);
}
// Top horizontal non croppped part
height = this.cropZoneRect.y - this.imageRect.y;
if (height > 0)
g.fillRect(this.clippingZoneRect.x, this.imageRect.y,
this.clippingZoneRect.width, height);
// Bottom
{
g.fillRect(this.cropZoneRect.x, this.imageRect.y,
this.cropZoneRect.width, height);
}
// Bottom horizontal non croppped part
height = (this.imageRect.y + this.imageRect.height)
- (this.clippingZoneBottomRight.y);
- (this.cropZoneRect.y + this.cropZoneRect.height);
if (height > 0)
g.fillRect(this.clippingZoneRect.x, this.clippingZoneBottomRight.y,
this.clippingZoneRect.width, height);
{
g.fillRect(
this.cropZoneRect.x,
this.cropZoneRect.y + this.cropZoneRect.height,
this.cropZoneRect.width,
height);
}
}
/**
* Start image cropping action.
* @param e the mouse event, initial clicking.
*/
public void mousePressed(MouseEvent e)
{
// Init the dragging
mouseStartX = e.getX();
mouseStartY = e.getY();
xInit = this.imageRect.x;
yInit = this.imageRect.y;
}
/**
* Event that user is dragging the mouse.
* @param e the mouse event.
*/
public void mouseDragged(MouseEvent e)
{
// New position of the image
int xpos = xInit + (e.getX() - mouseStartX);
int ypos = yInit + (e.getY() - mouseStartY);
// Checks if the image doesn't go out of the clip zone
if (xpos <= this.clippingZoneRect.x && xpos
+ this.imageRect.width > this.clippingZoneBottomRight.x)
this.imageRect.x = xpos;
if (ypos <= this.clippingZoneRect.y && ypos
+ this.imageRect.height > this.clippingZoneBottomRight.y)
this.imageRect.y = ypos;
int newXpos = this.imageRect.x + e.getX() - mouseStartX;
int newYpos = this.imageRect.y + e.getY() - mouseStartY;
if(newXpos <= cropZoneRect.x
&& newXpos + imageRect.width
>= cropZoneRect.x + cropZoneRect.width)
{
this.imageRect.x = newXpos;
mouseStartX = e.getX();
}
if(newYpos < cropZoneRect.y
&& newYpos + imageRect.height
>= cropZoneRect.y + cropZoneRect.height)
{
this.imageRect.y = newYpos;
mouseStartY = e.getY();
}
this.repaint();
}
/**
* Not used.
* @param e
*/
public void mouseClicked(MouseEvent e) {}
/**
* Not used.
* @param e
*/
public void mouseEntered(MouseEvent e) {}
/**
* Not used.
* @param e
*/
public void mouseExited(MouseEvent e) {}
/**
* Not used.
* @param e
*/
public void mouseReleased(MouseEvent e) {}
/**
* Not used.
* @param e
*/
public void mouseMoved(MouseEvent e) {}
}

@ -1,3 +1,9 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.presence.avatar.imagepicker;
import java.awt.*;
@ -12,16 +18,22 @@
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
/**
* Dialog in which we can load an image from file or take new one by using
* the webcam. Scaling the image to desired size.
*
* @author Shashank Tyagi
* @author Damien Roth
* @author Damian Minkov
*/
public class ImagePickerDialog
extends SIPCommDialog
implements ActionListener
{
private TransparentPanel fullEditPanel;
private EditPanel editPanel;
private JButton okButton, cancelButton;
private JButton resetButton, selectFileButton, webcamButton;
private JButton selectFileButton, webcamButton;
private boolean editCanceled = false;
@ -35,6 +47,9 @@ public ImagePickerDialog(int clipperZoneWidth, int clipperZoneHeight)
this.setLocationRelativeTo(null);
}
/**
* Initialize the dialog with the already created components.
*/
private void initDialog()
{
this.setTitle(GuiActivator.getResources()
@ -42,32 +57,35 @@ private void initDialog()
this.setModal(true);
this.setResizable(true);
this.setLayout(new BorderLayout());
TransparentPanel editButtonsPanel = new TransparentPanel();
editButtonsPanel.setLayout(new GridLayout(1, 3, 5, 0));
editButtonsPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
editButtonsPanel.add(this.selectFileButton);
editButtonsPanel.add(this.webcamButton);
editButtonsPanel.add(this.resetButton);
this.fullEditPanel = new TransparentPanel();
this.fullEditPanel.setLayout(new BorderLayout());
this.fullEditPanel.add(this.editPanel, BorderLayout.CENTER);
this.fullEditPanel.add(editButtonsPanel, BorderLayout.SOUTH);
TransparentPanel okCancelPanel = new TransparentPanel();
okCancelPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
okCancelPanel.add(cancelButton);
okCancelPanel.add(okButton);
TransparentPanel buttonsPanel = new TransparentPanel();
buttonsPanel.setLayout(new BorderLayout());
buttonsPanel.add(editButtonsPanel, BorderLayout.WEST);
buttonsPanel.add(okCancelPanel, BorderLayout.CENTER);
this.add(fullEditPanel, BorderLayout.CENTER);
this.add(okCancelPanel, BorderLayout.SOUTH);
this.add(this.editPanel, BorderLayout.CENTER);
this.add(buttonsPanel, BorderLayout.SOUTH);
this.pack();
}
/**
* Initialize UI components.
* @param clipperZoneWidth
* @param clipperZoneHeight
*/
private void initComponents(int clipperZoneWidth, int clipperZoneHeight)
{
// Edit panel
@ -84,11 +102,6 @@ private void initComponents(int clipperZoneWidth, int clipperZoneHeight)
this.cancelButton.addActionListener(this);
this.cancelButton.setName("cancelButton");
this.resetButton = new JButton(GuiActivator.getResources()
.getI18NString("service.gui.avatar.imagepicker.RESET"));
this.resetButton.addActionListener(this);
this.resetButton.setName("resetButton");
this.selectFileButton = new JButton(GuiActivator.getResources()
.getI18NString("service.gui.avatar.imagepicker.CHOOSE_FILE"));
this.selectFileButton.addActionListener(this);
@ -100,7 +113,12 @@ private void initComponents(int clipperZoneWidth, int clipperZoneHeight)
this.webcamButton.addActionListener(this);
this.webcamButton.setName("webcamButton");
}
/**
* Shows current dialog and setting initial picture.
* @param image the initial picture to show.
* @return the result: clipped image (from file or webcam).
*/
public byte[] showDialog(Image image)
{
if(image != null)
@ -114,6 +132,10 @@ public byte[] showDialog(Image image)
return this.editPanel.getClippedImage();
}
/**
* Invoked for any button activity.
* @param e
*/
public void actionPerformed(ActionEvent e)
{
String name = ((JButton) e.getSource()).getName();
@ -152,10 +174,6 @@ else if (name.equals("okButton"))
editCanceled = false;
this.setVisible(false);
}
else if (name.equals("resetButton"))
{
this.editPanel.reset();
}
else if (name.equals("webcamButton"))
{
WebcamDialog dialog = new WebcamDialog(this);
@ -169,12 +187,19 @@ else if (name.equals("webcamButton"))
}
}
}
/**
* Closes the dialog.
* @param isEscaped
*/
protected void close(boolean isEscaped)
{
dispose();
}
/**
* The filter for file chooser.
*/
class ImageFileFilter extends SipCommFileFilter
{
public boolean accept(File f)

@ -48,12 +48,14 @@ public class WebcamDialog
*/
public WebcamDialog(ImagePickerDialog parent)
{
super(parent);
super(false);
this.setTitle(GuiActivator.getResources()
.getI18NString("service.gui.avatar.imagepicker.TAKE_PHOTO"));
this.setModal(true);
init();
this.setSize(320, 240);
}
/**
@ -91,7 +93,7 @@ private void init()
}
TransparentPanel buttonsPanel
= new TransparentPanel(new GridLayout(1, 2));
= new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
buttonsPanel.add(this.grabSnapshot);
buttonsPanel.add(cancelButton);
@ -99,9 +101,15 @@ private void init()
TransparentPanel southPanel = new TransparentPanel(new BorderLayout());
southPanel.add(timerPanel, BorderLayout.CENTER);
southPanel.add(buttonsPanel, BorderLayout.SOUTH);
this.add(this.videoContainer, BorderLayout.CENTER);
this.add(southPanel, BorderLayout.SOUTH);
TransparentPanel videoPanel
= new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
videoPanel.add(this.videoContainer);
this.add(videoPanel, BorderLayout.CENTER);
this.add(southPanel, BorderLayout.SOUTH);
this.setResizable(false);
}
/**
@ -170,12 +178,20 @@ private void playSound()
audio.play();
}
/**
* Invoked when a window is closed. Dispose dialog.
* @param isEscaped
*/
protected void close(boolean isEscaped)
{
this.videoContainer = null;
dispose();
}
/**
* Listens for actions for the buttons in this dialog.
* @param e
*/
public void actionPerformed(ActionEvent e)
{
String actName = ((JButton) e.getSource()).getName();
@ -231,11 +247,29 @@ public void run()
private class TimerImage
extends JComponent
{
/**
* Image width.
*/
private static final int WIDTH = 30;
/**
* Image height.
*/
private static final int HEIGHT = 30;
/**
* Whether image is already elapsed.
*/
private boolean isElapsed = false;
/**
* Font of the image.
*/
private Font textFont = null;
/**
* The string that will be shown in the image.
*/
private String second;
public TimerImage(String second)
@ -248,13 +282,20 @@ public TimerImage(String second)
this.textFont = new Font("Sans", Font.BOLD, 20);
this.second = second;
}
/**
* Is current image elapsed.
*/
public void setElapsed()
{
this.isElapsed = true;
this.repaint();
}
/**
* Paint the number image.
* @param g
*/
@Override
protected void paintComponent(Graphics g)
{

Loading…
Cancel
Save