Metoda na "wyjątkowość" skrótu klawiszowego

0

Hej,

Znacie może jakiś elegancki i wydajny sposób na obsługę skrótów klawiszowych? Chodzi mi o to, że mam X opcji, gdzie każda może zostać uruchomiona poprzez kombinację [ALT / CTRL / SHIFT] + [litery alfabetu oraz cyfry], np. opcjaPierwsza = ALT + A, opcjaDruga = CTRL + T itd. Szukam sposobu na niemożliwość powtarzania się kombinacji klawiszy dla różnych opcji. Samo sprawdzenie może nastąpić dopiero przy zatwierdzaniu ustawień.

Załóżmy że mam sobie takie menu i w nim ustawiam konkretne skróty:
Problem.jpg

Będę wdzięczny za porady!

Pozdrawiam serdecznie.

0

Znacie może jakiś elegancki i wydajny sposób na obsługę skrótów klawiszowych?

Szukam sposobu na niemożliwość powtarzania się kombinacji klawiszy dla różnych opcji

Nie dość że pytasz o jedno, a piszesz o drugim, to jeszcze sam sobie przeczysz...

Samo sprawdzenie może nastąpić dopiero przy zatwierdzaniu ustawień.

Skoro sprawdzanie ma się odbywać tylko po wciśnięciu przycisku do zapisu ustawień, to jak chcesz sprawdzać czy kombinacja jest zajęta podczas jej wyboru?

To już lepiej sprawdzać na bieżąco podczas ustawiania, a przy zapisie nie (bo wtedy już nie trzeba).

0
furious programming napisał(a):

Nie dość że pytasz o jedno, a piszesz o drugim, to jeszcze sam sobie przeczysz...

Ja nie widzę żadnej rozbieżności w swoich słowach. Zapytałem o dobry sposób na obsługę skrótów klawiszowych, który uwzględniałby niemożliwość powtarzania się danych kombinacji. Gdzie tu jakiekolwiek zaprzeczanie swoim własnym słowom?

Skoro sprawdzanie ma się odbywać tylko po wciśnięciu przycisku do zapisu ustawień, to jak chcesz sprawdzać czy kombinacja jest zajęta podczas jej wyboru?

Dlatego też pytam, czy jest jakiś elegancki sposób, by to osiągnąć, a jeżeli takowy nie istnieje dla pojedynczej akcji przycisku, to czy da się osiągnąć wydajną weryfikację kombinacji inną drogą.

To już lepiej sprawdzać na bieżąco podczas ustawiania, a przy zapisie nie (bo wtedy już nie trzeba).

Tak, wiem. Dlatego pytam o "elegancki" np. na to sposób.

1

Gdzie tu jakiekolwiek zaprzeczanie swoim własnym słowom?

Uczepiłem się (przyznaję), jednak napisałeś o dwóch różnych rzeczach - zabezpieczenie przed ustawieniem jednego skrótu dla dwóch funkcji to jedno, a obsługa skrótów to drugie - obsługa (jak sama nazwa wskazuje) to przyporządkowanie danej funkcji (ogólnie algorytmu) do jakiegoś skrótu i po jego zaistnieniu wykonanie tego kodu; Nijak ma się to do Twojego problemu;

Nie piszę w Javie, jednak w OP obsługę skrótów klawiszowych (nie licząc komponentów z właściwością np. Shortcut jak w TMenuItem) należałoby zaimplementować w zdarzeniu np. OnKeyDown formularza, a sprawdzenie poprawności ustawień wykonać np. w zdarzeniu OnChange komponentu TComboBox - jak widzisz to dwie zupełnie różne rzeczy;


Dlatego też pytam, czy jest jakiś elegancki sposób, by to osiągnąć, a jeżeli takowy nie istnieje dla pojedynczej akcji przycisku, to czy da się osiągnąć wydajną weryfikację kombinacji inną drogą.

Sprawdzić czy dana kombinacja jest już do jakiejś funkcji przyporządkowana i tak musisz (co najmniej raz) - czy to przy wybieraniu danej kombinacji, czy przy zapisie; Wszystko zależy od tego jaki efekt Cię interesuje;

  1. Jeśli użytkownik może ustawić (dajesz mu taką możliwość) taką samą kombinację dla więcej niż jednej funkcji to przy zapisie musisz sprawdzić czy jest wszystko w porządku i jeśli nie - wyświetlić komunikat żeby usunął powtórzenia; Sprawdzasz raz po skończeniu ustawiania;

  2. Jeśli użytkownik nie może wybrać (przed zapisem ustawień) dwa razy tej samej kombinacji to przy każdej zmianie pozycji w każdej kontrolce msusisz sprawdzić czy są powtórzenia i jeśli tak - komunikat + przywrócenie poprzedniej pozycji w tej kontrolce; Przy zapisie już sprawdzać nie trzeba, bo cokolwiek by użytkownik nie nawydziwiał to poprawność była sprawdzana na bieżąco;

Podsumowując - albo sprawdzasz na bieżąco i informujesz jeśli jest jakieś powtórzenie (wtedy użytkownik od razu wie, że coś jest nie tak), albo informujesz go tylko przy zapisie ustawień (i tym samym pozwalasz mu tracić czas myśląc, że wszystko ustawił jak należy);

