I need to get the id3 tags of tracks that are located on the user's computer.
var song_sound:Sound;
function ID3Tag(path:String)
{
song_sound = new Sound();
var _soundURL:URLRequest = new URLRequest(path);
song_sound.load(_soundURL);
song_sound.addEventListener(Event.ID3, readID3);
}
function readID3(event:Event):void
{
trace(song_sound.id3.artist+" "+song_sound.id3.album);
}
function directorySelected(directory:File):void
{
//var count:int = 0;
if (directory.isDirectory)
{
var files:Array = directory.getDirectoryListing();
for (var i:int = 0; i < files.length; i++)
{
if (files[i].isDirectory)
{
directorySelected( files[i] );
}
else
{
ID3Tag(files[i].nativePath);// DOES NOT WORK
}
}
}
}
After starting I get an error:
Error #2044: Unhandled IOErrorEvent:. text=Error #2032: Stream Error.
at P_1_fla::MainTimeline/ID3Tag()[P_1_fla.MainTimeline::frame1:29]
at P_1_fla::MainTimeline/directorySelected()[P_1_fla.MainTimeline::frame1:54]
at P_1_fla::MainTimeline/directorySelected()[P_1_fla.MainTimeline::frame1:50]
at Function/<anonymous>()[P_1_fla.MainTimeline::frame1:22]
But if you call the function like this:
ID3Tag("D:\\Music\\2013 Killswitch Engage - Disarm The Descent (Special Edition)\\01 The Hell In me.mp3");
then it works.
What's the problem?
Related
I have a script which copy ads, keywords, negativeKeywords, sitelinks, callouts, shippets from master account to slave account
Everything works properly. But when I create keywords in slave account I receive errors
[CONCURRENT_MODIFICATION : DatabaseError.CONCURRENT_MODIFICATION : ]
Most weird that from 10 execution of script 5 can be executed without any error but 5 with error
function copyKeywords(slaveGroup, masterKeywordsData, replicationSettings) {
var count = Object.keys(masterKeywordsData).length;
l('Copying %s keywords...', count);
for (var i = 0; i < count; i++) {
var key = Object.keys(masterKeywordsData)[i];
var masterKeywordData = masterKeywordsData[key];
log('%s/%s - Replicating keyword %s...', (parseInt(i) + 1), count, masterKeywordData.id);
log('Keyword data: %s', JSON.stringify(masterKeywordData));
var slaveKeyword = null;
var finalUrl = null;
if(masterKeywordData.finalUrl) {
finalUrl = formateUrl(masterKeywordData.finalUrl, replicationSettings);
}
slaveKeyword = slaveGroup
.newKeywordBuilder()
.withText(masterKeywordData.text);
if(finalUrl) {
slaveKeyword = slaveKeyword
.withFinalUrl(finalUrl);
}
slaveKeyword = slaveKeyword
.build();
if (slaveKeyword == null) {
log('Nothing was replicated');
} else {
if (slaveKeyword.isSuccessful()) {
log('Keyword %s successfuly replicated', masterKeywordData.id);
} else {
log(slaveKeyword.getErrors());
error('Cannot replicate keyword %s ', masterKeywordData.id);
}
}
sleep(2000);
}
}
With 2000 milliseconds sleep I receive errors not so often. But sometimes it happens(
Does anybody know why I receive error about
[CONCURRENT_MODIFICATION : DatabaseError.CONCURRENT_MODIFICATION : ]
cause I do not make any modification
I'm currently following a tutorial, and I watched it like 6-7 times over, but for some reason I keep getting:
TypeError: Error#1034: type Coercion failed.
I'm trying to make a matching game for a school assignment, and I currently have this:
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.events.MouseEvent;
public class MatchingGame extends MovieClip {
var fClip:Logo
var sClip:Logo
var myTimer:Timer
var frames:Array = new Array(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10);
public function MatchingGame() {
// Constructor code
for(var i:Number=1; i<=5; i++) {
for(var j:Number=1; j<=4; j++) {
var myLogo:Logo = new Logo();
var index = Math.floor(Math.random() * frames.length)
myLogo.frameNo = frames[index];
frames.splice(index, 1);
addChild(myLogo);
myLogo.x = j*100;
myLogo.y = i*100;
myLogo.gotoAndStop(11);
myLogo.addEventListener(MouseEvent.CLICK, openLogo);
}
}
}
private function openLogo(e:MouseEvent) {
var clickObj:Logo = Logo(e.target);
if(fClip == null) {
fClip = clickObj;
fClip.gotoAndStop(fClip.frameNo);
}
else if(sClip == null && fClip != clickObj) {
sClip = clickObj;
sClip.gotoAndStop(sClip.frameNo);
if(fClip.frameNo == sClip.frameNo) {
myTimer = new Timer(1000, 1);
myTimer.start();
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, removeLogos);
}
else {
myTimer = new Timer(1000, 1);
myTimer.start();
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, resetLogos);
}
}
}
private function removeLogos(e:TimerEvent) {
removeChild(fClip);
removeChild(sClip);
myTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, removeLogos);
fClip = null;
sClip = null;
}
private function resetLogos(e:TimerEvent) {
fClip.gotoAndStop(11);
sClip.gotoAndStop(11);
myTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, resetLogos);
fClip = null;
sClip = null;
}
}
}
The error pops up at line 38 and when I try debugging it tell me that clickObj is undefined.
How can I fix this problem?
This is the entire error message:
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::MovieClip#a3e4a61 to Logo.
at MatchingGame/openLogo()[H:\Informatica\Matching game\MatchingGame.as:39]
It looks like the cast from MovieClip to Logo isn't working.
put a trace before that line to see what event.target is.
Depending on the display list structure and event bubbling, you might be getting a different element that what you expect.
Try var clickObj:Logo = Logo(e.currentTarget); as a quick test.
Be sure to go through Trevor McCauley's article to get a better understanding of event bubbling.
i'm trying to intercept datetime value in kendo datasource to adjust UTC time offset but i can't find the e.response.Data property
code
var interceptDate = []; // List of intercept member
var onRequestEnd = function (e) {
setIntercept(e); // another function to fill interceptDate from schema
if (e.response.Data && e.response.Data.length) {
var rowsData = e.response.Data;
if (interceptDate.length > 0) {
if (this.group().length && e.type == "read") {
for (var i = 0; i < rowsData.length; i++) {
var gr = rowsData[i];
for (var j = 0; j < interceptDate.length; j++) {
if (gr.Member == interceptDate[j]) {
gr.Key = gr.Key.replace(/\d+/,
function (n) { return parseInt(n) + offsetMiliseconds; }
);
}
addOffset(gr.Items);
}
}
} else {
addOffset(rowsData);
}
}
}
};
in chrome devtools the e.response look like
_defaultPrevented: false
isDefaultPrevented: function (){return this._defaultPrevented===!0}
preventDefault: function (){this._defaultPrevented=!0}
response: Object
odata.count: "4"
odata.metadata: "http://localhost:7000/odata/$metadata#DateIntercept"
value: Array[4]
0: Object
1: Object
2: Object
3: Object
length: 4
__proto__: Array[0]
__proto__: Object
sender: lt.extend.init
type: "read"
__proto__: Object
If you want to modify the returned data, you should use the parse callback in the dataSource's schema. Leaving out irrelevant stuff it would look something like:
new kendo.ui.Grid({
dataSource: new kendo.data.DataSource({
schema: {
parse: function (results) {
for (var i = 0; i < results.length; i++) {
// MODIFY RESULTS HERE. FOR EXAMPLE
results[i].someField = results[i].someField + " Hello World";
}
return results;
}
}
});
});
From the API page, I gather there's no function for what I'm trying to do. I want to read text from a file storing it as a list of strings, manipulate the text, and save the file. The first part is easy using the function:
abstract List<String> readAsLinesSync([Encoding encoding = Encoding.UTF_8])
However, there is no function that let's me write the contents of the list directly to the file e.g.
abstract void writeAsLinesSync(List<String> contents, [Encoding encoding = Encoding.UTF_8, FileMode mode = FileMode.WRITE])
Instead, I've been using:
abstract void writeAsStringSync(String contents, [Encoding encoding = Encoding.UTF_8, FileMode mode = FileMode.WRITE])
by reducing the list to a single string. I'm sure I could also use a for loop and feed to a stream line by line. I was wondering two things:
Is there a way to just hand the file a list of strings for writing?
Why is there a readAsLinesSync but no writeAsLinesSync? Is this an oversight or a design decision?
Thanks
I just made my own export class that handles writes to a file or for sending the data to a websocket.
Usage:
exportToWeb(mapOrList, 'local', 8080);
exportToFile(mapOrList, 'local/data/data.txt');
Class:
//Save data to a file.
void exportToFile(var data, String filename) =>
new _Export(data).toFile(filename);
//Send data to a websocket.
void exportToWeb(var data, String host, int port) =>
new _Export(data).toWeb(host, port);
class _Export {
HashMap mapData;
List listData;
bool isMap = false;
bool isComplex = false;
_Export(var data) {
// Check is input is List of Map data structure.
if (data.runtimeType == HashMap) {
isMap = true;
mapData = data;
} else if (data.runtimeType == List) {
listData = data;
if (data.every((element) => element is Complex)) {
isComplex = true;
}
} else {
throw new ArgumentError("input data is not valid.");
}
}
// Save to a file using an IOSink. Handles Map, List and List<Complex>.
void toFile(String filename) {
List<String> tokens = filename.split(new RegExp(r'\.(?=[^.]+$)'));
if (tokens.length == 1) tokens.add('txt');
if (isMap) {
mapData.forEach((k, v) {
File fileHandle = new File('${tokens[0]}_k$k.${tokens[1]}');
IOSink dataFile = fileHandle.openWrite();
for (var i = 0; i < mapData[k].length; i++) {
dataFile.write('${mapData[k][i].real}\t'
'${mapData[k][i].imag}\n');
}
dataFile.close();
});
} else {
File fileHandle = new File('${tokens[0]}_data.${tokens[1]}');
IOSink dataFile = fileHandle.openWrite();
if (isComplex) {
for (var i = 0; i < listData.length; i++) {
listData[i] = listData[i].cround2;
dataFile.write("${listData[i].real}\t${listData[i].imag}\n");
}
} else {
for (var i = 0; i < listData.length; i++) {
dataFile.write('${listData[i]}\n');
}
}
dataFile.close();
}
}
// Set up a websocket to send data to a client.
void toWeb(String host, int port) {
//connect with ws://localhost:8080/ws
//for echo - http://www.websocket.org/echo.html
if (host == 'local') host = '127.0.0.1';
HttpServer.bind(host, port).then((server) {
server.transform(new WebSocketTransformer()).listen((WebSocket webSocket) {
webSocket.listen((message) {
var msg = json.parse(message);
print("Received the following message: \n"
"${msg["request"]}\n${msg["date"]}");
if (isMap) {
webSocket.send(json.stringify(mapData));
} else {
if (isComplex) {
List real = new List(listData.length);
List imag = new List(listData.length);
for (var i = 0; i < listData.length; i++) {
listData[i] = listData[i].cround2;
real[i] = listData[i].real;
imag[i] = listData[i].imag;
}
webSocket.send(json.stringify({"real": real, "imag": imag}));
} else {
webSocket.send(json.stringify({"real": listData, "imag": null}));
}
}
},
onDone: () {
print('Connection closed by client: Status - ${webSocket.closeCode}'
' : Reason - ${webSocket.closeReason}');
server.close();
});
});
});
}
}
I asked Mads Agers about this. He works on the io module. He said that he decided not to add writeAsLines because he didn't find it useful. For one it is trivial to write the for loop and the other thing is that you have to parameterize it which the kind of line separator that you want to use. He said he can add it if there is a strong feeling that it would be valuable. He didn't immediately see a lot of value in it.
I'm using code for the open source MP3 player Howler and trying to port it to a Spark MobileApplication type. I'm getting a null pointer exception and I have no idea what's causing it. I've tried debugging extensively with breakpoints at what I think is causing the error, and set breakpoints in the untouched Howler project but all the variables in scope seem to be identical between my non-working project, and the Howler project. The only thing I can think of is that Howler uses MX components and I am using spark. I've pasted all my code below (which is very long) but I've bolded the lines that are throwing the error. The error occurs immediately after I choose a folder in the browse folder dialog.
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Home"
xmlns:Comp="components.*" xmlns:display="flash.display.*">
<s:Button id="browse" x="546" y="43" label="Open Directory" click="browseForFolder()"/>
<s:DataGrid id="dgPlaylist" width="82" height="141" itemRenderer="components.DurationFormatter">
</s:DataGrid>
<s:Button id="btnForward" x="187" y="126" label="Forward"/>
<s:Button id="btnPause" x="90" y="39" label="Pause"/>
<s:Button id="btnBack" x="55" y="166" label="Back" click="changeSoundIndex(-1)"/>
<s:Button id="btnPlay" x="336" y="199" label="Button"/>
<s:Button id="btnStop" x="366" y="89" label="Stop"/>
<s:VScrollBar id="sldrPosition" x="280" y="43" mouseDown="thumbTimer.stop()"
mouseUp="thumbTimer.start()"
/>
<s:VScrollBar id="sldrVolume" x="265" y="234" change="ChangeSoundTransform()"
/>
<s:RichText id="txtID3" x="236" y="41" width="99">
</s:RichText>
<fx:Declarations>
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.ericcarlisle.PlayList;
import com.ericcarlisle.PlayModes;
import com.ericcarlisle.Utility;
import flash.desktop.NativeDragManager;
import flash.media.Sound;
import mx.core.UIComponent;
import mx.events.CloseEvent;
import mx.events.DragEvent;
import org.osmf.traits.PlayTrait;
import spark.components.DataGrid;
// Player properties
private var playMode:String = "STOP";
private var volume:uint;
private const panning:int = 0;
private var selectedFileCount:uint;
private var loadedFileCount:uint;
private var soundIndex:uint;
// Player objects
private var SoundObj:Sound;
private var Channel:SoundChannel;
private var Transform:SoundTransform;
private var thumbTimer:Timer;
private var PlayList:com.ericcarlisle.PlayList;
private var SoundFilter:FileFilter = new FileFilter("Sounds", "*.mp3;*.wav");
//private var PlaylistFilter:FileFilter = new FileFilter("Sounds", "*.pls;*.m3u");
// Visualization objects.
private var Spectrum:ByteArray;
private const VISUALIZER_HEIGHT:Number = 50;
private const VISUALIZER_COLOR:Number = 0x336699;
// ID3 and other metadata
private var ID3:ID3Info;
private var Duration:int;
/*---------- PLAYER INITIALIZER ----------*/
// Initialization function used to add event handlers and set initial settings.
private function init():void
{
// Set player initial settings.
playMode = PlayModes.STOP;
selectedFileCount = 0;
loadedFileCount = 0;
soundIndex = 0;
// Set initial application height.
//this.height= cvsControlBar.height + cvsPlayer.height;
// Set volume.
volume = sldrVolume.value;
// Instantiate sound objects.
Channel = new SoundChannel();
Transform = new SoundTransform(volume/100, panning);
PlayList = new com.ericcarlisle.PlayList();
// Bind playlist data to datagrid.
dgPlaylist.dataProvider = PlayList.Sounds;
// Create a timer to control the song position hslider.
thumbTimer = new Timer(500);
thumbTimer.addEventListener(TimerEvent.TIMER, onTimerTick);
// Create event handlers for application.
this.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onPlayerDragInto);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onPlayerDropInto);
this.addEventListener(InvokeEvent.INVOKE, onInvoke);
}
/*---------- DRAG/DROP & FILE MANAGEMENT ----------*/
private function onInvoke(event:InvokeEvent):void
{
if (event.arguments.length > 0)
{
var file:File;
var files:Array = new Array();
for (var i:int = 0; i < event.arguments.length; i++)
{
file = new File(event.arguments[i]);
files.push(file);
}
if (PlayList.Sounds.length > 0) removeAllSounds();
loadFiles(files);
}
}
// Handles file selection event dispatched by browse dialog.
private function onFileSelect(event:FileListEvent):void
{
loadFiles(event.files);
}
// Handles folder selection event dispatched by browse dialog.
private function onDirectorySelect(event:Event):void
{
var directory:File = event.target as File;
**loadFiles(directory.getDirectoryListing());**
}
// Loads a batch of files into the playlist.
private function loadFiles(files:Array):void
{
var file:File;
// Count the number of files selected. Only accept files with .mp3 extension.
selectedFileCount = 0;
for (var i:uint = 0; i < files.length; i++)
{
file = files[i];
if (file.extension == "mp3") selectedFileCount++;
}
// Reset the count on files currently loaded.
loadedFileCount = 0;
**// Set the player mode so that loaded files are played automatically.
if (PlayList.Sounds.length == 0) playMode = PlayModes.LOADTOPLAY;**
// Load files as sound objects.
for(var j:uint = 0; j < files.length; j++)
{
file = files[j];
if (file.extension == "mp3" || file.extension == "wav")
{
var sound:Sound = new Sound(new URLRequest(file.url));
sound.addEventListener(Event.ID3,onID3);
}
}
}
// Presents file browse (multiple file) dialog.
private function browseForFiles():void
{
var SoundFile:File = new File();
SoundFile.browseForOpenMultiple("Open", [SoundFilter]);//, PlaylistFilter]);
SoundFile.addEventListener(FileListEvent.SELECT_MULTIPLE, onFileSelect);
}
// Presents file browse (folder) dialog.
private function browseForFolder():void
{
var directory:File = File.documentsDirectory;
directory.browseForDirectory("Select Directory");
directory.addEventListener(Event.SELECT, onDirectorySelect);
}
// Accept files dragged into player.
private function onPlayerDragInto(event:Event):void
{
NativeDragManager.acceptDragDrop(this);
}
// Manages files dropped into player.
private function onPlayerDropInto(event:NativeDragEvent):void
{
// Accept only files.
if (event.clipboard.hasFormat(ClipboardFormats.FILE_LIST_FORMAT))
{
// Parse dragged contents into array of files.
var dragFiles:Array = event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
// Load the files.
loadFiles(dragFiles);
}
}
/*---------- SOUND MANAGEMENT ----------*/
private function loadSound():void
{
SoundObj = new Sound();
SoundObj.load(new URLRequest(PlayList.Sounds[soundIndex]["url"]));
SoundObj.addEventListener(Event.COMPLETE, onSoundLoaded);
}
private function onSoundLoaded(event:Event):void
{
// Retrieve data for current sound from playlist.
var soundData:Object = PlayList.Sounds[soundIndex];
// Place ID3 information into the readout panel.
//txtID3.htmlText = Utility.ReadoutHTML(soundData["title"], soundData["track"], soundData["album"], soundData["artist"], soundData["year"], soundData["duration"]);
// Configure the holizontal slider to act as a playhead.
sldrPosition.maximum = soundData["duration"];
// Set the selected row in the playlist display.
dgPlaylist.selectedIndex = soundIndex;
// Start the player if the mode is correct.
if (playMode == PlayModes.LOADTOPLAY)
{
playSound();
}
else
{
playMode = PlayModes.LOADED;
}
}
// Plays the current sound.
public function playSound():void
{
// Load sound into channel.
Channel.stop();
Channel = SoundObj.play(sldrPosition.value,0,Transform);
playMode = PlayModes.PLAY;
// Start position timer.
thumbTimer.start();
// Configure UI controls.
btnPlay.visible = false;
btnPause.visible = true;
sldrPosition.enabled = true;
btnPlay.enabled = true;
btnStop.enabled = true;
setBackForwardButtons();
Channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
}
private function setBackForwardButtons():void
{
if (soundIndex == PlayList.Sounds.length-1 || PlayList.Sounds.length == 0)
{
btnForward.enabled = false;
}
else
{
btnForward.enabled = true;
}
if (soundIndex == 0 || PlayList.Sounds.length == 0)
{
btnBack.enabled = false;
}
else
{
btnBack.enabled = true;
}
}
// Stops the current sound.
public function stopSound():void
{
Channel.stop();
thumbTimer.stop();
sldrPosition.value = 0;
playMode = PlayModes.STOP;
//Visualizer.graphics.clear();
btnPlay.visible = true;
btnPause.visible = false;
}
// Pause a playing sound.
private function pauseSound():void
{
Channel.stop();
thumbTimer.stop();
btnPlay.visible = true;
btnPause.visible = false;
}
// Change the sound index
private function changeSoundIndex(delta:int):void
{
stopSound();
playMode = PlayModes.LOADTOPLAY;
soundIndex = soundIndex + delta;
loadSound();
}
// Change the volume and panning via the sound transform object.
private function ChangeSoundTransform():void
{
volume = Math.round(sldrVolume.value);
Channel.soundTransform = new SoundTransform(volume/100, panning);
}
// Handles event for sound completing.
private function onSoundComplete(event:Event):void
{
stopSound();
soundIndex++;
if (soundIndex < PlayList.Sounds.length)
{
playMode = PlayModes.LOADTOPLAY;
loadSound();
}
}
// Load ID3 information into local variables.
// Update the readout panel.
// Configure position slider.
private function onID3(event:Event):void
{
var sound:Sound = Sound(event.target);
ID3 = ID3Info(sound.id3);
Duration = Math.floor(sound.length);
// Load sound id3 data into the playlist.
PlayList.AddSound(ID3.songName, ID3.album, ID3.artist, ID3.track, ID3.year, ID3.genre, Duration, sound.url);
// Increment the loaded file count.
loadedFileCount++;
if (loadedFileCount == selectedFileCount * 2)
{
// Refresh the playlist so that new results will be visually displayed.
PlayList.Sounds.refresh();
// Set the count properties.
selectedFileCount = 0;
loadedFileCount = 0;
soundIndex = 0;
if (playMode == PlayModes.LOADTOPLAY) loadSound();
}
}
/*---------- VISUALIZATION ----------*/
private function UpdateVisualizer():void
{
// Instantiate a new byte array to contain spectrum data.
Spectrum = new ByteArray();
// Clear the visualizer graphics.
//Visualizer.graphics.clear();
// Dump the spectrum data into the byte array.
SoundMixer.computeSpectrum(Spectrum,false,0);
var f:Number;
var i:int;
var ave:int;
//Visualizer.graphics.lineStyle(1, VISUALIZER_COLOR,1);
//Visualizer.graphics.beginFill(VISUALIZER_COLOR, 0.75);
for (i = 0; i < 512; i=i+10)
{
f = Spectrum.readFloat();
//Visualizer.drawRoundRect(Math.floor(i*0.7) + 7, cvsReadout.height - 10, 4, -Math.abs(f) * (cvsReadout.height-10));
}
//Visualizer.graphics.endFill();
}
// Updates the position of the hslider thumb.
private function onTimerTick(event:TimerEvent):void
{
sldrPosition.value = Math.round(Channel.position);
}
// Update the wave visualizer if the sound is playing.
private function onEnterFrame(event:Event):void
{
if (playMode == PlayModes.PLAY)
{
UpdateVisualizer();
}
}
// Show application information.
private function showHowlerInfo():void
{
//cvsAbout.visible = true;
}
private function togglePlayList():void
{
}
private function onItemDoubleClick(event:Event):void
{
this.playMode = PlayModes.LOADTOPLAY;
thumbTimer.stop();
sldrPosition.value = 0;
loadSound();
}
/*---------- ERROR HANDLING ----------*/
// Handles IO errors.
private function onIOError(event:IOErrorEvent):void
{
//Alert.show("File load error: " + event.text);
}
private function startMove():void
{
stage.nativeWindow.startMove();
}
private function unloadSound():void
{
stopSound();
txtID3.text = "";
btnPlay.visible = true;
btnPause.visible = false;
btnPlay.enabled = false;
btnStop.enabled = false;
}
private function removeSound():void
{
var index:int = dgPlaylist.selectedIndex;
if (index >= 0)
{
if (index == soundIndex)
{
unloadSound();
}
PlayList.RemoveSoundAt(index);
PlayList.Sounds.refresh();
setBackForwardButtons();
}
}
private function removeAllSounds():void
{
unloadSound();
PlayList.Sounds.removeAll();
PlayList.Sounds.refresh();
setBackForwardButtons();
}
private function onKeyDown(event:KeyboardEvent):void
{
if (event.charCode.toString() == "8" || event.charCode.toString() == "127")
{
removeSound();
}
}
]]>
</fx:Script>
</s:View>
I'm new to Flex so I don't know if this is causing the problem or not, but the Howler app uses an MX:DataGrid defined like this:
<mx:DataGrid x="6"
y="7"
width="388"
height="310"
id="dgPlaylist"
keyDown="onKeyDown(event)"
dragMoveEnabled="true"
doubleClickEnabled="true"
dragEnabled="true"
dropEnabled="true"
dragComplete="onPlaylistDragDrop(event)"
itemDoubleClick="onItemDoubleClick(event)">
<mx:columns>
<mx:DataGridColumn width="168" headerText="Title" dataField="title" />
<mx:DataGridColumn width="160" headerText="Album" dataField="album"/>
<mx:DataGridColumn width="60" headerText="Duration" dataField="duration" textAlign="right" itemRenderer="components.DurationFormatter"/>
</mx:columns>
</mx:DataGrid>
It has additional columns that I'm not using. Could this be the cause?
We are going to need the error message. Generally what you are experiencing is called a null pointer exception ( just like the error said ). Which basically means you tried to access a property of an object that is null. For example, running the following code will cause the same problem
var arrayCollection:ArrayCollection;
arrayCollection.addItem( new Object() );
To fix your error, you should find the object that the error is referring to in your code and make sure it isn't null when your program executes whatever line it is complaining about, or add an if-loop in the event it is null.