?? player.java
字號:
/*******************************************************************************
* Copyright (c) 2004 Berthold Daum. All rights reserved. This program and the
* accompanying materials are made available under the terms of the Common
* Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors: Berthold Daum
******************************************************************************/
package com.bdaum.jukebox;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javazoom.jlGui.BasicPlayer;
import javazoom.jlGui.BasicPlayerListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.*;
/**
* Player module. This module demonstrates the various techniques of the SWT, in
* particular the coordination between SWT thread and other threads.
*/
public class Player implements BasicPlayerListener {
// Operation states
private static final int PLAY = 1;
private static final int PAUSE = 2;
private static final int STOP = 3;
private static final int EOM = 4;
// Text representation of operation state
private static final String PLAYING = "Playing";
private static final String PAUSED = "Paused";
private static final String IDLE = "Idle";
// Features in the playlist data model
public final static String TITLE = "title";
public final static String SOUNDFILE = "soundfile";
public final static String IMAGEFILE = "image";
public final static String DESCRIPTION = "description";
/* Data model of the player model */
// Current operation state
private int state = STOP;
// The player engine
private BasicPlayer soundPlayer;
// The playlist's data model
private IPlaylist playlistModel;
// Duration of current tune
private double lengthInSec = 0;
// Current position
private int currentPosition = 0;
// Maximum position
private int maxPosition = 0;
// Text representation of current operation state
private String mediaState = "Stopped";
// Current background image
private String currentImage;
// Title of current tune
private String currentTitle = "";
/** * GUI elements ** */
/* Widgets of player windows */
// Player shell
private Shell toplevelShell;
// Outline of shell
private static final int[] OUTLINE = new int[] { 5, 0, 355, 0, 360, 5, 360,
20, 330, 295, 325, 300, 15, 290, 10, 285, 0, 5 };
// The hole in the shell
private static final int[] HOLLOW = new int[] { 13, 10, 247, 10, 250, 13,
255, 27, 252, 30, 13, 30, 10, 27, 10, 13 };
// Current Display instance
private Display display;
// Canvas for background image
private Canvas canvas;
// Taste zum Schlie遝n der Shell
private Button closeButton;
// Status Panel
private Composite statusPanel;
private Label statusLabel, lengthLabel;
// Toolbar with buttons
private ToolBar toolbar;
private ToolItem backButton, playButton, pauseButton, stopButton,
forwardButton, playlistButton, descriptionButton;
// Scale
private Scale scale;
// Additional windows
private DescriptionWindow descriptionWindow;
private PlaylistWindow playlistWindow;
/**
* main method for starting the player
*
* @param args
* unused
*/
public static void main(String args[]) {
Player player = new Player();
player.run();
}
/**
* Initialize Player
*/
private void run() {
// Create Playlist domain model
playlistModel = new PlaylistModel();
// Create Display instance
display = new Display();
// Create top level shell with the usual controls
toplevelShell = new Shell(display, SWT.NO_TRIM);
// Set title (appears in tasks bar)
toplevelShell.setText("Jukebox");
// Hintergrundfarbe setzen
Color bgColor = new Color(display, 160, 160, 255);
toplevelShell.setBackground(bgColor);
// Create region for the player shell outline
Region region = new Region();
region.add(OUTLINE);
region.subtract(HOLLOW);
// Apply region to shell
toplevelShell.setRegion(region);
// Retrieve size of region
Rectangle size = region.getBounds();
// Position shell on the primary monitor
Monitor mon1 = display.getPrimaryMonitor();
Rectangle r = mon1.getClientArea();
toplevelShell.setBounds(r.x + 20, r.y + 20, size.width, size.height);
// Since the shell does not have a trim
// we must handle the repositioning of the window ourselves
Listener listener = new Listener() {
Point origin;
public void handleEvent(Event e) {
switch (e.type) {
case SWT.MouseDown:
// Remember mouse position
origin = new Point(e.x, e.y);
break;
case SWT.MouseUp:
// Indicate operation stopped
origin = null;
break;
case SWT.MouseMove:
if (origin != null) {
// Shift shell by difference to origin
Point p = display.map(toplevelShell, null, e.x, e.y);
toplevelShell.setLocation(p.x - origin.x, p.y
- origin.y);
}
break;
}
}
};
toplevelShell.addListener(SWT.MouseDown, listener);
toplevelShell.addListener(SWT.MouseUp, listener);
toplevelShell.addListener(SWT.MouseMove, listener);
// Create rest of Player GUI
constructPlayer(toplevelShell);
// Create the jlGui-engine
soundPlayer = new BasicPlayer(this);
// Display shell
toplevelShell.open();
// Event loop
while (!toplevelShell.isDisposed()) {
// Check for waiting events
if (!display.readAndDispatch())
display.sleep();
}
// If necessary stop playing
stop();
// Force session exit -
// otherwise the Java audio system would remain active
System.exit(0);
}
/**
* Retrieves the playlist
*
* @return IPlaylist - the playlist model
*/
public IPlaylist getPlaylist() {
return playlistModel;
}
/** * GUI erzeugen ** */
/**
* Constructs the Player-GUI.
*
* @param parent
* containing Composite
*/
private void constructPlayer(Composite parent) {
// We use a GridLayout for the containing Composite
GridLayout gridLayout = new GridLayout();
gridLayout.marginHeight = 0;
parent.setLayout(gridLayout);
// Composite for CloseButton and StatusPanel
Composite comp = new Composite(parent, SWT.NONE);
gridLayout = new GridLayout(2, false);
gridLayout.marginWidth = 10;
comp.setLayout(gridLayout);
comp.setBackground(parent.getBackground());
// Layoutdaten for Composite
GridData data = new GridData();
data.horizontalAlignment = GridData.END;
data.verticalAlignment = GridData.BEGINNING;
data.grabExcessHorizontalSpace = true;
comp.setLayoutData(data);
// Create status panel
createStatusPanel(comp);
// Create button for closing the window
createCloseButton(comp);
// Create canvas
canvas = new Canvas(parent, SWT.NONE);
// Set preferred canvas size
data = new GridData();
data.widthHint = 355;
data.heightHint = 235;
canvas.setLayoutData(data);
// The Canvas instance acts as a Composite, too.
// So we apply a GridLayout to it, too.
gridLayout = new GridLayout();
gridLayout.marginHeight = 2;
gridLayout.verticalSpacing = 0;
canvas.setLayout(gridLayout);
// Construct Toolbar
createToolbar(canvas);
// Construct scale
createScale(canvas);
// Add PaintListener to Canvas to support drawing
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
paintCanvas(e.gc);
}
});
// Add MouseTrackListener to Canvas
canvas.addMouseTrackListener(new MouseTrackAdapter() {
public void mouseEnter(MouseEvent e) {
setCanvasControlsVisible(true);
}
public void mouseExit(MouseEvent e) {
Rectangle rect = canvas.getClientArea();
// Check if mouse has really left the canvas area
if (!rect.contains(e.x, e.y))
setCanvasControlsVisible(false);
}
});
setCanvasControlsVisible(false);
}
/**
* Create window close button
*
* @param parent
* the containing Composite
*/
private void createCloseButton(Composite parent) {
closeButton = new Button(parent, SWT.PUSH | SWT.FLAT);
closeButton.setText("x");
closeButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
toplevelShell.close();
}
});
}
/**
* Shows or hides the control elements on top of the canvas.
*
* @param v
* true for showing, false for hiding
*/
private void setCanvasControlsVisible(boolean v) {
toolbar.setVisible(v);
scale.setVisible(v);
}
/** * Graphic Operations ** */
/**
* Draw all graphical elements on the canvas.
*
* @param gc
* The graphics context
*/
private void paintCanvas(GC gc) {
Rectangle area = canvas.getClientArea();
// Check if we have an image file
if (doesFileExist(currentImage)) {
// Scale and draw image
Image image = new Image(display, currentImage);
Rectangle bounds = image.getBounds();
gc.drawImage(image, bounds.x, bounds.y, bounds.width,
bounds.height, area.x, area.y, area.width, area.height);
// Dispose image
image.dispose();
} else {
// Otherwise fill background with gray color
gc.setBackground(toplevelShell.getBackground());
gc.fillRectangle(area);
}
// Draw title of current sound file
if (currentTitle != null && currentTitle.length() > 0) {
gc.setBackground(display.getSystemColor(SWT.COLOR_DARK_GRAY));
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawText(" " + currentTitle + " ", 5, 12, false);
}
}
/**
* Checks if a file with the specified name exists.
*
* @param filename
* File name
* @return boolean - true, if the file exists
*/
private static boolean doesFileExist(String filename) {
return (filename != null && filename.length() > 0 && openFile(filename)
.exists());
}
/**
* Convert file name into File instance
*
* @param file
* File name
* @return File - File instance
*/
private static File openFile(String file) {
return new File(file);
}
/** * Instrument Canvas ** */
/**
* Creates a scale that shows the current position in the sound file.
*
* @param parent
* the containing Composite
*/
private void createScale(Composite parent) {
scale = new Scale(parent, SWT.NONE);
// Set scale size
GridData data = new GridData();
data.horizontalIndent = 18;
data.widthHint = 300;
data.heightHint = 20;
scale.setLayoutData(data);
// Event processing for scale handle movements
scale.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
seek();
}
});
}
/**
* Create toolbar with all buttons
*
* @param parent
* the containing Composite
*/
private void createToolbar(Composite parent) {
// Create Toolbar instance
toolbar = new ToolBar(parent, SWT.NONE);
// Create all buttons
backButton = makeToolItem(toolbar, SWT.PUSH, "<<", "Previous");
playButton = makeToolItem(toolbar, SWT.PUSH, ">", "Play");
pauseButton = makeToolItem(toolbar, SWT.PUSH, "||", "Pause");
stopButton = makeToolItem(toolbar, SWT.PUSH, "[]", "Stop");
forwardButton = makeToolItem(toolbar, SWT.PUSH, ">>", "Next");
makeToolItem(toolbar, SWT.SEPARATOR, null, null);
playlistButton = makeToolItem(toolbar, SWT.CHECK, "PlayList",
"Show Playlist");
descriptionButton = makeToolItem(toolbar, SWT.CHECK, "ShowText",
"Show Description");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -