I created a save button and added an eventlistener to run the saveAs() when the button is clicked but I'm getting
Error #1063: Argument count mismatch on views::TxtView/saveAs(). Expected 0, got 1.
I haven't supplied any arguments.
In my init()
...
var saveAsFileBtn:IconButton = new IconButton();
saveAsFileBtn.setIcon("../icons/saveas.png");
saveAsFileBtn.width=100;
saveAsFileBtn.x=saveFileBtn.width+71;
saveAsFileBtn.sizeMode = SizeMode.BOTH;
saveAsFileBtn.sizeUnit = SizeUnit.PIXELS
saveAsFileBtn.addEventListener(MouseEvent.CLICK, saveAs);
...
then
private function saveAs():void
{
trace("Save as");
var fileChooser:File;
if (currentFile)
{
fileChooser = currentFile;
}
else
{
fileChooser = File.documentsDirectory.resolvePath('untitled.html')
}
fileChooser.browseForSave("Save As");
fileChooser.addEventListener(Event.SELECT, saveAsFileSelected);
}
The debugger stops when the Save As button is clicked.
Your method definition is incorrect.
Try : private function saveAs(event:MouseEvent):void
Flex wants the event listener to accept the MouseEvent that caused it to be called. Altering your method definition to the following should fix your problem.
private function saveAs(e:MouseEvent):void
If the method is called from any other context, you can pass a null as the parameter. Alternatively, you could make a small wrapper method that takes the event, and calls saveAs() internally.
saveAsFileBtn.addEventListener(MouseEvent.CLICK, saveAsWrapper);
...
private function saveAsWrapper(e:MouseEvent):void
{
saveAs();
}
Related
I am a beginner in javafx.I have a function button_loop() that is supposed to dynamically generate a specified number of buttons and add an action listener for each button as it is generated.The buttons are then stored in an ArrayList and the ArrayList is then added to a HBox. The buttons are generating fine. However, when I attempt to add an action listener like so:
button.addActionListener(this)
And despite implementing the actionListener interface,I get the following error:
error: cannot find symbol
button.addActionListener(this);
symbol: method addActionListener(dummy_td)
location: variable button of type Button
The code for the function is:
void button_loop() throws SQLException, ClassNotFoundException {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection c = DriverManager.getConnection(connection, user_name, password);
PreparedStatement st = c.prepareStatement("select service_name from services");
ResultSet rs = st.executeQuery();
while (rs.next()) {
String service = rs.getString("service_name");
Button button = new Button(service);
button.addActionListener(this);
buttonlist.add(i,button);
}
hboxx.getChildren().addAll(buttonlist);
}
I've been trying to figure this out for 2 days..please help.
It's either
button.setOnAction(this);
(allows only for a single event handler added this way)
or
button.addEventHandler(ActionEvent.ACTION, this);
// event type ^^^^^^ | ^^^ handler
Note: if you get this error it may be worth checking the JavaDoc, if the member even exists.
I'm currently trying to implement an automated bug reporter for a Flex application, and would like to return error messages to a server along with the function/line number that caused the error. Essentially, I'm trying to get the getStackTrace() information without going into debug mode, because most users of the app aren't likely to have the debug version of flash player.
My current method is using the UncaughtErrorEvent handler to catch errors that occur within the app, but the error message only returns the type of error that has occurred, and not the location (which means it's useless). I have tried implementing getStackTrace() myself using a function name-grabber such as
private function getFunctionName (callee:Function, parent:Object):String {
for each ( var m:XML in describeType(parent)..method) {
if ( this[m.#name] == callee) return m.#name;
}
return "private function!";
}
but that will only work because of arguments.callee, and so won't go through multiple levels of function calls (it would never get above my error event listener).
So! Anyone have any ideas on how to get informative error messages through the global
error event handler?
EDIT: There seems to be some misunderstanding. I'm explicitly avoiding getStackTrace() because it returns 'null' when not in debug mode. Any solution that uses this function is what I'm specifically trying to avoid.
Just noticed the part about "I don't want to use debug." Well, that's not an option, as the non-debug version of Flash does not have any concept of a stack trace at all. Sucks, don't it?
Not relevant but still cool.
The rest is just for with the debug player.
This is part of my personal debug class (strangely enough, it is added to every single project I work on). It returns a String which represents the index in the stack passed -- class and method name. Once you have those, line number is trivial.
/**
* Returns the function name of whatever called this function (and whatever called that)...
*/
public static function getCaller( index:int = 0 ):String
{
try
{
throw new Error('pass');
}
catch (e:Error)
{
var arr:Array = String(e.getStackTrace()).split("\t");
var value:String = arr[3 + index];
// This pattern matches a standard function.
var re:RegExp = /^at (.*?)\/(.*?)\(\)/ ;
var owner:Array = re.exec(value);
try
{
var cref:Array = owner[1].split('::');
return cref[ 1 ] + "." + owner[2];
}
catch( e:Error )
{
try
{
re = /^at (.*?)\(\)/; // constructor.
owner = re.exec(value);
var tmp:Array = owner[1].split('::');
var cName:String = tmp.join('.');
return cName;
}
catch( error:Error )
{
}
}
}
return "No caller could be found.";
}
As a side note: this is not set up properly to handle an event model -- sometimes events present themselves as either not having callers or as some very weird alternate syntax.
You don't have to throw an error to get the stack trace.
var myError:Error = new Error();
var theStack:String = myError.getStackTrace();
good reference on the Error class
[EDIT]
Nope after reading my own reference getStackTrace() is only available in debug versions of the flash player.
So it looks like you are stuck with what you are doing now.
I have a DropdownList that shows a list of providers & the Provider associated with that Patient must be selected.
The Dropdown list:
<s:DropDownList id="providerList"
width="80%"
fontSize="12"
fontWeight="bold"
selectionColor="white"
creationComplete="providerList_creationCompleteHandler(event)"
dataProvider="{model.practiceProviderList.practiceProviders}"/>
where practiceProviders is an ArrayCollection
The CreationCompleteHandler function:
protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
var firstN:String;
var lastN:String;
var providerObj:Provider = new Provider();
if (model.patientDetails.patientDetail.patientProviders != null && model.patientDetails.patientDetail.patientProviders.length > 0)
{
firstN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.firstName;
lastN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.lastName;
for (var count:int = 0; count < patientDetailsModel.practiceProviderList.practiceProviders.length; ++count)
{
providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;
if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
{
this.providerList.selectedIndex = count;
}
}
}
}
The issue is when I go to this page the first time, the error is :
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.newwavetechnologies.modules::demographics/providerList_creationCompleteHandler()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:166]
at com.newwavetechnologies.modules::demographics/__providerList_creationComplete()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:359]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:12266]
at mx.core::UIComponent/set initialized()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:1577]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:759]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]
where line 166 is:
if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
The providerObj is null the first time. But when hit back and come to the same page again, everything works fine and 1 of the providers in the list is selected correctly.
Probably I think the first time, the creationComplete handler method is called before the List is populated. The 2nd time when the call is made, the list is populated and the handler works fine. It would be great if someone can help me in this regard on how to go about this.
Thanks
Harish
It's hard to tell what's going on here, but the problem lies here:
providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;
There's a tonne of places in that line that Null pointer exceptions could occur.
Most likely - the practiceProvider returned at position count doesn't have a provider set. We can't see how this value is populated, but given this code works later, I'd say you've got a race condition happening - the data is being accessed before it's been set.
At very least, you should add a guardClause for this:
var practiceProviders:ArrayCollection = patientDetailsModel.practiceProviderList.practiceProviders;
for (var count:int = 0; count < practiceProviders.length; ++count)
{
providerObj = practiceProviders.getItemAt(count, 0).provider as Provider;
if (!providerObj)
continue;
// etc
}
The race condition is a little trickier, given the asyncronous natoure of flex server calls. (I'm assuming that you're loading the data from a remote server).
There's two approaches to solve this - either
defer execution of this method until the data has loaded - you could do this by adding an eventListener to the ResultEvent of the RemoteService
or
Don't worry about it the first time around, but re-execute the method whenever the data changes.
eg:
protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,onCollectionChange,false,0,true);
updateProviders();
// Rest of existing creationComplete code moved to updateProviders();
}
private function updateProviders()
{
// Code from existing creationComplete handler goes here
}
private function onCollectionChange(event:CollectionEvent):void
{
updateProviders();
}
I'm building a Flex app which requires me to download files.
I have the following code:
public function execute(event:CairngormEvent) : void
{
var evt:StemDownloadEvent = event as StemDownloadEvent;
var req:URLRequest = new URLRequest(evt.data.file_path);
var localRef:FileReference = new FileReference();
localRef.addEventListener(Event.OPEN, _open);
localRef.addEventListener(ProgressEvent.PROGRESS, _progress);
localRef.addEventListener(Event.COMPLETE, _complete);
localRef.addEventListener(Event.CANCEL, _cancel);
localRef.addEventListener(Event.SELECT, _select);
localRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _securityError);
localRef.addEventListener(IOErrorEvent.IO_ERROR, _ioError);
try {
localRef.download(req);
} catch (e:Error) {
SoundRoom.logger.log(e);
}
}
As you can see, I hooked up every possible event listener as well.
When this executes, I get the browse window, and am able to select a location, and click save. After that, nothing happens.
I have each event handler hooked up to my logger, and not a single one is being called! Is there something missing here?
The problem seems to be with my command being destroyed before this could finish.
For a proof of concept, I set my localRef variable to be static instead of an instance variable, and everything went through successfully! I guess Cairngorm commands kill themselves asap!
I am trying to learn Flex and now i have the next code: http://pastebin.com/rZwxF7w1
This code is for my login component. I want to get a special string for encrypting my password. This string is given by my authservice. But when i login i get a multiple times a alert with Done(line 69 in the pastebin code or line 4 in the code on the bottom of this question). But i want that it shows one single time. Does someone know what is wrong with this code?
Tom
protected function tryLogin():void {
encryptStringResult.addEventListener('result', function(event:ResultEvent):void {
var encryptString:String = event.result.toString();
Alert.show('Done');
});
encryptStringResult.token = auth.getEncryptString();
}
It's possible that tryLogin is called multiple times, meaning that you'd be adding multiple event handlers that does the same thing to the same event.
You could try the following:
protected function tryLogin():void {
if (encryptStringResult.hasEventListener('result'))
return;
encryptStringResult.addEventListener('result', function(event:ResultEvent):void {
encryptStringResult.removeEventListener('result', arguments.callee);
var encryptString:String = event.result.toString();
Alert.show('Done');
});
encryptStringResult.token = auth.getEncryptString();
}
It will first check wether or not there already is an event listener for 'result' in which case it will simply return. Also, it will remove the (anonymous) event listener that gets added when the event has been dispatched.