package inputreading;
import java.util.Date;
import java.util.Random;
import java.util.Scanner;
public class InputReading {
public static void main(String[] args) {
// billentyűzet scanner
Scanner kbd = new Scanner(System.in);
char cAnswer;
int iTip;
boolean bEnd;
Date dtStart;
Date dtEnd;
do {
dtStart = new Date();
int iTryCnt = 0;
// feladvány előállítása
int iNum = new Random().nextInt(10) + 1;
do {
System.out.println(++iTryCnt + ". kísérlet");
System.out.print("Írd be a tippet: ");
// int szám beolvasása a konzolról
iTip = kbd.nextInt();
} while (iTip != iNum);
dtEnd = new Date();
Double dDifference = (dtEnd.getTime() - dtStart.getTime()) / 1000.0;
System.out.println(dDifference + " másodperc alatt találtad ki a feladványt");
System.out.println(iTryCnt + " lépésből találtad ki a számot");
System.out.println("");
do {
System.out.println("Akarsz újra játszani? (i/n)");
cAnswer = Character.toLowerCase(kbd.findWithinHorizon(".", 0).charAt(0));
} while (cAnswer != 'i' && cAnswer != 'n');
bEnd = (cAnswer == 'n');
// ismételd addig, amíg bEnd true nem lesz
} while (!bEnd);
}
}
Oldalak
2012. augusztus 7., kedd
Egyszerű "kitalálós" játék
Ez az egyszerű játék igazából a konzolról történő beolvasást demonstrálja. A példában kétféle beolvasási mód van: az egyik egy int szám beolvasása kbd.nextInt(), a másik egyetlen karakter beolvasása a konzolról kbd.findWithinHorizon(".", 0).charAt(0). Ezen kívül természetesen a Scanner osztálynak még számos más metódusa létezik.
2012. augusztus 1., szerda
Form TopMost tulajdonságának beállítása
Néha szükség lehet arra, hogy egyes ablakok mindig legfelül "topmost" módon jelenjenek meg. Ezt egy egyszerű WinAPI trükkel lehet megoldani (persze létezik erre más módszer is).
procedure TfrmDlgCommonSyncProgress.FormShow(Sender: TObject);
begin
SetWindowPos(
Self.Handle,
HWND_TOPMOST,
0,
0,
0,
0,
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;
Persze ugyanezt a hatást lehet elérni, ha az adott form CreateParams metódusának felülírásával is.
Flyweight minta alkalmazása
A Flyweight (pehelysúlyú) szerkezeti objektum minta megvalósítása Delphi alatt. Ezt a mintát valósítja meg a TCollection és TCollectionItem osztály. Ezt a gyakorlatban olyan esetekben szoktam használni, amikor dinamikusan összetett adatokat kell kezelni és a hagyományos tömb szerkezet ehhez nem nyújt kellő rugalmasságot.
A TCollection és TCollectionItem osztályokból származtatott saját konténer osztályok alkalmazásával ki lehet aknázni az OOP által nyújtott előnyöket mint például a kollekcióba szervezett adatok belső integritásának védelme, vagy az adatok állapot változásának esemény kezelése saját eseménykezelők használatával (pl. ha a kollekcióban egy elem állapota megváltozik, akkor egy eseménykezelőben kezelni lehessen a bekövetkezett változásokat).
A Flyweight minta megvalósítása örökléssel a TCollection és TCollectionItem osztályokból (ez csak egy kód csontváz, amit igazából az adott célnak megfelelően kell elkészíteni, kiegészíteni a feladathoz leginkább illeszkedő mezőkkel, metódusokkal) Kollekció elem csontváz osztály interface része:
A TCollection és TCollectionItem osztályokból származtatott saját konténer osztályok alkalmazásával ki lehet aknázni az OOP által nyújtott előnyöket mint például a kollekcióba szervezett adatok belső integritásának védelme, vagy az adatok állapot változásának esemény kezelése saját eseménykezelők használatával (pl. ha a kollekcióban egy elem állapota megváltozik, akkor egy eseménykezelőben kezelni lehessen a bekövetkezett változásokat).
A Flyweight minta megvalósítása örökléssel a TCollection és TCollectionItem osztályokból (ez csak egy kód csontváz, amit igazából az adott célnak megfelelően kell elkészíteni, kiegészíteni a feladathoz leginkább illeszkedő mezőkkel, metódusokkal) Kollekció elem csontváz osztály interface része:
interface
uses
Classes, ...;
type
TMyCustomDataItem = class(TCollectionItem)
private
// itt kell definiálni azokat a mezők tároló változóit,
// amit majd a külvilág felé publikálni szeretnénk tulajdonságokon
// keresztül
FMyIntField : Integer;
FMyStringField : String;
...
public
constructor Create(Collection: TCollection); override;
...
property MyIntField : Integer read FMyIntField write FMyIntField;
property MyStringField : String read FMyStringField write FMyStringField;
...
end;
A kollekció elem publikált mezőihez lehet getter/setter metódusokat definiálni, ezt a konkrét feladat dönti el, hogy mire van szükségünk. Ha például eseményt szeretnénk kiváltani, ha egy elemnek (TCollectionItem) megváltozik a belső állapota, akkor a figyelni kívánt tulajdonság setter metódusát kell "felokosítani" erre a feladatra, hogy az állapot változásról értesítse ki a kollekciót kezelő objektumot (TCollection).
Kollekció csontváz osztály interface része:
...
TMyCustomDataCollection = class(TCollection)
private
function GetMyCustomDataItem(Index : Integer) : TMyCustomDataItem;
procedure SetMyCustomDataItem(Index : Integer;
const Value : TMyCustomDataItem);
public
destructor Destroy; override;
function Add : TMyCustomDataItem; overload;
function Add(AMyInt : Integer; AMyString : String) : TMyCustomDataItem; overload;
procedure DeleteAll;
procedure OrderByMyIntField;
property Items[Index : Integer] : TMyCustomDataItem read GetMyCustomDataItem
write SetMyCustomDataItem;
end;
A fenti példában a TMyCustomDataCollection osztályt felruházom rendezés funkcióval, ami a MyIntField mező szerint fogja a kollekcióban az elemeket sorba rendezni, az összes elem törlése funkció, egyedi adatokkal történő a adat inicializálás Add(1, 'MyString').
TMyCustomDataItem osztály implementációs csontváza:
...
implementation
{ TMyCustomDataItem }
constructor TMyCustomDataItem.Create(Collection: TCollection);
begin
inherited Create(Collection);
FMyIntField := $F0F0;
FMyStringField := '';
..
// további inicializáló utasítások
end;
TMyCustomDataCollection kollekció implementációs csontváza:
{ TMyCustomDataCollection }
destructor TMyCustomDataCollection.Destroy;
begin
DeleteAll;
inherited Destroy;
end;
function TMyCustomDataCollection.Add: TMyCustomDataItem;
begin
Result := inherited Add as TMyCustomDataItem;
end;
function TMyCustomDataCollection.Add(AMyInt : Integer; AMyString : String): TMyCustomDataItem;
begin
Result := inherited Add as TMyCustomDataItem;
Result.MyIntField := AMyInt;
Result.MyStringField := AMyString;
..
// további értékadó utasítások
end;
procedure TMyCustomDataCollection.DeleteAll;
begin
while (Self.Count > 0) do
Self.Delete(0);
end;
function TMyCustomDataCollection.GetMyCustomDataItem(Index: Integer): TMyCustomDataItem;
begin
Result := inherited Items[Index] as TMyCustomDataItem;
end;
procedure TMyCustomDataCollection.SetMyCustomDataItem(Index: Integer;
const Value: TMyCustomDataItem);
begin
inherited Items[Index] := Value;
end;
procedure TMyCustomDataCollection.OrderBySessionNum;
var
iIndex : Integer;
iIndex2 : Integer;
pMinItem : TMyCustomDataItem;
pCurrItem : TMyCustomDataItem;
begin
// elemek rendezése FMyInt szám szerint növekvő sorrendben
// a min sort algoritmusnál van gyorsabb rendezés is ;)
for iIndex := 0 to Self.Count - 1 do
begin
pMinItem := Self.Items[iIndex];
for iIndex2 := iIndex to Self.Count - 1 do
begin
pCurrItem := Self.Items[iIndex2];
if pCurrItem.SessionNum < pMinItem.SessionNum then
begin
pCurrItem.Index := pMinItem.Index;
pMinItem := pCurrItem;
end;
end;
end;
end;
A fenti csontvázak alapján a saját igényeknek megfelelően kell tovább bővíteni a kollekció és kollekció elem osztályokat.
String írása/olvasása TMemoryStream-el
Az alábbi snipet egy String tartalmának írását olvasását szemlélteti egy TMemoryStream-ben. Ez nagyon hasznos tud lenni, ha nem akarunk tömbökkel bűvészkedni. Az alábbi kód töredéket gyakran szoktam használni.
procedure TForm1.btnStreamRWTestClick(Sender: TObject);
var
msStream : TMemoryStream;
sData : String;
begin
sData := 'Ez egy tesz szöveg';
msStream := TMemoryStream.Create;
try
msStream.Clear;
// sData tartalmának kiírása az msStream MemoryStream-be
msStream.WriteBuffer(Pointer(sData)^, Length(sData));
sData := 'alma';
// msStream tartalmának visszaolvasása a sData String-be
// sData méret beállítása !!!
SetLength(sData, msStream.Size);
// SData tartalmának "nullázása"
FillChar(sData[1], msStream.Size, 0);
// pozicionálás a MemoryStream elejére olvasás előtt
msStream.Position := 0;
msStream.ReadBuffer(Pointer(sData)^, msStream.Size);
finally
if Assigned(msStream) then
begin
msStream.Clear;
msStream.Free;
end;
end;
end;
Feliratkozás:
Megjegyzések (Atom)