/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.hadeslee.yoyoplayer.lyric;
import com.hadeslee.yoyoplayer.util.Config;
import com.hadeslee.yoyoplayer.util.Playerable;
import com.hadeslee.yoyoplayer.util.Util;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
/**
*
* @author hadeslee
*/
public class LyricPanel extends JPanel implements Runnable, DropTargetListener,
MouseListener, MouseWheelListener, MouseMotionListener {
private static final long serialVersionUID = 20071214L;
private static Logger log = Logger.getLogger(LyricPanel.class.getName());
private DropTarget dt;//
private Playerable player;//
private Lyric ly;//
public static final int V = 0;//
public static final int H = 1;//
private int state = H;//
private volatile boolean isPress;//,
private volatile boolean isDrag;//
private int start;//,,
private int end;//
private volatile boolean isResized;//
private volatile boolean pause = true;//
private final Object lock = new Object();
private volatile boolean isOver;//
private Rectangle area = new Rectangle();
private final String logo = Config.getResource("LyricPanel.logo");
private boolean isShowLogo = false;
private Config config;//
// private Component parent;//
public LyricPanel(Playerable pl) {
this();
this.player = pl;
this.setDoubleBuffered(true);
}
public LyricPanel() {
config = Config.getConfig();
dt = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
state = config.getLpState();
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addMouseWheelListener(this);
Thread th = new Thread(this);
th.setDaemon(true);
th.start();
}
public void setConfig(Config config) {
this.config = config;
}
public void setShowLogo(boolean b) {
isShowLogo = b;
}
/**
*
* @param pl
*/
public void setPlayList(Playerable pl) {
this.player = pl;
}
/**
* ,
* PlayList
* @param ly
*/
public void setLyric(Lyric ly) {
this.ly = ly;
isResized = false;
}
public void pause() {
log.log(Level.INFO, "");
pause = true;
}
public void start() {
log.log(Level.INFO, "...");
pause = false;
synchronized (lock) {
lock.notifyAll();
}
}
protected void paintComponent(Graphics g) {
Graphics2D gd = (Graphics2D) g;
if (config.isTransparency()) {
} else {
super.paintComponent(g);
gd.setColor(config.getLyricBackground());
gd.fillRect(0, 0, getWidth(), getHeight());
}
if (config.isAntiAliasing()) {
gd.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// gd.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
}
g.setFont(config.getLyricFont());
state = config.getLpState();
if (ly != null) {
//,,,
//
if (config.isAutoResize() && !isResized && ly.isInitDone() && state == V) {
int maxWidth = ly.getMaxWidth(g);
int inset = player.getLyricUI().getInsets().left + player.getLyricUI().getInsets().right;
JDialog win = config.getLrcWindow();
if (win != null) {
win.setSize(maxWidth + inset, win.getHeight());
isResized = true;
}
}
if (isPress && isDrag) {
if (state == H) {
ly.moveH(start - end, g);
} else {
ly.moveV(start - end, g);
}
}
if (state == H) {
ly.drawH(g);
} else {
ly.drawV(g);
}
if (isPress && isDrag) {
if (state == H) {
drawTimeH((int) (ly.getTime() / 1000), g);
} else {
drawTimeV((int) (ly.getTime() / 1000), g);
}
}
} else {
g.setColor(config.getLyricHilight());
int width = Util.getStringWidth(Config.NAME, g);
int height = Util.getStringHeight(Config.NAME, g);
Util.drawString(g, Config.NAME, (getWidth() - width) / 2, (getHeight() - height) / 2);
}
if (isShowLogo) {
drawLogo(g);
}
}
/**
* LOGO
* @param g
*/
private void drawLogo(Graphics g) {
g.setFont(new Font("Dialog", Font.BOLD, 14));
int width = Util.getStringWidth(logo, g);
int height = Util.getStringHeight(logo, g);
area.x = 5;
area.y = 5;
area.width = width;
area.height = height;
if (isOver) {
g.setColor(Color.RED);
} else {
Color bg = config.getLyricBackground();
int rgb = bg.getRGB();
int xor = ~rgb;
rgb = xor & 0x00ffffff;
Color c = new Color(rgb);
g.setColor(c);
}
Util.drawString(g, logo, 5, 5);
}
/**
* ,
*
* @return
*/
public Playerable getPlayer() {
return this.player;
}
/**
* ,
*
* @param sec
* @param g
*/
private void drawTimeV(int sec, Graphics g) {
String s = Util.secondToString(sec);
int width = getWidth();
int height = getHeight();
int centerY = height / 2;
g.drawLine(3, centerY - 5, 3, centerY + 5);
g.drawLine(width - 3, centerY - 5, width - 3, centerY + 5);
g.drawLine(3, centerY, width - 3, centerY);
g.setFont(new Font(Config.getResource("LyricPanel.font"), Font.PLAIN, 14));
g.setColor(Util.getColor(config.getLyricForeground(), config.getLyricHilight()));
Util.drawString(g, s, width - Util.getStringWidth(s, g), (height / 2 - Util.getStringHeight(s, g)));
}
/**
* ,
*
* @param sec
* @param g
*/
private void drawTimeH(int sec, Graphics g) {
String s = Util.secondToString(sec);
int centerX = getWidth() / 2;
int height = getHeight();
g.drawLine(centerX - 5, 3, centerX + 5, 3);
g.drawLine(centerX - 5, height - 3, centerX + 5, height - 3);
g.drawLine(centerX, 3, centerX, height - 3);
g.setFont(new Font(Config.getResource("LyricPanel.font"), Font.PLAIN, 14));
g.setColor(Util.getColor(config.getLyricForeground(), config.getLyricHilight()));
Util.drawString(g, s, centerX, (height - Util.getStringHeight(s, g)));
}
public void run() {
while (true) {
try {
Thread.sleep(config.getRefreshInterval());
if (pause) {
synchronized (lock) {
lock.wait();
}
} else {
if (ly != null) {
ly.setHeight(this.getHeight());
ly.setWidth(this.getWidth());
ly.setTime(player.getTime());
repaint();
}
}
} catch (Exception exe) {
exe.printStackTrace();
}
}
}
public void dragEnter(DropTargetDragEvent dtde) {
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
}
public void dragOver(DropTargetDragEvent dtde) {
}
public void dropActionChanged(DropTargetDragEvent dtde) {
}
public void dragExit(DropTargetEvent dte) {
}
public void drop(DropTargetDropEvent e) {
try {
//windowsDataFlavor.javaFileListFlavor
//linuxDataFlavor.stringFlavor
String os = System.getProperty("os.name");
if (os.startsWith("Windows")) {
if (e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
Transferable tr = e.getTransferable();
e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
@SuppressWarnings("unchecked")
java.util.List<File> s = (java.util.List<File>) tr.getTransferData(
DataFlavor.javaFileListFlavor);
if (s.size() == 1) {
File f = s.get(0);
if (f.isFile() && player.getCurrentItem() != null) {
ly = new Lyric(f, player.getCurrentItem());
ly.setWidth(this.getWidth());
ly.setHeight(this.getHeight());
player.setLyric(ly);
}
}
e.dropComplete(true);
}
} else if (os.startsWith("Linux")) {
if (e.isDataFlavorSupported(DataFlavor.stringFlavor)) {
e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable tr = e.getTransferable();
String[] ss = tr.getTransferData(DataFlavor.stringFlavor).toString().split("\r\n");
if (ss.length == 1) {
File f = new File(new URI(ss[0]));
if (f.isFile() && player.getCurrentItem() != null) {
ly = new Lyric(f, player.getCurrentItem());
ly.setWidth(this.getWidth());
ly.setHeight(this.getHeight());
player.setLyric(ly);
}
}
e.dropComplete(true);
}
} else {
e.rejectDrop();
}
} catch ( Exception io) {
io.printStackTrace();
e.rejectDrop();
}
}
public void setState(int state) {
if (state == H || state == V) {
this.state = state;
}
}
public void setResized(boolean b) {
isResized = b;
}
public void mouseClicked(MouseEvent e) {
// //,
// if (e.getClickCount() == 2) {
// if (state == H) {
// state = V;
// } else {
// state = H;
// }
// }
}
public void mousePressed(MouseEvent e) {
if (ly == null) {
return;
}
if (e.getButton() == MouseEvent.BUTTON1) {
if (area != null && area.contains(e.getPoint())) {
try {
Desktop.getDesktop().browse(new URI("http://www.blogjava.net/hadeslee"));
} catch (URISyntaxException ex) {
Logger.getLogger(LyricPanel.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(LyricPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (ly != null && ly.canMove()) {
isPress = true;
isDrag = false;
if (state == V) {
start = e.getY();
} else {
start = e.getX();
}
ly.startMove();
}
}
}
public void mouseReleased(MouseEvent e) {
if (ly == null) {
return;
}
//
if (e.getButton() == MouseEvent.BUTTON1) {
if (ly.canMove() && isDrag) {
if (state == H) {
end = e.getX();
} else {
end = e.getY();
}
long time = ly.getTime();
player.setTime(time);
start = end = 0;
}
ly.stopMove();
isPress = false;
isDrag = false;
//
} else if (e.getButton() == MouseEvent.BUTTON3) {
if (player.getCurrentItem() == null) {
return;
}
JPopupMenu pop = new JPopupMenu();
Util.generateLyricMenu(pop, this);
pop.show(this, e.getX(), e.getY());
}
}
/**
*
*/
public void hideMe() {
player.setShowLyric(false);
}
public Lyric getLyric() {
return ly;
}
public void mouseEntered(MouseEvent e) {
if (ly != null && ly.canMove()) {
this.setCursor(new Cursor(Cursor.HAND_CURSOR));
} else {
this.setCursor(Cursor.getDefaultCursor());
}
}
public void mouseExited(MouseEvent e) {
this.setCursor(Cursor.getDefaultCursor());
isOver = false;
}
public void mouseWheelMoved(MouseWheelEvent e) {
if (ly == null) {
return;
}
//
if (config.isMouseScrollAjustTime()) {
int adjust = e.getUnitsToScroll() * 100;//,300
ly.adjustTime(adjust);
}
}
public void mouseDragged(MouseEvent e) {
if (ly == null) {
return;
}
if (ly.canMove() && isPress) {
isDrag = true;
if (state == H) {
end = e.getX();
} else {
end = e.getY();
}
}
}
public void mouseMoved(MouseEvent e) {
if (area != null && area.contains(e.getPoint())) {
isOver = true;
this.setCursor(new Cursor(Cursor.HAND_CURSOR));
} else {
isOver = false;
mouseEntered(e);
}
}
}
|