Strange behaviour with Transitions - java-me

I set transitions to a Form :
public class Ecran extends Form {
private Transition transIn = CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, true, 250);
private Transition transOut = CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, false, 250);
public Ecran()
{
super();
setTransitionInAnimator(transIn);
setTransitionOutAnimator(transOut);
}
public Ecran(String titre)
{
super(titre);
setTransitionInAnimator(transIn);
setTransitionOutAnimator(transOut);
}
}
public class MenuPrincipalForm extends Ecran implements ActionListener, FocusListener, Runnable
{
...
}
The problem is that in runtime the transition slides twice ! So how to make it slide only once ?

Use only the out transition for forms. Transition in allows more elaborate cases for forms and is useful for cases such as dialogs.

Related

OpenFL - How to use addChild in another class?

The answer should be simple but I can't find out how anywhere..
So I have a Main.hx class and a ObjectManager.hx class.
In the main class's constructor, it calls ObjectManager.addAllToScreen(); and my objectManager should then add the objects to the screen.
I thought this would be ok because in the constructor of Main you can just say addChild(Objects.platform); but apparently addChild isn't accessible?
The error is: Class<Main> has no field addChild so I'd guess that addChild is a method of Sprite or something?
package;
class Main extends Sprite {
public function new() {
super();
ObjectManager.addAllToScreen();
}
}
In ObjectManager:
package;
class ObjectManager {
public static function addAllToScreen():Void {
Main.addChild(Objects.platform);
Main.addChild(Objects.messageField);
}
}
UPDATE:
Ok so now the code is this... and it runs just fine apart from the objects never showing up on screen - however if the addChild code is put in main, they do show up.
Main:
class Main extends Sprite {
public function new() {
super();
var objectManager = new ObjectManager();
objectManager.addAllToScreen();
}
ObjectManager:
package;
import openfl.display.Sprite;
class ObjectManager extends Sprite {
public function new() {
super();
}
public function addAllToScreen() {
addChild(Objects.platform);
addChild(Objects.messageField);
}
}
addChild() is available in openfl.DisplayObjectContainer, which Sprite extends. So you would need to make your class extend Sprite, yes.
You just need to pass a reference to the stage to your ObjectManager class so you can add things to it later on.
Check this out.
Main.hx
package;
import openfl.display.Sprite;
class Main extends Sprite {
public function new () {
super();
ObjectManager.setup(stage);
ObjectManager.addAllToScreen();
}
}
ObjectManager.hx
package ;
import openfl.display.Sprite;
import openfl.display.Stage;
class ObjectManager {
// The reference to the applications stage
private static var stage:Stage;
// Do this first,
// we need to hold a reference to the Stage object so we can add to it later
public static function setup(stageref:Stage) {
stage = stageref;
}
public static function addAllToScreen() {
// An array of randomly generated sprite objects
var sprites:Array<Sprite> = [randomSprite(), randomSprite(), randomSprite()];
for(sprite in sprites) {
// Position the sprites randomly over the screen
sprite.x = Math.random() * stage.stageWidth;
sprite.y = Math.random() * stage.stageHeight;
// Add them to the stage
stage.addChild(sprite);
}
}
// Ignore this
// Makes a randomly sized circle in a random colour
private static function randomSprite():Sprite {
var spr = new Sprite();
spr.graphics.beginFill(Std.int(0xffffff * Math.random()), 1);
spr.graphics.drawCircle(0, 0, (Math.random() * 100) + 20);
spr.graphics.endFill();
return spr;
}
}

Binding a button to a different view model

I have a button in View "A" which already has a bindingSet attached to it (it binds to ViewModel "A"). I have button though which needs to be bound to ViewModel "B".
What is the best way to do this?
Your ViewModel is your Model for your View.
If that ViewModel is made up of parts, then that can be done by aggregation - by having your ViewModel made up of lots of sub-models - e.g:
// simplified pseudo-code (add INPC to taste)
public class MyViewModel
{
public MainPartViewModel A {get;set;}
public SubPartViewModel B {get;set;}
public string Direct {get;set;}
}
With this done, then a view component can be bound to direct sub properties as well as sub properties of sub view models:
set.Bind(button).For("Title").To(vm => vm.Direct);
set.Bind(button).For("TouchUpInside").To(vm => vm.A.GoCommand);
set.Bind(button).For("Hidden").To(vm => vm.B.ShouldHideThings);
As long as each part supports INotifyPropertyChanged then data-binding should "just work" in this situation.
If that approach doesn't work for you... In mvvmcross, you could set up a nested class within the View that implemented IMvxBindingContextOwner and which provided a secondary binding context for your View... something like:
public sealed class Nested : IMvxBindingContextOwner, IDisposable {
public Nested() { _bindingContext = new MvxBindingContext(); }
public void Dispose() {
_bindingContext.Dispose();
}
private MvxBindingContext _bindingContext;
public IMvxBindingContext BindingContext { get { return _bindingContext; } }
public Thing ViewModel {
get { return (Thing)_bindingContext.DataContext; }
set { _bindingContext.DataContext = value; }
}
}
This could then be used as something like:
_myNested = new Nested();
_myNested.ViewModel = /* set the "B" ViewModel here */
var set2 = _myNested.CreateBindingSet<Nested, Thing>();
// make calls to set2.Bind() here
set2.Apply();
Notes:
I've not run this pseudo-code, but it feels like it should work...
to get this fully working, you will also want to call Dispose on the Nested when Dispose is fired on your View
given that Views and ViewModels are normally written 1:1 I think this approach is probably going to be harder to code and to understand later.

Presenter with swappable sub-presenters

Using GWT 2.4 with MVP, I have a presenter where the top portion can swap between a read-only presenter of a set of data or an editor for that data, depending on how you arrived at the page.
Without using GWTP, how can I swap between those two presenters and the underlying views?
Currently, the classes looks like this:
public class MainPagePresenter implements Presenter, MainPageView.Presenter, ParentPresenter {
private MainPageViewview;
private final ClientFactory clientFactory;
private StaticDataPresenter staticPresenter;
private SomeOtherPresenter otherPresenter;
}
I'd like for StaticDataPresenter to become some structure that can either hold a StaticDataPresenter or a DynamicDataPresenter that lets you edit.
Thanks for your input.
public interface DataPresenter {
void handleEdit();
}
public class StaticDataPresenter implements DataPresenter {
#Override
public void handleEdit() {
// Do nothing.
}
}
public class DynamicDataPresenter implements DataPresenter {
#Override
public void handleEdit() {
// Do something.
}
}
public class MainPagePresenter implements Presenter, MainPageView.Presenter, ParentPresenter {
private MainPageView view;
private final ClientFactory clientFactory;
private DataPresenter dataPresenter;
private SomeOtherPresenter otherPresenter;
...
public void switchDataPresenter(DataPresenter dataPresenter) {
this.dataPresenter = dataPresenter;
DataPresenterView dataPresenterView = view.dataPresenterView();
dataPresenterView.setPresenter(dataPresenter);
}
}
Your MainPageView can have a DeckPanel with both the StaticDataPresenter's view, and the SomeOtherPresenter's view.
MainPagePresenter can then tell the MainPageView to switch what is being displayed based on your needs.
What I ended up doing was putting both editors on the page, and then turning on and off the visibility in the presenter.
Thanks for your suggestions. They helped.

How do I get input from a user using j2me canvases? is this even possible?

I am currently trying to learn J2ME and build a connect four game (some of you might know this as 'four in a row'). I've More or less got all of the aspects of my game working, apart from one thing that is driving me mad! This is of course getting the text from the user!
For the two player mode of the game I want to be able to allow each player to enter their name. I am struggling to find a working example of text input that doesn't use the main Midlet.
For example the examples on java2x.com just use a single midlet (no classes or canvases or anything).
As it stands my application's main midlet start method simply opens a main menu class:
package midlet;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import view.*;
public class Main extends MIDlet {
public void startApp() {
MainMenu mm = new MainMenu();
showScreen(mm);
}
public static void showScreen(Displayable screen) {
Display.getDisplay(instance).setCurrent(screen);
}
public void pauseApp() {
}
public static void quitApp() {
instance.notifyDestroyed();
}
public void destroyApp(boolean unconditional) {
}
}
The main menu class is as follows:
package view;
import javax.microedition.lcdui.*;
import lang.*;
import model.*;
import midlet.Main;
public class MainMenu extends List implements CommandListener {
private Command ok = new Command(StringDefs.currDefs.getString("TEXT_OK"), Command.OK, 1);
public MainMenu() {
super(StringDefs.currDefs.getString("TEXT_TITLE"), List.IMPLICIT);
// we we add in the menu items
append(StringDefs.currDefs.getString("TEXT_PLAY1"), null);
append(StringDefs.currDefs.getString("TEXT_PLAY2"), null);
append(StringDefs.currDefs.getString("TEXT_HIGHSCORETABLE"), null);
append(StringDefs.currDefs.getString("TEXT_HELP"), null);
append(StringDefs.currDefs.getString("TEXT_QUIT"), null);
this.addCommand(ok);
this.setCommandListener(this);
}
public void commandAction(Command c, Displayable d) {
if (c == ok) {
int selectedItem = this.getSelectedIndex();
if (selectedItem != -1) {
switch (selectedItem) {
case 0:
GameBoard gameBoard = new model.GameBoard();
GameCanvasOnePlayer board = new GameCanvasOnePlayer(gameBoard);
Main.showScreen(board);
break;
case 1:
GameBoard gameBoardTwo = new model.GameBoard();
GameCanvasTwoPlayer GameCanvasTwoPlayer = new GameCanvasTwoPlayer(gameBoardTwo);
Main.showScreen(GameCanvasTwoPlayer);
break;
case 2:
HighScores hc = new HighScores();
midlet.Main.showScreen(hc);
break;
case 3:
Help he = new Help();
midlet.Main.showScreen(he);
break;
case 4:
QuitConfirmation qc = new QuitConfirmation();
midlet.Main.showScreen(qc);
break
}
}
}
}
}
When a two player game is selected (case 1 in the above switch) from this menu I would like two text boxes to appear so that I can get both player names and store them.
What would be the best way of going about this? is this even possible with canvases? And do you know where I can find a relevant example or at least something which may help?
You can either:
1. Make the user enter his input in an ugly Textbox (which takes the whole screen)
2. Use the textbox control I've written from scratch a long time ago which is available here
and looks something like this (3 Textfields shown):
I've got a solution! well sort of.
I can create a form without using the main midlet:
The following main class is part of a source package called midlet (much like in my project):
package midlet;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import view.*;
public class Main extends MIDlet {
private static UsernameForm unameForm=new UsernameForm();
private static MIDlet instance;
public void startApp() {
instance=this;
showScreen(unameForm); // show user name form
}
public static String getUsername1() {
return(unameForm.getUsername1());
}
public static String getUsername2() {
return(unameForm.getUsername2());
}
public void pauseApp() {
}
public static void showScreen(Displayable d) {
Display.getDisplay(instance).setCurrent(d); // show next screen
}
public void destroyApp(boolean unconditional) {
}
}
The next bit of code is the username form class that is part of a source package called view:
package view;
import javax.microedition.lcdui.*;
public class UsernameForm extends Form implements CommandListener {
private String username1="";
private String username2="";
private TextField tfUsername1=new javax.microedition.lcdui.TextField("User 1","User1",40,TextField.ANY);
private TextField tfUsername2=new javax.microedition.lcdui.TextField("User 2","User2",40,TextField.ANY);
private Command cmdOK=new Command("OK",Command.OK,1);
public UsernameForm() {
super("User details");
append(tfUsername1);
append(tfUsername2);
addCommand(cmdOK);
setCommandListener(this);
}
public void commandAction(Command cmd,Displayable d) {
if (cmd==cmdOK) {
this.setUsername1(tfUsername1.getString());
this.setUsername2(tfUsername2.getString());
// TO DO, GO TO NEXT SCREEN
}
}
/**
* #return the username1
*/
public String getUsername1() {
return username1;
}
/**
* #param username1 the username1 to set
*/
public void setUsername1(String username1) {
this.username1 = username1;
}
/**
* #return the username2
*/
public String getUsername2() {
return username2;
}
/**
* #param username2 the username2 to set
*/
public void setUsername2(String username2) {
this.username2 = username2;
}
}
So it looks like there's no easy way of doing it using canvases, I think I am better of using 'ugly forms' instead as they should work whatever the device.
That's a really sticky situation. Basically you will need to use J2ME's input text widget (which by the way looks horrible). If you don't, you'll end up having to implement all the logic behind the different types of phone keyboards and you won't have access to the dictionary... Your canvas will basically only be capturing keystrokes, not text input...
Sorry.
Here you need to, implement custom Items, all you need to do is to extend the part of the canvas where to want the user/player to enter his/her name to the CustomItems, and implement the customItems predefined abstract methods, and write method for Key Strokes and that's available in the nokia forum. They have explained it pretty good. Check out the Nokia forum.

Is it ok to set Datacontext as a property in repository?

Is there any potential problem in setting datacontext as property like this:
repository
public Repository()
{
public DataContext dc {get;set;}
public GetOrders(int id)
{ ...from dc.Orders...}
}
service layer:
public GetNewOrders()
{
....
Repository rep=new Repository();
using {DataContext dc=new DataContext())
{
rep.dc=dc;
rep.GetOrders(id);
}
}
From what I have read, using the DataContext "for more than one business conversation is usually the wrong thing to do." Scroll down to the Why Is This Important? section for the quote. Due to caching and other factors, you should consider your DataContext stale immediately. From that, it is safe to say you don't want to keep the DataContext as a property that is reused by all your methods. Using Eric Duncan's suggestion, you will want to pass in some kind of DataContext factory to get a new context for each query.
For a discussion focused on the DataContext, the APress Pro LINQ book has an entire chapter on the DataContext, the very last page of which also advises you to "consider the DataContext stale immediately."
In DDD, you're missing the bigger picture here by referencing the concret classes. You are not interfacing between the Repository and "Services layer" by best practices. If you must have DataContext injected into the Repository, I would recommend refactoring to:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(IDataContext dataContext)
{
_dataContext = dataContext;
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
The better solution would be to let the Repository handle the DataContext on its own - keeping the seperation of concert valid by masking the underlying requirements:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(String connectionString)
{
_dataContext = new DataContext(connectionString);
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
If you must keep control of the DataContext (or another class) yourself (perhaps you want to keep a static reference around, or change settings based on an WebRequest, etc), you you will need to use a "Factory".
The factory would look something like this:
public static class DataContextFactory
{
public static IDataContext GetInstance()
{
// return either a static instance,
// or threaded instance, a GlobalContext instance
// or whatever your preference is here
//
}
}
That way, you have full control over how the instance of DataContext is controlled outside and away from your "Services" layer. So, you would use this DataContextFactory like the following:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
public IList<Orders> GetNewOrders()
{
using (var dataContext = DataContextFactory.GetInstance())
{
// dataContext is now your IDataContext to work with
}
}
}
"How to access the IRepository?" you may ask?
Your services layer would do something like:
public void GetNewOrdersForServices()
{
// Not recommended!
// IRepository repo = new Repository()
//
// The following is recommended instead; because, it removes the
// the Concret reference from your Services layer completely!
//
IRepository repo = ServiceLocator.InstanceOf<IRepository>();
IList myList = repo.GetNewOrders();
}
Or, you would inject it into the constructor of your service using your favorite flavor of Inversion of Control container like so:
public class OrderService
{
private IRepository _repo;
public OrderService(IRepository repo)
{
_repo = repo;
}
public void GetNewOrdersForServices()
{
IList myList = _repo.GetNewOrders();
}
If you are not fimilar with the service locator concepts, check out Castle Windsor as it Encapsulates just about all your needs.

Resources