Pierwsza opcja jest na pewno szybsza, bo sprawdzenie poprawności wykonujesz raz, ale użytkownik może się denerwować, że jak wybierał dubla to mu program nie podpowiedział, że dana kombinacja jest już zarezerwowana; Druga opcja jest wolniejsza, bo sprawdza poprawność przy każdej zmianie pozycji każdej kontrolki, za to użytkownik od razu wie czy ustawił dobrze, czy nie; Jednak przy tak małej ilości kombinacji wolałbym wybrać opcję drugą, by użytkownik był informowany na bieżaco o błędnej konfiguracji.

0

W skrocie:

var NowaKombinacja;
foreach(Kombinacja in Kombinacje) {
  if(NowaKombinacja == Kombinacja) {
    throw("jestes za glupi na ustawienie skrotow, rotfl");
  }
}

Chyba, ze Kombinacje.Size > {bardzo duza liczba}, wtedy zlozonosc o(n) moze byc problematyczna w real-time.

0
  1. zazwyczaj sprawdzanie odbywa się w momencie przypisania. Dlaczego? Bo można wtedy po prostu zapytać czy chcesz przypisać kombinacje aktualnej akcji i wyzerować "starej" czy zostawić ze "starą"
  2. taki sposób przypisywania skrótu nie jest zbyt dobry - nie można przypisać skrótów jedno lub np. trzy znakowych
0

Dziękuję bardzo wszystkim za odpowiedzi :) Piszę od 6 rano i chyba po prostu już wyczerpałem neuroprzekaźniki pod pajęczynówką... W każdym razie znalazłem rozwiązanie :) Śmiga, aż miło. Zrobiłem to tak:

  1. Podzieliłem comboboxy na dwie grupy - na te z [alt, ctrl, shift] oraz te z [literami i cyframi].
  2. Następnie dla każdej z tych grup napisałem po jednej metodzie, w której parametrze przekazuję indeks wybranego elementu z danego comboxa, a wartością którą zwracają owe metody są wartości true, lub false.
  3. Tak więc pod każdym comboxem dodałem actionListenera i utworzyłem w metodzie actionPerformed dwa obiekty logiczne, do których przypisuję wyniki każdej z w/w metod.
  4. Na koniec jedna zagnieżdżona krótka instrukcja "if" i tyle :)

Poniżej prezentuję krótkie zastosowanie w kodzie:

/*
* METODA DLA LITER I CYFR
*/
public boolean isAlreadyKeyEvent(int index) {

     int vector[] = {comboTXT_2.getSelectedIndex(), comboDROP_2.getSelectedIndex(),      comboREFRESH_2.getSelectedIndex(), 
          comboSCROLL_2.getSelectedIndex(), comboLOCK_2.getSelectedIndex(), comboSET_2.getSelectedIndex(),
          comboCOPY_2.getSelectedIndex(), comboDELETE_2.getSelectedIndex(), comboCLEAR_2.getSelectedIndex()};

     int x = 0;

     for (int i : vector) {
          if (i == index) {
               x++;
          }
     }

     if (x > 1) {
          return true;
     } else {
          return false;
     }
}

/*
* METODA DLA ALT, CTRL, SHIFT
*/
public boolean isAlreadyInputEvent(int index) {
          
     int vector[] = {comboTXT_1.getSelectedIndex(), comboDROP_1.getSelectedIndex(), comboREFRESH_1.getSelectedIndex(), 
          comboSCROLL_1.getSelectedIndex(), comboLOCK_1.getSelectedIndex(), comboSET_1.getSelectedIndex(),
          comboCOPY_1.getSelectedIndex(), comboDELETE_1.getSelectedIndex(), comboCLEAR_1.getSelectedIndex()};
          
     int x = 0;
          
     for (int i : vector) {
          if (i == index) {
               x++;
          }
     }
          
     if (x > 1) {
          return true;
     } else {
          return false;
     }
}

/*
* Przykład na konkretnym JComboBoxie
*/
comboTXT_2.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
                    
          // Wywołanie metody dla JComboBoxa zawierającego litery i znaki
          boolean one = isAlreadyKeyEvent(comboTXT_2.getSelectedIndex());
                    
          // Wywołanie metody dla JComboBoxa zawierającego Alt, Ctrl i Shift
          boolean two = isAlreadyInputEvent(comboTXT_1.getSelectedIndex());
                    
          if (one) {
               if (two) {
                    JOptionPane.showMessageDialog(null, "Such shortcut already exists! \n" + 
               "Choose something else.");
                              
                    // Jeżeli wybrana przez użytkownika kombinacja już istnieje,
                    // to ustawiana jest wcześniejsza wartość JComboBox'a.
                    // Klasa SettingsSave zawiera aktualizowane dane.
                    comboTXT_2.setSelectedIndex(SettingsSave.TXT_COMBO_2);
               } else {
                    SettingsSave.TXT_COMBO_2 = comboTXT_2.getSelectedIndex();
               }
          } else {
               SettingsSave.TXT_COMBO_2 = comboTXT_2.getSelectedIndex();
          }     
     }
});

Jeszcze raz dzięki za pomoc i pobudzenie połamanego już umysłu :P

Pozdrawiam ciepło! ^^

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