Kashiash's Blog

o programowaniu inaczej : jak zrobić i się nie narobić

Archive for Luty 2011

Posted by kashiash w dniu 11 lutego, 2011

Tutorial II: Vehicle Management System – Part 3: New Tables

 

 

In such a vehicle management system, an information about expenses is usually very useful.

To implement it, let’s add a FuelLog and two dictionary tables about fuel provider company and fuel type. To do so, please follow the table:

FuelLog  

 

PkFuelLog 

KEY(Ful:Id),DUP,NOCASE 

KeyVehicle 

KEY(Ful:Vehicle),DUP,NOCASE 

KeyBrand 

KEY(Ful:Brand),DUP,NOCASE 

KeyFuelType 

KEY(Ful:FuelType),DUP,NOCASE 

Columns 

 

Id  

LONG 

Vehicle 

LONG 

FillUpDate 

DATE 

Quantity  

REAL 

TotalCost  

REAL 

Notes 

STRING(100) 

StartingOdometer 

LONG 

EndingOdometer 

LONG 

OdometerChange 

LONG 

Brand 

LONG 

FuelType 

LONG 

   

Brands 

 

PkBrands

KEY(Bra:Id),DUP,NOCASE 

KeyBrand 

KEY(Bra:Brand),DUP,NOCASE 

Kolumny 

 

Id  

LONG 

Brand 

STRING(51) 

   
   

FuelTypes  

 

PkFuelTypes 

KEY(Fty:Id),DUP,NOCASE 

KeyFuelType 

KEY(Fty:FuelTypes),DUP,NOCASE 

Columns 

 

Id 

LONG 

FuelTypes 

STRING(50) 

 

In addition, define relations between the tables:

FuelTypes <->> FuelLog

Vehicles <->> FuelLog

Brands <->> FuelLog

For the newly created FuelLog table, set must be in file for the fields Vehicle, Brand i FuelType. (this should be done in the Validity Checks tabs)

Then, set for these columns UseSpinner and DSP.

 

 

 

Finally, we’ll obtain a following database structure:

 

Let’s save the application and generate code.

We have 3 new tables, so we need new icons for them. Without them, the application will not run.

We need brands.png, fuelstypes.png and fuellog.png, to be added to the res/drawables folder.

After starting the generated application we should see:

 

 

As you see, we are running out of space. Making icons smaller than 48×48 would help to some extent,. We could also stop showing all these buttons in the main menu.

But, so far, look what more came out from our efforts:

 

There is surely a problem with space, but MOBY will help us!

In File User Options set PromptsInLine(true) . After regenerating:

 

 

The same can be set for Vehicles: PromptsInLine(true).

In the current version, there are 2 posssiblities to get into the fuel log: either directly from the main menu or from the menu key in the vehicle screen.

When we set UseTabHost(true) in FileUserOptions for Vehicles, the application will generate code so, that the list will be accessible also from a separate tab in the vehicle screen.



 

In the subsequent steps, we’ll work on more lists to be displayed for vehicles and on the fuel log. So far play with the application as is.

 

 

 

 

 

 

 

 

 

Why doesn’t it compile ?

When we get a message in Eclipse that our project has errors and can’t be started, check the PROBLEMS tab.

Here an example of a message. In this case cleaning the project is sufficient to get it right.

 

We recommend to start any attempts in this way. Simply select Project/Clean and look what is displayed in the Problems tab.

In addition, it is good to know that common error in a MOBY application is caused by the lack of required icons.

Simply add the icons with required names to the res/drawables folder and the issue should be solved.

 

 

 

 

 

Posted in Uncategorized | Leave a Comment »

Sprawdzanie poprawności wprowadzonych danych

Posted by kashiash w dniu 6 lutego, 2011

Clarion posiada możliwość deklaracji kontroli poprawności danych

Na zakładce Validate Fields możemy wybrać kilka opcji. MOBY korzysta z niektórych z nich:

MUST BE IN TABLE – oznacza ze wartość z tej kolumny musi znajdować się w tabeli w relacji. MOBY pilnuje zaraz po wprowadzeniu wartości czy jest poprawna

CANNOT BE ZERO OR BLANK – w polu musi być cokolwiek wpisane

MUST BE IN RANGE – wartość musi znajdować się w wartościach podanych w tej opcji

Dodatkowo można wypełnić opcje VALIDATE i wpisać w niej wyrażenie logiczne zgodne z syntaktyka języka JAVA, które musi być spełnione, aby można było zapisać dane.

Posted in Android, Clarion, MOBY | Leave a Comment »

Ewidencja pojazdów: Policzmy to i owo ;)

Posted by kashiash w dniu 6 lutego, 2011

Standardowo clarion ma cos takiego jak Formuły, gdzie możesz zdecydować co ma być liczone , jak i kiedy. Niestety zrobienie tego w DCT jest dużo trudniejsze. Uważam, że nie należy robić nic na siłę. Moby I pozwala jedynie na określenie formuł wypełniających poszczególne pola, jakieś specyficzne wyliczenia trzeba zakodować ręcznie. Uspokajam – MOBY II będzie pozwalał na definiowanie formuł w sposób podobny do clarion’a.

Prosta aplikacja, którą próbujemy tu zrobić ma rejestr pojazdów oraz rejestr ich tankowania. Podczas tankowania użytkownik będzie wpisywał stan licznika z momentu tankowania. Możemy ta informacje wpisywać do pola odometer w naszych pojazdach, przez co będą aktualizowane automatycznie.

Jak to zrobić ?

Prostym zapytaniem SQL jesteśmy w stanie pobrać najwyższa wartość stanu licznika dla wybranego pojazdu. Poniżej przypominam strukturę bazy danych.

Pytamy o maksymalna wartość licznika w logu, np. tak :

Select max(EndingOdometer) from FuelLog where Vehicle = 1

Operacje wykonujemy na oknie VehiclesEdit, gdzie id naszego pojazdu możemy pobrać z obiektu reprezentującego rekord z tabeli Vehicles:

Możemy się do niego dostać używając metody getId :


VehiclesRecord.getId()

Czyli nasze zapytanie bedzie wyglądalo tak :

„Select max(EndingOdometer) from FuelLog where Vehicle = ” + VehiclesRecord.getId()

a takie zapytanie wywołamy w następujący sposób:

VehiclesxDbAdapter.getInstance().getQueryScalarLong(„Select max(EndingOdometer) from FuelLog where Vehicle = ” + VehiclesRecord.getId());

aby wpisywalo sie do naszego pola należy wpisać w opcjach pola EndingOdometer EVALUATE oraz EVALUATECONDITION.

EVALUATE(VehiclesxDbAdapter.getInstance().getQueryScalarLong(„Select max(EndingOdometer) from FuelLog where Vehicle = ” + VehiclesRecord.getId()))

EVALUATECONDITION( VehiclesRecord.getId() != null)

Dzięki tym opcjom MOBY wygeneruje kod który pod warunkiem spełnienia warunku w EVALUATECONDITION wpisze wynik z EVALUETE do pola EndingOdometer


public
void DoLookups() {


if (VehiclesRecord.getId() != null) {


VehiclesRecord.setOdmoter(VehiclesxDbAdapter.getInstance().getQueryScalarLong(„Select max(EndingOdometer) from FuelLog where Vehicle = „ + VehiclesRecord.getId()));


// Vehicles Veh:Odmoter


if ( VehiclesRecord.getOdmoter() != null) {


mOdmoterText.setText(VehiclesRecord.getOdmoter().toString());

}

}

}

Uruchamiamy aplikację, wybieramy pojazd, wchodzimy do jego edycji i robimy wpis do logu tankowania, wracamy na dane i pojazdu i …? cieszymy się jak nasz log się aktualizuje.

