2009-12-05 35 views
5

Trong Java, bằng cách sử dụng giao diện hệ thống không mặc định, chúng tôi sẽ có sơ đồ bàn phím khác nhau.Sử dụng KeyMap mặc định của hệ điều hành gốc

Ví dụ Tôi đang sử dụng Mac OS X và sử dụng giao diện Chất (giao diện hệ thống không mặc định). Hiệu ứng là tôi mất khóa "meta" để chọn tất cả thành phần văn bản Trong mac os x nên là "meta + a", nhưng sử dụng Substance chúng ta phải sử dụng "ctrl + a" (và nhiều hơn thế nữa như "từ tiếp theo", "từ trước", "dòng kết thúc", dòng bắt đầu ", v.v.) Vì vậy, chúng tôi không có cảm giác mac OS x bằng cách sử dụng giao diện hệ thống không mặc định (Giao diện và cảm nhận chất).

có cách nào để sử dụng cái nhìn hệ thống không phải mặc định và cảm nhận nhưng hệ thống sử dụng (bản địa) keymap?

Trả lời

1

công việc xung quanh

một giải pháp ít thanh lịch, bạn có thể thử thêm trình nghe khóa để ghi đè hành vi "ctrl + a" mặc định bằng cách triển khai phương thức keyPressed (xin lưu ý rằng mẫu sau không cho phép "ctrl + a" chỉ thêm hỗ trợ cho "meta + a"):

@Override 
public void keyPressed(final KeyEvent e) { 
    // Get the default toolkit shortcut mask ("meta" for OSX). 
    int keyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); 

    // You could also check modifiers against KeyEvent.META_MASK... 
    if (e.getModifiers() == keyMask && e.getKeyCode() == KeyEvent.VK_A) { 
    // Select everything (assumes member of child text component class). 
    this.selectAll(); 

    // We handled this keystroke, 'a' will be ignored by underlying text component. 
    e.consume(); 
    } 
} 

Một giải pháp thay thế tốt hơn là sử dụng inputMaps (xem bình luận của uudashr bên dưới).


Suy nghĩ về các nguyên nhân gốc rễ

Thật không may, như tên lớp cho thấy giao diện (hoặc LAF) là sự kết hợp của sự xuất hiện tức là nhìn, cũng như "hệ thống hành vi ", tức là cảm thấy. Nếu bạn khai thác xung quanh nguồn chất, thì SubstanceLookAndFeel sẽ ghi đè số BasicLookAndFeel được vận chuyển bằng xích đu. Dường như nó nằm trong BasicLookAndFeel hành vi vi phạm được đặt trong initComponentDefaults. Bạn sẽ có thể nhận được UIDefaults từ LAF bằng cách gọi getDefaults().

vấn đề từ đây là:

  • "Hệ thống hành vi" mà bạn muốn thay đổi được xen kẽ với các thiết lập xuất hiện bạn muốn rời khỏi chạm.
  • Tôi cũng không thể tìm thấy bất kỳ cách nào dễ dàng để đưa các mặc định này vào chất ở cấp LAF ... Bất kỳ ai có ý tưởng khác về điều này?
+1

Không, đó không phải là giải pháp thanh lịch. Tôi có thể làm điều gì đó như (có thể thanh lịch hơn): InputMap inputMap = textComponent.getInputMap(); inputMap.put (KeyStroke.getKeyStroke (KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK), "none"); inputMap.put (KeyStroke.getKeyStroke (KeyEvent.VK_A, KeyEvent.META_DOWN_MASK), DefaultEditorKit.selectAllAction); "none" sẽ tắt ctrl mặc định + a. Nhưng đây không phải là điều tôi muốn. Tại sao? Bởi vì tôi phải biết tất cả các hành vi mac os x. Nếu có một cách giống như nhận được một hành vi hệ thống và cài đặt nó trên giao diện mới và cảm thấy nó sẽ là tuyệt vời. – uudashr

+0

+1 Đối với bình luận của bạn, bạn có một công việc thanh lịch hơn. Xem câu trả lời đã chỉnh sửa trên một số ý tưởng khác về nguyên nhân gốc rễ ... – Clinton

0

Một khả năng là dịch sự kiện quan trọng META thành sự kiện khóa CTRL. Vì vậy, khi người dùng trên OS X nhấn phím META, nó sẽ được dịch sang phím CTRL. Điều này sẽ hoạt động chính xác cho các phím tắt chỉ có CTRL và META được hoán đổi giữa LAF. Nếu có các combo khác phức tạp hơn, bạn luôn có thể thực hiện việc dịch và kết hợp phức tạp hơn. Mã để làm bản dịch cơ bản là dưới đây, tôi đã thử nghiệm nó với một JMenuItem với một máy gia tốc chính của CTRL + O, vì vậy bây giờ META + O kích hoạt máy gia tốc.

java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { 

      public void eventDispatched(AWTEvent event) { 
       KeyEvent kev = (KeyEvent) event; 
       if (kev.getID() == KeyEvent.KEY_PRESSED || kev.getID() == KeyEvent.KEY_RELEASED || kev.getID() == KeyEvent.KEY_PRESSED) { 
        if ((kev.getModifiersEx() & KeyEvent.META_DOWN_MASK) != 0 && !((kev.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0)) { 
         kev.consume(); // Drop the original event, this is really optional. 
         KeyEvent fake = new KeyEvent(kev.getComponent(), 
           kev.getID(), 
           kev.getWhen(), 
           (kev.getModifiersEx() & ~KeyEvent.META_DOWN_MASK) | KeyEvent.CTRL_DOWN_MASK, 
           kev.getKeyCode(), kev.getKeyChar()); 
         java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(fake); 
        } 
       } 
      } 
     }, KeyEvent.KEY_EVENT_MASK); 

Thao tác này sẽ cài đặt AWTEventListener trên hàng đợi AWTEvent và sẽ ảnh hưởng đến tất cả các sự kiện chính.

Các vấn đề liên quan