Gxt Rpc Grid called to client and used as local grid - grid

I have an ArrayList in my server I want to display it in a grid at client side. I am using RPC Mechanism for this purpose. The RPC call was successful but while am adding pagination it did not work. If have not done this in a proper way please guide me to do this correctly.
I just took the ArrayList to client and then added to grid. I thought that this is causing problems .
Here is my code:
ArrayList valls=new ArrayList();
public ContentPanel mainPanel1 = new ContentPanel();
public PagingToolBar toolBar = new PagingToolBar(10);
public ContentPanel cpc=new ContentPanel();
public ContentPanel mainPanel = new ContentPanel();
public ContentPanel cp = new ContentPanel();
public ListStore<BeanModelType> clientList=new ListStore<BeanModelType>();
public ListStore<BeanModelType> createGrid()
{
System.out.print("METHOD DDDDDDDDD");
final FeedServiceAsync feedService =Registry.get(RSSReaderConstants.FEED_SERVICE);
feedService.createNewFeed(new AsyncCallback<Feed>() {
#Override
public void onFailure(Throwable caught)
{
// TODO Auto-generated method stub
Info.display("RSSReader", "Unable to create a new feed");
System.out.print("ERRORRRRRR");
}
#Override
public void onSuccess(Feed result)
{
ArrayList valls=result.getVal();
PagingModelMemoryProxy proxy = new PagingModelMemoryProxy(TestData.getClients(result.getVal()));
PagingLoader loader = new BasePagingLoader(proxy);
loader.setRemoteSort(true);
/*
final PagingToolBar toolBar = new PagingToolBar(5);
toolBar.bind(loader);
loader.load(0, 5);
*/
clientList.add(TestData.getClients(valls));
/*
* if we remove the above code only shows the pagination not the content value
*
* Actual code shoiuld be like this
*
*
*clientList= new ListStore<BeanModelType>(loader);
*
* returns clientList;
*
*
* but int his method its not working sirrrr aM SORRY TO SAY THIS
*
*
*/
clientList = new ListStore<BeanModelType>(loader);
toolBar.bind(loader);
loader.load(0, 10);
loader.setRemoteSort(true);
}
});
return clientList;
}
/*
==============================================================================
code for grid
=====================================================================================*/
/*
*
* Grid Starts
*
*/
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig column = new ColumnConfig();
column.setId("name");
column.setHeader("CLIENT");
column.setWidth(200);
configs.add(column);
column = new ColumnConfig("name1", "CAMPAIGN", 150);
column.setAlignment(HorizontalAlignment.LEFT);
configs.add(column);
column = new ColumnConfig("name2", "SITE", 100);
column.setAlignment(HorizontalAlignment.LEFT);
configs.add(column);
column = new ColumnConfig("name3", "ADUNIT", 100);
column.setAlignment(HorizontalAlignment.LEFT);
configs.add(column);
column = new ColumnConfig("name4", "START", 100);
column.setAlignment(HorizontalAlignment.LEFT);
configs.add(column);
ColumnModel cm = new ColumnModel(configs);
Grid<BeanModelType> grid = new Grid<BeanModelType>(createGrid(), cm);
grid.setStyleAttribute("borderTop", "none");
grid.setAutoExpandColumn("name");
grid.setAutoExpandColumn("name1");
grid.setAutoExpandColumn("name2");
grid.setAutoExpandColumn("name3");
grid.setAutoExpandColumn("name4");
grid.setBorders(true);
grid.setStripeRows(true);
//grid.getView().setAutoFill(true);
//grid.setAutoWidth(true);
cp.setBodyBorder(false);
cp.setHeading("Employee List");
cp.setButtonAlign(HorizontalAlignment.CENTER);
cp.setSize(1440,609);
cp.setFrame(true);
cp.setAnimCollapse(false);
cp.setLayout(new FillLayout(Orientation.VERTICAL));
cp.setBottomComponent(toolBar);
cp.add(grid);
cp.setSize("", "370");
mainPanel.add(cp);
/*
*
* End Of Grid
*
*
*
*
*/