Skoro poznaliśmy kolejną, istotną możliwość MOBY, wykorzystajmy ja dalej: w logu tankowania przydałoby się, aby stan licznika poprzedniego tankowania był automatycznie podpowiadany, przy okazji niech, jako licznik kończący wpisze się ta sama wartość i oczywiście wyliczy się różnice przejechanych kilometrów.

Robimy to bardzo podobnie jak wcześniej, zmieniamy tylko klauzulę where – mamy wyszukać maksymalna wartość z licznika dla wpisów wcześniejszych niż edytowany. W EVALUATE wpiszemy wyrażenie wyliczające maksymalny licznik z wcześniej wpisanej pozycji

FuelLogxDbAdapter.getInstance().getQueryScalarLong(„Select max(EndingOdometer) from FuelLog where Vehicle = ” + FuelLogRecord.getVehicle() + ” and _id < ” + FuelLogRecord.getId())


Dzięki temu pole StartingOdometer będzie automatycznie uzupełniane.

W kolejnym kroku wprowadzimy wypełnianie EndingOdometer w sytuacji gdy jest puste. Dodatkowo włączymy opcje SPINNABLE, co spowoduje ze MOBY doda 2 przyciski, które pozwalają zwiększać lub zmniejszać wartość tego pola.


UPDATECONTROLS powoduje ze po aktualizacji tego pola pozostałe są ponownie wyliczane, i pole OdometerChange zostanie przeliczone wg zadeklarowanego wyrażenia w EVALUATE.


Wchodzimy do edycji pojazdu, jak widacz licznik jest 6809


Teraz dopisujemy tankowanie, podpowiada nam się Starting i Ending Odometer, zmieniając wartość w Ending Odometer, automatycznie wylicza nam się OdometerChange


Po zapisaniu informacji o tankowaniu w pojeździe automatycznie zaktualizuje nam się Licznik bieżacy



Posted in Android, Clarion, MOBY | Leave a Comment »

Ewidencja pojazdów – dopieszczanie interfejsu

Posted by kashiash w dniu 5 lutego, 2011

O atrakcyjności aplikacji decyduje wygląd interfejsu. Niestety interfejs androida nie jest „sexy” i np. odbiega od tego co oferuje iPhone czy aplikacje robione w Adobe Air/Flex. Bolączką wielu programistów, niestety także autora tego tekstu jest brak smykałki do dopracowywania wyglądu interfejsu. Na szczęście Moby dostarcza kilka predefiniowanych szablonów wyglądu list danych. Oto opis jak ich używać.

Dla każdej tabeli możemy zdefiniować layout alternatywny. Najprostszy z nich to Layout 3 zawierający linijke tekstu oraz ikonkę pozwalającą wyświetlać ikonkę, która zależy od zawartości rekordu listy.

Układ graficzny nr 3

LeftIconField

UpTextField

RightIconField

LoTextField

Aby uzyskać taki wygląd należy w FileUserOptions dodać opcje typu Number o nazwie ALTROWLAYOUT i wpisać jej wartość 3

Oraz określić, jakie pole ma być wyświetlane w UpTextField w przypadku tabeli Dostawców paliwa wybieramy pole Brand, co oznacza , że w polu górnym widoku ma być wyświetlona wartość kolumny Brand z tabeli którą edytujemy czyli w tym przypadku Brands.

Dodatkowo określamy jak ikonka powinna być wyświetlona w LeftIconField podajemy wyrażenie zgodne ze składnia języka JAVA, którego wynik daje nazwę ikonki.

Podobnie robimy w tabeli Makes

Oraz w tabeli Models

Wykaz ikonek potrzebnych dla naszej aplikacji – zawartośc katalogu res\drawables

Układ graficzny nr 3 wersja rozbudowana

Aby pokazac układ bardziej rozbudowany, zmodyfikujemy nieco tabelę z dostawcami paliwa – dodamy pole z informacja czy akceptują karte paliwowa UTA

