Wątki - Symulacja klawiatury telefonu komórkowego

0

Witam!

Chciałbym prosić o pomoc przy programie, którego dane wejściowe mają być wprowadzane poprzez klawiaturę znaną z telefonów komórkowych: po 3-4 literki na klawisz, wielokrotne wciskanie klawisza pozwala wybrać literę.

Moja idea jest prosta - wciskanie klawiszy wyłapywane przez actionlistenera ma zmieniać zawartość jakiejś zmiennej typu char. Ta z kolei ma być po opóźnieniu x=3sek. dopisywana do innej zmiennej (stringa). Dodatkowo każde wciśnięcie klawisza powoduje nadpisanie opóźnienia do 3 sekund.

Podstawowy problem to wspomniane opóźnienie, które umożliwia wybranie jednej z 3-4 liter. Sama operacja prezentowania kolejnych znaków jest prosta (zmienna char ++, ogranicznik). Z moich przemyśleń: pierwsze wciśnięcie klawisza powinno wywoływać wątek opóźnionego kopiowania, ale kolejne wciśnięcia (tego samego klawisza) powinny nadpisywać czas opóźnienia, albo niszczyć trwający wątek i rozpoczynać nowy. Niestety żadnego z tych pomysłów nie udało mi się skutecznie zrealizować - prosiłbym o pomoc w tej materii. A może jest dużo prostszy sposób rozwiązania tego zagadnienia?

Pozdrawiam

0

Przy wejściu do listenera zapisz bieżący czas (najlepiej nanoTime bo nie wpływają na niego zmiany zegara systemowego) i porównaj z takim samym czasem wprowadzonym podczas poprzedniego wejścia do listenera i zapisanego w polu obiektu.

  1. Jeżeli różnica tego czasu jest niższa niż ustalony przez Ciebie limit, to modyfikujesz poprzednio wprowadzony i zapisany w polu obiektu znak zgodnie z przynależnością znaku do konkretnego klawisza. Poszczególne kody fizycznych klawiszy musisz sobie zapisać jako tablice kodów znaków - zwykle odpowiadają one kodom ASCII, ale tylko dla znaków alfanumerycznych.
    1a. Jeżeli nowy znak należy do tej samej sekwencji jakiegoś klawisza, to zmieniasz zapisany znak na kolejny z tej samej sekwencji (lub po dojściu do końca na pierwszy - to jest pętla),
    1b. a jeżeli z innej sekwencji, to traktujesz go jak by czas został przekroczony, co jest opisane dalej ( przeskakujesz do pkt. 2).
    Na koniec ustalasz kolejny znak w sekwencji i ten znak staje się znakiem bieżącym i zapisywanym w polu obiektu wraz z czasem, który został odczytany przy wejściu do listenera.

  2. Jeżeli różnica czasu jest wyższa, to znaczy, że poprzednio zapisany w obiekcie znak stał się znakiem utrwalonym, a więc należy go potraktować jako znak wprowadzony (w telefonie kursor przesunie się na następną pozycję). Od tego momentu należy zresetować zapisane pole znaku oraz czas do wartości początkowych takie jak wprowadzone w konstruktorze.
    A w nim należy ustalić wartości niemożliwe do wprowadzenia takie jak znak, którego kod nigdy nie znajdzie się w buforze klawiatury oraz czas o nieużytecznej wartości takiej jak zero lub liczba ujemna. Dzięki temu możesz rozpoznać, że jednoznakowy bufor klawiatury jest pusty, a czas nie jest jeszcze liczony. W takiej sytuacji wciśnięty kod klawisza będzie zawsze identyfikował pierwszy znak z sekwencji przypisanej do niego. Zamiast kombinować ze specjalnymi wartościami znaku i czasu (wartownikami) możesz posłużyć się obiektami Character i Long, dzięki czemu ich niewłaściwą (nie wprowadzoną) wartość może identyfikować po prostu null. Jednak jak w przypadku każdego obiektu wymaga to posłużenia się stertą, co w przypadku niektórych środowisk Java nie musi być korzystne (fragmentacja sterty w przypadku wielowątkowości) lub ideologicznie poprawne (użycie sterty do tak banalnego problemu), ale na pewno jest wystarczająco szybkie.

Jest jeszcze drobny problem "ostatniego znaku" chodzi o to, że ostatni znak wciąż będzie leżał sobie w polu obiektu czekając wciąż na kolejne wywołanie listenera, które wcale nie musi nastąpić zanim pojawi się żądanie odczytania całego wprowadzonego tekstu. W takim wypadku metoda taka jak get musi po prostu sprawdzać limit czasu i w przypadku jego przekroczenia przenosić kod znaku z pola do miejsca gdzie powinien znajdować się ostatni wprowadzony znak (oraz resetować obiekt jak w punkcie 2). Dlatego ta operacja powinna być wspólną prywatną metodą zarówno dla get jak i dla metody obsługi klawiszy listenera.

To powinno wystarczyć, żebyś sobie sklecił poprawny kod.
Jak widać nie potrzeba do tego żadnych nowych wątków poza normalnym wątkiem obsługi zdarzeń.

1 użytkowników online, w tym zalogowanych: 0, gości: 1