You cant do that. feedService.createNewFeed is Async process. What you had return on createGrid method is an empty clientList. reconfigure the grid inside onSuccess method
public void onSuccess(Feed result){
....
clientList = new ListStore<BeanModelType>(loader);
toolBar.bind(loader);
loader.setRemoteSort(true);
grid.reconfigure(clientList, grid.getColumnModel());
}

Related

How to get an auto-sorting TableView?

I have a TableView with a list of items (Transaction) and want it to sort, so that all positive values are above the negative ones. This is the only requirement.
What I have until now:
expensesTableView.sortPolicyProperty().set(
new Callback<TableView<Transaction>, Boolean>() {
#Override
public Boolean call(TableView<Transaction> param) {
Comparator<Transaction> c = (a, b) -> {
if (a.getValue().contains("-") ^ b.getValue().contains("-")) { //getValue() returns a String
return a.getValue().contains("-") ? 1 : -1;
}
return 0;
};
FXCollections.sort(expensesTableView.getItems(), c);
return true;
};
});
This wasn't my idea, I found this on the net, so don't ask if it looks like a strange way to achieve that. The real problem is, that the table doesn't sort on its own when a new item is added/edited/deleted. I need to click the header 3 times and then it does what I want.
How can I have a list that is always sorted correctly?
I tried adding a ChangeListener and sort on change. But besides that this is an ugly way to do that, it didn't even work... I'm at the end of ideas.
The bitwise OR in the comparator didn't work in my tests, so I've changed it to a normal one, and it's also not checking for change in the value of items from the list.
I wonder if it might be more efficient to do a numeric check rather than a String check, negatives could still sort out below, but I guess the conversion might cost more?
My first idea with SortedList in the comments was actually related to keeping the original sorted order, to be restored after the user has changed the sort, so was off the mark.
Edited to add: Just to clarify, it's the act of keeping the source list sorted that keeps the table list sorted.
public class TestApp extends Application {
private int c;
private ObservableList<TestTransaction> sortedOL;
private final Comparator<TestTransaction> comp = (TestTransaction a, TestTransaction b) -> {
if (a.getValue().contains("-") || b.getValue().contains("-")) {
return a.getValue().contains("-") ? 1 : -1;
}
return 0;
};
private TableView<TestTransaction> tableView;
#Override
public void start(Stage primaryStage) {
ArrayList<TestTransaction> rawList = new ArrayList<>();
for (int i = 1; i < 20; i++) {
int v = i * 3;
if (v % 2 > 0) {
v = v * -1;
}
c = i;
rawList.add(new TestTransaction(Integer.toString(v), "Item " + c));
}
sortedOL = FXCollections.observableArrayList(rawList);
sortedOL.addListener((ListChangeListener.Change<? extends TestTransaction> c1) -> {
if (c1.next() && (c1.wasAdded() || c1.wasRemoved())) {
FXCollections.sort(sortedOL, comp);
}
});
FXCollections.sort(sortedOL, comp);
tableView = new TableView<>(sortedOL);
TableColumn<TestTransaction,String> valCol = new TableColumn<>("Value");
valCol.setCellValueFactory(new PropertyValueFactory("value"));
TableColumn<TestTransaction,String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(new PropertyValueFactory("name"));
tableView.getColumns().setAll(valCol, nameCol);
BorderPane tpane = new BorderPane();
Button btnAdd = new Button("Add");
btnAdd.setOnAction(a -> {addTransaction();});
ToolBar tb = new ToolBar(btnAdd);
tpane.setTop(tb);
tpane.setCenter(tableView);
tpane.setPrefSize(600, 600);
Scene scene = new Scene(tpane, 600, 600);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
private void addTransaction() {
c++;
int v = (int) Math.floor(Math.random() * 50);
if (v % 2 > 0) {
v = v * -1;
}
sortedOL.add(new TestTransaction(Integer.toString(v), "New Item " + c));
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
public class TestTransaction {
private String value;
private String name;
public TestTransaction(String value, String name) {
this.value = value;
this.name = name;
}
/**
* #return the value
*/
public String getValue() {
return value;
}
/**
* #return the name
*/
public String getName() {
return name;
}
}
If you want to use SortedList, meaning you could inline the comparator:
sortedOL = FXCollections.observableArrayList(rawList);
SortedList sorted = new SortedList(sortedOL, comp);
tableView = new TableView<>(sorted);

JMapper convert child Collection<Entity> to Collection<Dto>

I'm try to convert DemoEntity to DemoDto. And they have child attribute Collection<SubEntity> and Collection<SubDto>. Error happened when converting Collection<SubEntity>. If I don't add #JMap("subEntities"), JMapper would works well. Now I want that when converting DemoEntity, the Collection<SubEntity> could be converted together.
public class DemoEntity {
/** The id. */
private int id;
/** The code. */
private String code;
/** The date. */
private Date date;
private Collection<SubEntity> subEntities;
#JMapConversion(from = "date", to = "date")
public String convertDate(Date date) {
return date.toString();
}
public DemoEntity(int id, String code, Date date, Collection<SubEntity> subEntities) {
super();
this.id = id;
this.code = code;
this.date = date;
this.subEntities = subEntities;
}
...setter and getter...
}
public class DemoDto {
/** The id. */
#JMap
private Long id;
/** The code. */
#JMap
private String code;
/** The date. */
#JMap
private String date;
#JMap("subEntities")
private Collection<SubDto> subDtos;
... setter and getter...
}
The main method is below:
Collection<SubEntity> subEntities = new ArrayList<>();
for (int i = 1; i < 100; i++) {
SubEntity subEntity = new SubEntity(i, "C" + i, new Date());
subEntities.add(subEntity);
}
DemoEntity demoEntity = new DemoEntity(1, "D" + 1, new Date(), subEntities);
JMapperAPI api = new JMapperAPI();
MappedClass mappedClass = new MappedClass(SubDto.class);
api.add(mappedClass);
JMapper<DemoDto, DemoEntity> mapper = new JMapper<>(DemoDto.class, DemoEntity.class, api);
DemoDto demoDto = mapper.getDestination(demoEntity);
System.out.println(demoDto);
An exception happened, when covert DemoEntity.subEntities to DemoDto.subDtos
Exception in thread "main" com.googlecode.jmapper.exceptions.JMapperException: java.lang.NullPointerException
at com.googlecode.jmapper.config.JmapperLog.ERROR(JmapperLog.java:46)
at com.googlecode.jmapper.JMapper.<init>(JMapper.java:445)
at com.googlecode.jmapper.JMapper.<init>(JMapper.java:411)
at com.googlecode.jmapper.JMapper.<init>(JMapper.java:385)
at com.jmapper.JmapperDemo.main(JmapperDemo.java:35)
Caused by: java.lang.NullPointerException
at com.googlecode.jmapper.operations.complex.AComplexOperation.newInstance(AComplexOperation.java:107)
at com.googlecode.jmapper.operations.complex.AComplexOperation.newInstance(AComplexOperation.java:98)
at com.googlecode.jmapper.operations.recursive.MappedCollectionOperation.sharedCode(MappedCollectionOperation.java:64)
at com.googlecode.jmapper.operations.complex.AComplexOperation.sourceControl(AComplexOperation.java:156)
at com.googlecode.jmapper.operations.complex.AComplexOperation.genericFlow(AComplexOperation.java:133)
at com.googlecode.jmapper.operations.complex.AComplexOperation.write(AComplexOperation.java:89)
at com.googlecode.jmapper.generation.MapperConstructor.mapping(MapperConstructor.java:154)
at com.googlecode.jmapper.generation.MapperConstructor.wrappedMapping(MapperConstructor.java:123)
at com.googlecode.jmapper.generation.MapperConstructor.getMappings(MapperConstructor.java:89)
at com.googlecode.jmapper.generation.MapperGenerator.generateMapperClass(MapperGenerator.java:54)
at com.googlecode.jmapper.generation.MapperBuilder.generate(MapperBuilder.java:88)
at com.googlecode.jmapper.JMapper.createMapper(JMapper.java:458)
at com.googlecode.jmapper.JMapper.<init>(JMapper.java:440)
... 3 more
Besides, is there any method convert Collection<Entity> to Collection<Dto>
This is a case of recursive mapping, you need to map sub classes.
As you map DemoDTO with DemoEntity, you need to map SubDTO with SubEntity.

Bukkit How do I get a argument from a string?

I'm trying to make a plugin that detects when people chat
"#say " it will broadcast a message with those arguments.
What I need to know is how to get arguments from a string.
Please help.
Main:
package com.gong.say;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin{
String sayMessage = ChatColor.GREEN + "Your message has been said!";
public void onEnable()
{
Bukkit.getLogger().info("[BukkitAPIEnhancer] Plugin started!");
Bukkit.getPluginManager().registerEvents(new ChatListener(this), this);
}
public void onDisable()
{
Bukkit.getLogger().info("[BukkitAPIEnhancer] Plugin disabled!");
}
}
ChatListener:
package com.gong.say;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
public class ChatListener implements Listener {
Main plugin;
public ChatListener(Main plugin)
{
this.plugin = plugin;
}
#EventHandler
public void onChat(AsyncPlayerChatEvent e)
{
if(e.isAsynchronous())
{
String message = e.getMessage();
if(message.contains("#say"))
{
//String[] args = Arguments after #say
//Bukkit.broadcastMessage(args);
}
}
}
}
You should usually use commands prefixed by /, so, normally you would do /say String[args], and It would be easier to get the arguments, yet if you want it to be prefixed by #, then that's another story. You could do something like this:
if(message.contains("#say")){
String messageToSend = message.replaceAll("#say", "");//get the arguments
if(messageToSend.length <= 0){//make sure there's something after #say
e.getPlayer().sendMessage("Correct usage: #say <arguments>"); //the user didn't put anything after #say
return;
}
else{
e.setCancelled(true);//cancel the event
Bukkit.getServer().broadcastMessage(messageToSend);//send the message that comes after "#say"
//you may want to add a chat color to the message to make it stand out more
}
}
So, here's what your event should look like:
#EventHandler
public void onChat(AsyncPlayerChatEvent e){
if(e.isAsynchronous()){
String message = e.getMessage();
if(message.contains("#say")){
String messageToSend = message.replaceAll("#say", "");//get the arguments
if(messageToSend.length <= 0){//make sure there's something after #say
e.getPlayer().sendMessage("Correct usage: #say <arguments>"); //the user didn't put anything after #say
return;
}
else{
e.setCancelled(true);//cancel the event
Bukkit.getServer().broadcastMessage(messageToSend);//send the message that comes after "#say"
//you may want to add a chat color to the message to make it stand out more
}
}
}
}
#EventHandler
public void onChat2(AsyncPlayerChatEvent e) {
if(e.isAsynchronous()) {
String msg = e.getMessage();
/** Verify if message starts with #say **/
if(msg.startsWith("#say")) {
/** Split message for get the args **/
String[] args = e.getMessage().split(" ");
/** Verify if have something after #say **/
if(args.length > 1) {
/** Cancel message and broadcast **/
e.setCancelled(true);
StringBuilder sb = new StringBuilder();
for(int i = 1; i <args.length; i++) {
sb.append(args[i] + " ");
}
/** Add color to broadcast */
String broadcast = ChatColor.translateAlternateColorCodes('&', sb.toString());
/** Broadcast prefix **/
String prefix = "§c[Broadcast] §r";
/** Broadcast **/
Bukkit.broadcastMessage(prefix + broadcast);
}
}
}
}

crawler4j compile error with class CrawlConfig - VariableDeclaratorId Expected

The code will not compile. I changed the JRE to 1.7. The compiler does not highlight the class in Eclipse and the CrawlConfig appears to fail in the compiler. The class should be run from the command line in Linux.
Any ideas?
Compiler Error -
Description Resource Path Location Type
Syntax error on token "crawlStorageFolder", VariableDeclaratorId expected after this token zeocrawler.java /zeowebcrawler/src/main/java/com/example line 95 Java Problem
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
import edu.uci.ics.crawler4j.url.WebURL;
public class Controller {
String crawlStorageFolder = "/data/crawl/root";
int numberOfCrawlers = 7;
CrawlConfig config = new CrawlConfig();
config.setCrawlStorageFolder(crawlStorageFolder);
PageFetcher pageFetcher = new PageFetcher(config);
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
controller.addSeed("http://www.senym.com");
controller.addSeed("http://www.merrows.co.uk");
controller.addSeed("http://www.zeoic.com");
controller.start(MyCrawler.class, numberOfCrawlers);
}
public URLConnection connectURL(String strURL) {
URLConnection conn =null;
try {
URL inputURL = new URL(strURL);
conn = inputURL.openConnection();
int test = 0;
}catch(MalformedURLException e) {
System.out.println("Please input a valid URL");
}catch(IOException ioe) {
System.out.println("Can not connect to the URL");
}
return conn;
}
public static void updatelongurl()
{
// System.out.println("Short URL: "+ shortURL);
// urlConn = connectURL(shortURL);
// urlConn.getHeaderFields();
// System.out.println("Original URL: "+ urlConn.getURL());
/* connectURL - This function will take a valid url and return a
URL object representing the url address. */
}
public class MyCrawler extends WebCrawler {
private Pattern FILTERS = Pattern.compile(".*(\\.(css|js|bmp|gif|jpe?g"
+ "|png|tiff?|mid|mp2|mp3|mp4"
+ "|wav|avi|mov|mpeg|ram|m4v|pdf"
+ "|rm|smil|wmv|swf|wma|zip|rar|gz))$");
/**
* You should implement this function to specify whether
* the given url should be crawled or not (based on your
* crawling logic).
*/
#Override
public boolean shouldVisit(WebURL url) {
String href = url.getURL().toLowerCase();
return !FILTERS.matcher(href).matches() && href.startsWith("http://www.ics.uci.edu/");
}
/**
* This function is called when a page is fetched and ready
* to be processed by your program.
*/
#Override
public void visit(Page page) {
String url = page.getWebURL().getURL();
System.out.println("URL: " + url);
if (page.getParseData() instanceof HtmlParseData) {
HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
String text = htmlParseData.getText();
String html = htmlParseData.getHtml();
List<WebURL> links = htmlParseData.getOutgoingUrls();
System.out.println("Text length: " + text.length());
System.out.println("Html length: " + html.length());
System.out.println("Number of outgoing links: " + links.size());
}
}
}
This is a pretty strange error since the code seems to be clean. Try to start eclipse with the -clean option on command line.
Change
String crawlStorageFolder = "/data/crawl/root";
to
String crawlStorageFolder = "./data/crawl/root";
i.e. add a leading .

How to change the loading clock in Flex

How can I replace the loading clock in Flex at the cursor to something like loading wheel in the middle of page instead of cursor
I loathe that little clock. A clock on the mouse just tells the user that something is busy, but they don't know what. It is much better to display a progress indicator visually NEAR the thing that it is showing the progress of!
So, my solution is to enforce a ban on CursorManager, and instead supply your own progress indicator.
Example: A submit button in a form. You know that the submittal is asynchronous and it will take an indeterminate amount of time. So after the user clicks the button and the request is executed, display a little spinner to the direct right of the button. When the request is complete, hide the spinner. It's very sad to see a user who is worried that her actions did not accomplish anything--so give them a way of determining that your application is indeed functioning!
To go along with Jonathon Dumaine's answer, here's an example of the Spinner class I use as a busy indicator in my apps. Just remember to call the stop() method when you first load it since it will use memory in your app if it's playing even when visible is set to false. You can call the play() method when you want it to start spinning again.
Spinner.as
package {
import flash.events.TimerEvent;
import flash.utils.Timer;
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
[Style(name="tickColor",type="uint",format="Color",inherit="no")]
public class Spinner extends UIComponent {
private static var STYLE_TICK_COLOR:String = "tickColor";
private var tickColorChanged:Boolean;
private static var classConstructed:Boolean = classConstruct();
// Make sure we create the ticks the first time updateDisplayList is called
private var creation:Boolean = true;
private var fadeTimer:Timer;
private var _isPlaying:Boolean;
private var _numTicks:int = 12;
private var numTicksChanged:Boolean;
private var _size:Number = 30;
private var sizeChanged:Boolean;
private var _tickWidth:Number = 3;
private var tickWidthChanged:Boolean;
private var _speed:int = 1000;
[Bindable] public var fadeSpeed:int = 600;
public var autoPlay:Boolean = true;
public function Spinner() {
super();
addEventListener(FlexEvent.CREATION_COMPLETE, handleCreationComplete);
addEventListener(FlexEvent.REMOVE, handleUnloading)
}
private function handleCreationComplete(e:FlexEvent):void {
removeEventListener(FlexEvent.CREATION_COMPLETE, handleCreationComplete);
if (autoPlay) {
play();
}
}
/**
* Set the height and width based on the size of the spinner. This should be more robust, but oh well.
*/
override protected function measure():void {
super.measure();
width = _size;
height = _size;
}
/**
* Override the updateDisplayList method
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
if (tickColorChanged || numTicksChanged || sizeChanged || tickWidthChanged || creation) {
creation = false;
// Find out whether it's playing so we can restart it later if we need to
var wasPlaying:Boolean = _isPlaying;
// stop the spinning
stop();
// Remove all children
for (var i:int = numChildren - 1; i >= 0; i--) {
removeChildAt(i);
}
// Re-create the children
var radius:Number = size / 2;
var angle:Number = 2 * Math.PI / _numTicks; // The angle between each tick
var tickWidth:Number = (_tickWidth != -1) ? _tickWidth : size / 10;
var tickColor:uint = getStyle(STYLE_TICK_COLOR);
var currentAngle:Number = 0;
for (var j:int = 0; j < _numTicks; j++) {
var xStart:Number = radius + Math.sin(currentAngle) * ((_numTicks + 2) * tickWidth / 2 / Math.PI);
var yStart:Number = radius - Math.cos(currentAngle) * ((_numTicks + 2) * tickWidth / 2 / Math.PI);
var xEnd:Number = radius + Math.sin(currentAngle) * (radius - tickWidth);
var yEnd:Number = radius - Math.cos(currentAngle) * (radius - tickWidth);
var t:Tick = new Tick(xStart, yStart, xEnd, yEnd, tickWidth, tickColor);
t.alpha = 0.1;
this.addChild(t);
currentAngle += angle;
}
// Start the spinning again if it was playing when this function was called.
if (wasPlaying) {
play();
}
tickColorChanged = false;
numTicksChanged = false;
sizeChanged = false;
tickWidthChanged = false;
}
}
private static function classConstruct():Boolean {
if (!FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("Spinner")) {
// If there is no CSS definition for StyledRectangle,
// then create one and set the default value.
var newStyleDeclaration:CSSStyleDeclaration = new CSSStyleDeclaration();
newStyleDeclaration.setStyle(STYLE_TICK_COLOR, 0x000000);
FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("Spinner", newStyleDeclaration, true);
}
return true;
}
override public function styleChanged(styleProp:String):void {
if (styleProp == STYLE_TICK_COLOR) {
tickColorChanged = true;
invalidateDisplayList();
}
}
/**
* Begin the circular fading of the ticks.
*/
public function play():void {
if (! _isPlaying) {
fadeTimer = new Timer(speed / _numTicks, 0);
// addEventListener for the ticking going forward
fadeTimer.addEventListener(TimerEvent.TIMER, handleTicking);
fadeTimer.start();
_isPlaying = true;
}
}
/**
* Start the Tick at each Timer.
*/
public function handleTicking(e:TimerEvent):void {
var tickNum:int = int(fadeTimer.currentCount % _numTicks);
if (numChildren > tickNum) {
var tick:Tick = getChildAt(tickNum) as Tick;
tick.fade(fadeSpeed != 1 ? fadeSpeed : speed * 6 / 10);
}
}
/**
* Start the Tick at each Timer.
*/
public function handleUnloading(e:FlexEvent):void {
stop();
removeEventListener(FlexEvent.REMOVE, handleUnloading);
trace("Removing "+this.uid.toString());
}
/**
* Stop the spinning.
*/
public function stop():void {
if (fadeTimer != null && fadeTimer.running) {
_isPlaying = false;
fadeTimer.removeEventListener(TimerEvent.TIMER, handleTicking);
fadeTimer.stop();
}
}
/**
* The overall diameter of the spinner; also the height and width.
*/
[Bindable]
public function set size(value:Number):void {
if (value != _size) {
_size = value;
sizeChanged = true;
invalidateDisplayList();
invalidateSize();
}
}
public function get size():Number {
return _size;
}
/**
* The number of 'spokes' on the spinner.
*/
[Bindable]
public function set numTicks(value:int):void {
if (value != _numTicks) {
_numTicks = value;
numTicksChanged = true;
invalidateDisplayList();
}
}
public function get numTicks():int {
return _numTicks;
}
/**
* The width of the 'spokes' on the spinner.
*/
[Bindable]
public function set tickWidth(value:int):void {
if (value != _tickWidth) {
_tickWidth = value;
tickWidthChanged = true;
invalidateDisplayList();
}
}
public function get tickWidth():int {
return _tickWidth;
}
/**
* The duration (in milliseconds) that it takes for the spinner to make one revolution.
*/
[Bindable]
public function set speed(value:int):void {
if (value != _speed) {
_speed = value;
fadeTimer.stop();
fadeTimer.delay = value / _numTicks;
fadeTimer.start();
}
}
public function get speed():int {
return _speed;
}
public function get isPlaying():Boolean {
return _isPlaying;
}
}
}
Tick.as
package {
import flash.display.Sprite;
import mx.effects.Fade;
public class Tick extends Sprite {
private var tickFade:Fade = new Fade(this);
public function Tick(fromX:Number, fromY:Number, toX:Number, toY:Number, tickWidth:int, tickColor:uint) {
this.graphics.lineStyle(tickWidth, tickColor, 1.0, false, "normal", "rounded");
this.graphics.moveTo(fromX, fromY);
this.graphics.lineTo(toX, toY);
}
public function fade(duration:Number):void {
tickFade.alphaFrom = 1.0;
tickFade.alphaTo = 0.1;
tickFade.duration = duration;
tickFade.play();
}
}
}
You can hide the cursor rather than calling setBusyCursor on the CursorManager use http://www.igorcosta.com/flex3/doc/mx/managers/CursorManager.html#hideCursor() then just toggle the visibility of an overlay with your loading graphic.
You can use CursorManager.showCursor(); and CursorManager.removeBusyCursor(); to show and remove busy cursor.

Resources