W ten sposób definiujemy pole typu CHECKBOX

Generujemy aplikację. W związku z tym, że zmieniła nam się struktura bazy, modyfikujemy numer wersji bazy danych. Dzięki tej informacji MOBY wygeneruje procedurę do konwersji z poprzedniej wersji, na wersje bieżącą.

Ustawiamy dodatkowe opcje jak poniżej:

Dodajemy opcje związane z informacja o prawej ikonce

RightIconField(„uta” + BrandsxDbAdapter.getAcceptUTACards(c))

Do projektu wgrywamy ikonkę uta1.png

Układ graficzny własny … tzn. ręcznie dziergany

Zmieniamy vehicles_list.xml na:

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;

android:id=”@+id/RelativeLayout01″

android:layout_height=”wrap_content”

android:layout_width=”fill_parent”>

 

<ImageView android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:id=”@+id/lefticon”

android:visibility=”gone”></ImageView>

 

 

<TextView

android:layout_width=”wrap_content”

android:text=”TextView”

android:padding=”5dp”

android:textAppearance=”?android:attr/textAppearanceMedium”

android:layout_height=”wrap_content”

android:id=”@+id/model”

android:layout_toRightOf=”@+id/lefticon”

android:layout_alignTop=”@+id/lefticon”

android:layout_alignBottom=”@+id/lefticon”>

</TextView>

 

<TextView

android:layout_width=”wrap_content”

android:text=”TextView”

android:textAppearance=”?android:attr/textAppearanceMedium”

android:layout_height=”wrap_content”

android:id=”@+id/odmoter”

android:padding=”5dp”

android:layout_alignParentRight=”true”>

</TextView>

<TextView

android:layout_width=”wrap_content”

android:text=”TextView”

android:padding=”5dp”

android:textAppearance=”?android:attr/textAppearanceMedium”

android:layout_height=”wrap_content”

android:id=”@+id/plateno”

android:layout_centerInParent=”true”

></TextView>

 

</RelativeLayout>

W VehiclesList.java odszukujemy procedure VehiclesHolder

I zmieniamy, aby wyglądała jak poniżej

static class VehiclesHolder {

 

private TextView Odmoter = null;

private TextView Model = null;

private TextView PlateNo = null;

private ImageView LeftIcon=null; //manual

private View row=null;

VehiclesHolder(View row) {

this.row=row;

 

LeftIcon=(ImageView)row.findViewById(R.id.lefticon);

Odmoter=(TextView)row.findViewById(R.id.odmoter);

Model=(TextView)row.findViewById(R.id.model);

PlateNo=(TextView)row.findViewById(R.id.plateno);

 

}

 

void populateFrom(Cursor c) {

if (VehiclesxDbAdapter.getOdmoter(c) != null) {

Odmoter.setText(VehiclesxDbAdapter.getOdmoter(c).toString());

}

if (VehiclesxDbAdapter.getModel(c) != null) {

Model.setText(VehiclesxDbAdapter.getModel(c).toString());

}

if (VehiclesxDbAdapter.getPlateNo(c) != null) {

PlateNo.setText(VehiclesxDbAdapter.getPlateNo(c));

}

int resId;

try {

resId = R.drawable.class.getDeclaredField(„makes” + VehiclesxDbAdapter.getMake(c).toLowerCase()).getInt(null);

LeftIcon.setImageResource(resId);

LeftIcon.setVisibility(View.VISIBLE);

} catch (Exception e) {

Log.d(TAG,”ikona:” + „makes” + VehiclesxDbAdapter.getMake(c).toLowerCase());

LeftIcon.setVisibility(View.INVISIBLE);

}

}

}

Oczywiście podczas kolejnego generowaniaclarion nadpisze nam nasze zmiany. Aby temu zapobiec, zabronimy generowanie kodu listy oraz layoutu wiersza listy

FreezeListLayout(true) oraz FreezeList(true)

Posted in Android, Clarion, MOBY | Leave a Comment »