LWUIT中的进度条实现(Progress Indicator & Threads In LWUIT by Shai Almog)
LWUIT doesn’t ship with a pre-existing progress indicator, mostly because making something generic enough for all the common cases is not as simple as it might seem in the beginning. Especially when considering how easy it is to write your own progress indicator…
This is a simple example of how to create a custom component in LWUIT in this specific case a progress indicator that supports both drawing itself (as a filled round rectangle and as a couple of images overlayed one on top of the other. The progress indicator component is fully themeable and customizable and will accept all L&F settings seamlessly. The screenshots show both an image based indicator (its ugliness is just a testament to my bad drawing skills) and an indicator drawn in graphics primitives (fill/drawRoundRect). These are the images used to draw the image progress:
Indicator & Threads In LWUIT by Shai Almog)” TITLE=”LWUIT中的进度条实现(Progress Indicator & Threads In LWUIT by Shai Almog)” />Indicator & Threads In LWUIT by Shai Almog)” TITLE=”LWUIT中的进度条实现(Progress Indicator & Threads In LWUIT by Shai Almog)” />
As part of this I also wanted to create something else familiar to Swing developers, the SwingWorker. Generally I prefer the foxtrot approach implemented in LWUIT as invokeAndBlock in Display, however lots of people like the SwingWorker approach so I used it here as part of the explanations.
First lets create the Progress indicator component:
public class Progress extends Component { private byte percent; private Image unfilled; private Image filled;
public void setProgress(byte percent) { this.percent = percent; repaint(); }
protected Dimension calcPreferredSize() { if(filled != null) { return new Dimension(filled.getWidth(), filled.getHeight()); } else { // we don’t really need to be in the font height but this provides // a generally good indication for size expectations return new Dimension(Display.getInstance().getDisplayWidth(), Font.getDefaultFont().getHeight()); } }
This code seems to me to be simple but obviously I’m not objective, if something is not clear or you think it might not be clear to others please let me know in the comments.
BackgroundTask is my equivalent to SwingWorker, its much simpler than SwingWorker:
public abstract class BackgroundTask {
public final void start() { if(Display.getInstance().isEdt()) { taskStarted(); } else { Display.getInstance().callSeriallyAndWait(new Runnable() { public void run() { taskStarted(); } }); } new Thread(new Runnable() { public void run() { if(Display.getInstance().isEdt()) { taskFinished(); } else { performTask(); Display.getInstance().callSerially(this); } } }).start(); }
public void taskStarted() { }
public abstract void performTask();
public void taskFinished() { } }
And this is the code to display these two progress bars:
Form progressForm = new Form(“Progress”); progressForm.setLayout(new BoxLayout(BoxLayout.Y_AXIS)); Progress p1 = new Progress(); progressForm.addComponent(new Label(“Drawn”)); progressForm.addComponent(p1); Progress p2 = new Progress(Image.createImage(“/unfilled.png”), Image.createImage(“/filled.png”)); p2.getStyle().setBgTransparency(0); progressForm.addComponent(new Label(“Image Based”)); progressForm.addComponent(p2); progressForm.show();
class ProgressCommand extends Command { private Progress p; public ProgressCommand(String name, Progress p) { super(name); this.p = p; } public void actionPerformed(ActionEvent ev) { new BackgroundTask() { public void performTask() { for(byte b = 0 ; b <= 100 ; b++) { try { p.setProgress(b); Thread.sleep(100); } catch (InterruptedException ex) { ex.printStackTrace(); } } } }.start(); } }
哈哈,谢谢肯定,以后要继续努力!
有图有代码,不错不错,顶~
最近在写文档,参考的你的大作《JBOB48_SCS_ams_UI_flow》,写得真不错!