2013-09-03 2 views
4

핫키 바로 가기를 구성하려는 테이블을 만들고 싶습니다. 키를 찾는 방법

나는이 간단한 테이블이 :

public static final String Column1MapKey = "A"; 
    public static final String Column2MapKey = "B"; 

    private ObservableList<Map> generateDataInMap() { 
     int max = 110; 
     ObservableList<Map> allData = FXCollections.observableArrayList(); 
     for (int i = 1; i < max; i++) { 
      Map<String, String> dataRow = new HashMap<>(); 

      String value1 = "A" + i; 
      String value2 = "B" + i; 

      dataRow.put(Column1MapKey, value1); 
      dataRow.put(Column2MapKey, value2); 

      allData.add(dataRow); 
     } 
     return allData; 
    } 

public TabPane hotKeysContent(){ 

     TableColumn<Map, String> firstDataColumn = new TableColumn<>("Actions"); 
     TableColumn<Map, String> secondDataColumn = new TableColumn<>("Shortcut"); 

     firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey)); 
     firstDataColumn.setMinWidth(230); 
     secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey)); 
     secondDataColumn.setMinWidth(230); 

     TableView table_view = new TableView<>(generateDataInMap()); 
     table_view.setPadding(new Insets(5, 5, 5, 5)); 

     table_view.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); // Autoresize when window size is changed 

     table_view.setEditable(true); 
     table_view.getSelectionModel().setCellSelectionEnabled(true); 
     table_view.getColumns().setAll(firstDataColumn, secondDataColumn); 
     Callback<TableColumn<Map, String>, TableCell<Map, String>> 
      cellFactoryForMap = new Callback<TableColumn<Map, String>, 
       TableCell<Map, String>>() { 
        @Override 
        public TableCell call(TableColumn p) { 
         return new TextFieldTableCell(new StringConverter() { 
          @Override 
          public String toString(Object t) { 
           return t.toString(); 
          } 
          @Override 
          public Object fromString(String string) { 
           return string; 
          }          
         }); 
        } 
     }; 
     firstDataColumn.setCellFactory(cellFactoryForMap); 
     secondDataColumn.setCellFactory(cellFactoryForMap); 

     return null; 
    } 

내가 누를하고 나중에 키보드 단축키를 활성화하려면이 키를 사용하여 키의 조합을 얻기 위해 두 번째 열에 행을 클릭하면 내가 원하는. 모든 예제가 도움이 될 것입니다. 명령과

P.S 테이블 : 더있는 tableView없는 열 또는 셀이 없지만 아래

public static final String Column1MapKey = "A"; 
    public static final String Column2MapKey = "B"; 

    private ObservableList<Map> generateDataInMap() { 
     int max = 110; 
     ObservableList<Map> allData = FXCollections.observableArrayList(); 
     for (int i = 1; i < max; i++) { 
      Map<String, String> dataRow = new HashMap<>(); 

      String value1 = "A" + i; 
      String value2 = "B" + i; 

      dataRow.put(Column1MapKey, value1); 
      dataRow.put(Column2MapKey, value2); 

      allData.add(dataRow); 
     } 
     return allData; 
    } 

    public TabPane hotKeysContent(){ 

     TabPane tabPane = new TabPane(); 
     //tabPane.setStyle("-fx-font-size: 13pt;"); // Set size of the tab name 

     Tab tabA = new Tab(); 
     Label tabALabel = new Label("Shortcuts"); 
     //tabALabel.setStyle("-fx-font-size: 12pt;"); // Set size of the tab name 
     tabA.setGraphic(tabALabel); 
     tabA.setClosable(false); // da se mahne opciqta da se zatvarq tab 


     TableColumn<Map, String> firstDataColumn = new TableColumn<>("Actions"); 
     TableColumn<Map, String> secondDataColumn = new TableColumn<>("Shortcut"); 

     firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey)); 
     firstDataColumn.setMinWidth(230); 
     secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey)); 
     secondDataColumn.setMinWidth(230); 

     TableView table_view = new TableView<>(generateDataInMap()); 
     table_view.setPadding(new Insets(5, 5, 5, 5)); 

     table_view.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); // Autoresize when window size is changed 

     table_view.setEditable(true); 
     table_view.getSelectionModel().setCellSelectionEnabled(true); 
     table_view.getColumns().setAll(firstDataColumn, secondDataColumn); 
     Callback<TableColumn<Map, String>, TableCell<Map, String>> 
      cellFactoryForMap = new Callback<TableColumn<Map, String>, 
       TableCell<Map, String>>() { 
        @Override 
        public TableCell call(TableColumn p) { 
         return new TextFieldTableCell(new StringConverter() { 
          @Override 
          public String toString(Object t) { 
           return t.toString(); 
          } 
          @Override 
          public Object fromString(String string) { 
           return string; 
          }          
         }); 
        } 
     }; 
     firstDataColumn.setCellFactory(cellFactoryForMap); 
     secondDataColumn.setCellFactory(cellFactoryForMap); 

     tabA.setContent(table_view);     
     tabPane.getTabs().add(tabA);  

     return tabPane; 
    } 

답변

8

는 SSCCE입니다. 그러나 논리는 비슷합니다. 필요에 따라 단서를 검토하고 자신의 코드를 작성 : 작동 원리

public class ShortCutDemo extends Application { 

    private KeyEvent shortcutKeyEvent; 
    private EventHandler selectedEventHandler; 
    private List<EventHandler> eventHandlers; 
    private HBox root; 

    @Override 
    public void start(Stage primaryStage) { 

     root = new HBox(10); 
     root.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent event) { 
       // Do not filter for TextFields 
       if (event.getTarget() instanceof TextField) { 
        return; 
       } 
       if (isKeyEventsAreEqual(event, shortcutKeyEvent)) { 
        // then apply shortcut event 
        selectedEventHandler.handle(null); 
        event.consume(); 
       } 
      } 
     }); 

     eventHandlers = new ArrayList<EventHandler>(); 
     eventHandlers.add(new EventHandler() { 
      @Override 
      public void handle(Event event) { 
       root.setStyle("-fx-background-color: lightgray"); 
      } 
     }); 

     eventHandlers.add(new EventHandler() { 
      @Override 
      public void handle(Event event) { 
       root.setSpacing(50); 
      } 
     }); 

     ChoiceBox cb = new ChoiceBox(); 
     cb.getItems().addAll("HBox background = gray", "HBox spacing = 50"); 
     cb.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() { 
      @Override 
      public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
       selectedEventHandler = eventHandlers.get(newValue.intValue()); 
      } 
     }); 
     cb.getSelectionModel().selectFirst(); // default value 

     final TextField textField = new TextField(); 
     textField.setEditable(false); 

     textField.setOnKeyPressed(new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent event) { 
       if (event.getCode() == KeyCode.TAB) { 
//     Platform.runLater(new Runnable() { 
//      @Override 
//      public void run() { 
//       root.requestFocus(); 
//      } 
//     }); 
       } else { 
        // Clear the previous text 
        textField.setText(""); 
        // Process only desired key types 
        if (event.getCode().isLetterKey() 
          || event.getCode().isDigitKey() 
          || event.getCode().isFunctionKey()) { 
         String shortcut = event.getCode().getName(); 
         if (event.isAltDown()) { 
          shortcut = "Alt + " + shortcut; 
         } 
         if (event.isControlDown()) { 
          shortcut = "Ctrl + " + shortcut; 
         } 
         if (event.isShiftDown()) { 
          shortcut = "Shift + " + shortcut; 
         } 
         textField.setText(shortcut); 
         shortcutKeyEvent = event; 
        } else { 
         shortcutKeyEvent = null; 
        } 
       } 
      } 
     }); 

     Button button = new Button("Reset"); 
     button.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       textField.setText(""); 
       root.setSpacing(10); 
       root.setStyle("-fx-background-color: white"); 
       shortcutKeyEvent = null; 
      } 
     }); 

     root.getChildren().addAll(new Label("Define a shortcut for "), cb, textField, button); 
     Scene scene = new Scene(root, 900, 150); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private boolean isKeyEventsAreEqual(KeyEvent event1, KeyEvent event2) { 
     return event1 != null 
       && event2 != null 
       && event1.getCode() == event2.getCode() 
       && event1.isAltDown() == event2.isAltDown() 
       && event1.isControlDown() == event2.isControlDown() 
       && event1.isShiftDown() == event2.isShiftDown(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

를?
1) 선택 상자에서 조치 (이벤트) 유형을 선택하십시오.
2) 텍스트 필드에 초점을 맞추고 원하는 바로 가기를 입력하십시오 (예 : ). + 예 :
3) 을 눌러 TextField에서 초점을 맞 춥니 다.
4)을 눌러 바로 가기 (Alt 키이 경우 + F1)는 다시 행동에 이벤트를 볼 수 있습니다.
5) "초기화"버튼을 눌러 상태를 확실하게 초기화하십시오.

추가 개선 사항은 ShortCut 키가있는 모델 클래스를 정의하고, Ctrl, Alt 및 Shift의 불린, 이벤트 처리기를 처리하고 적절하게 equals(...) 메서드를 재정의해야합니다.

+0

? 나는 어느 것이 눌러 졌는지 감지하는 방법이 있습니까? –

+0

@PeterPenzov, afaik no. 기능 요청으로 등록 할 수 있습니다. –

+0

한 가지 더 물어보고 싶습니다. 나는 당신이 대답으로 쓴 코드를 사용하고 싶다. 위에서 추가 한 테이블에 코드를 구현하기 위해 테스트했지만 성공하지는 못했습니다. 그것은 귀하의 코드와 함께 사용하기 위해 테이블을 재 설계해야하는 것 같습니다. 코드를 편집하고 이벤트 리스너를 테이블에 추가하십시오. 두 번째 열을 클릭하여 키 조합을 입력하면됩니다. –

1

다음은 시작해야 할 항목입니다. 간단히하기 위해 Ctrl 키와 Alt 키와 단 하나의 열만 처리했지만 계속 진행하는 방법은 분명합니다. 내 접근 방식은 키 바로 가기를 수신하고이를 KeyCharacterCombination으로 변환하는 사용자 지정 onKeyPressed 수신기와 함께 TextFieldTableCell을 사용하는 것이 었습니다.

이 예제는 그다지 완전하지 않거나 강력하지 않습니다. 예를 들어, 단일 문자는 제대로 처리되지 않습니다. 표준 바로 가기 (Ctrl-C, Ctrl-V 등)는 무시되지 않습니다. 자신 만의 TableCell 클래스를 구현해야하므로 입력 된 텍스트를 완전히 제어 할 수 있습니다. 지금까지 내가 거기에 바로 Ctrl 키 사이의 예에 차이가 없으며, Ctrl 키를 왼쪽 볼 수 그런데

public class KeyCombinationTableExample extends Application { 

    public static void main(String[] args) { 
     launch(KeyCombinationTableExample.class); 
    } 

    @Override 
    public void start(Stage stage) throws Exception { 
     final ObservableList<KeyCharacterCombination> items = FXCollections.observableArrayList(); 
     for (int i = 0; i < 110; i++) { 
      items.add(null); 
     } 
     TableView<KeyCharacterCombination> table = new TableView<>(items); 
     table.setEditable(true); 
     final TableColumn<KeyCharacterCombination, KeyCharacterCombination> column = new TableColumn<>(); 
     column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<KeyCharacterCombination, KeyCharacterCombination>, ObservableValue<KeyCharacterCombination>>() { 
             @Override 
             public ObservableValue<KeyCharacterCombination> call(TableColumn.CellDataFeatures<KeyCharacterCombination, KeyCharacterCombination> cellDataFeatures) { 
       return new ReadOnlyObjectWrapper<>(cellDataFeatures.getValue()); 
     } 
     }); 
     column.setCellFactory(new Callback<TableColumn<KeyCharacterCombination, KeyCharacterCombination>, TableCell<KeyCharacterCombination, KeyCharacterCombination>>() { 
            @Override 
            public TableCell<KeyCharacterCombination, KeyCharacterCombination> call(TableColumn<KeyCharacterCombination, KeyCharacterCombination> tableColumn) { 
       final TableCell<KeyCharacterCombination, KeyCharacterCombination> cell = new TextFieldTableCell<KeyCharacterCombination, KeyCharacterCombination>() { 
        @Override 
        public void updateItem(KeyCharacterCombination keyCharacterCombination, boolean b) { 
         super.updateItem(keyCharacterCombination, b); 
         if (this.getItem() == null || b) { 
          setText(null); 
         } else { 
          StringBuilder sb = new StringBuilder(); 
          if (keyCharacterCombination.getControl() == KeyCombination.ModifierValue.DOWN) { 
           sb.append("Ctrl + "); 
          } 
          if (keyCharacterCombination.getAlt() == KeyCombination.ModifierValue.DOWN) { 
           sb.append("Alt + "); 
          } 
          sb.append(keyCharacterCombination.getCharacter()); 
          setText(sb.toString()); 
         } 
        } 
       }; 
       cell.setOnKeyPressed(new EventHandler<KeyEvent>() { 
        Set<KeyCombination.Modifier> keys = new HashSet<>(); 

        @Override 
        public void handle(KeyEvent keyEvent) { 
         if (keyEvent.getCode() == KeyCode.CONTROL) { 
          keys.add(KeyCombination.CONTROL_DOWN); 
         } else if (keyEvent.getCode() == KeyCode.ALT) { 
          keys.add(KeyCombination.ALT_DOWN); 
         } else if (keyEvent.getCode().isLetterKey()) { 
          items.set(cell.getIndex(), new KeyCharacterCombination(keyEvent.getCode().getName(), 
            keys.toArray(new KeyCombination.Modifier[keys.size()]))); 
          keys.clear(); 
         } 
        } 
       }); 
       return cell; 
     } 
     }); 
     table.getColumns().add(column); 
     stage.setScene(new Scene(table)); 
     stage.show(); 
    } 
} 
+1

저는 Java 8을 사용합니다.'SceneBuilder, TableColumnBuilder, TableViewBuilder, KeyCharacterCombinationBuilder'는 더 이상 사용되지 않으며 예제가 작동하지 않습니다. Java 8에 대한 예제를 편집 할 수 있습니까? –

+0

Java 8을 설치하지 않았지만 모든 작성기 코드를 제거 했으므로 호환성이 있어야합니다. 건축가를 제거한 것은 수치스러운 일이었습니다. 그들은 함께 일하는 기쁨이었습니다. –

0
public class KeyboardExample extends Application{ 
@Override 
    public void start(final Stage stage) { 
     final Keyboard keyboard = new Keyboard(new Key(KeyCode.A), 
               new Key(KeyCode.S), 
               new Key(KeyCode.D), 
               new Key(KeyCode.F)); 

     final Scene scene = new Scene(new Group(keyboard.createNode())); 
     stage.setScene(scene); 
     stage.setTitle("Keyboard Example"); 
     stage.show(); 
    } 

    public static void main(final String[] args) { 
     launch(args); 
    } 

    private static final class Key { 
     private final KeyCode keyCode; 
     private final BooleanProperty pressedProperty; 

     public Key(final KeyCode keyCode) { 
      this.keyCode = keyCode; 
      this.pressedProperty = new SimpleBooleanProperty(this, "pressed"); 
     } 

     public KeyCode getKeyCode() { 
      return keyCode; 
     } 

     public boolean isPressed() { 
      return pressedProperty.get(); 
     } 

     public void setPressed(final boolean value) { 
      pressedProperty.set(value); 
     } 

     public Node createNode() { 
      final StackPane keyNode = new StackPane(); 
      keyNode.setFocusTraversable(true); 
      installEventHandler(keyNode); 

      final Rectangle keyBackground = new Rectangle(50, 50); 
      keyBackground.fillProperty().bind(
        Bindings.when(pressedProperty) 
          .then(Color.RED) 
          .otherwise(Bindings.when(keyNode.focusedProperty()) 
               .then(Color.WHITE) 
               .otherwise(Color.WHITE))); 
      keyBackground.setStroke(Color.BLACK); 
      keyBackground.setStrokeWidth(2); 
      keyBackground.setArcWidth(12); 
      keyBackground.setArcHeight(12); 

      final Text keyLabel = new Text(keyCode.getName()); 
      keyLabel.setFont(Font.font("Arial", FontWeight.BOLD, 20)); 

      keyNode.getChildren().addAll(keyBackground, keyLabel); 

      return keyNode; 
     } 

     private void installEventHandler(final Node keyNode) { 
      // handler for enter key press/release events, other keys are 
      // handled by the parent (keyboard) node handler 
      final EventHandler<KeyEvent> keyEventHandler = 
        new EventHandler<KeyEvent>() { 
         public void handle(final KeyEvent keyEvent) { 
          if (keyEvent.getCode() == KeyCode.ENTER) { 
           setPressed(keyEvent.getEventType() 
               == KeyEvent.KEY_PRESSED); 

           keyEvent.consume(); 
          } 
         } 
        }; 

      keyNode.setOnKeyPressed(keyEventHandler); 
      keyNode.setOnKeyReleased(keyEventHandler); 
     } 
    } 

    private static final class Keyboard { 
     private final Key[] keys; 

     public Keyboard(final Key... keys) { 
      this.keys = keys.clone(); 
     } 

     public Node createNode() { 
      final HBox keyboardNode = new HBox(6); 
      keyboardNode.setPadding(new Insets(6)); 

      final List<Node> keyboardNodeChildren = keyboardNode.getChildren(); 
      for (final Key key: keys) { 
       keyboardNodeChildren.add(key.createNode()); 
      } 

      installEventHandler(keyboardNode); 
      return keyboardNode; 
     } 

     private void installEventHandler(final Parent keyboardNode) { 
      // handler for key pressed/released events not handled by 
      // key nodes 
      final EventHandler<KeyEvent> keyEventHandler = 
        new EventHandler<KeyEvent>() { 
         public void handle(final KeyEvent keyEvent) { 
          final Key key = lookupKey(keyEvent.getCode()); 
          if (key != null) { 
           key.setPressed(keyEvent.getEventType() 
                == KeyEvent.KEY_PRESSED); 

           keyEvent.consume(); 
          } 
         } 
        }; 

      keyboardNode.setOnKeyPressed(keyEventHandler); 
      keyboardNode.setOnKeyReleased(keyEventHandler); 

      keyboardNode.addEventHandler(KeyEvent.KEY_PRESSED, 
             new EventHandler<KeyEvent>() { 
              public void handle(
                final KeyEvent keyEvent) { 
               handleFocusTraversal(
                 keyboardNode, 
                 keyEvent); 
              } 
             }); 
     } 

     private Key lookupKey(final KeyCode keyCode) { 
      for (final Key key: keys) { 
       if (key.getKeyCode() == keyCode) { 
        return key; 
       } 
      } 
      return null; 
     } 

     private static void handleFocusTraversal(final Parent traversalGroup, 
               final KeyEvent keyEvent) { 
      final Node nextFocusedNode; 
      switch (keyEvent.getCode()) { 
       case LEFT: 
        nextFocusedNode = 
          getPreviousNode(traversalGroup, 
              (Node) keyEvent.getTarget()); 
        keyEvent.consume(); 
        break; 

       case RIGHT: 
        nextFocusedNode = 
          getNextNode(traversalGroup, 
             (Node) keyEvent.getTarget()); 
        keyEvent.consume(); 
        break; 

       default: 
        return; 
      } 

      if (nextFocusedNode != null) { 
       nextFocusedNode.requestFocus(); 
      } 
     } 

     private static Node getNextNode(final Parent parent, 
             final Node node) { 
      final Iterator<Node> childIterator = 
        parent.getChildrenUnmodifiable().iterator(); 

      while (childIterator.hasNext()) { 
       if (childIterator.next() == node) { 
        return childIterator.hasNext() ? childIterator.next() 
                : null; 
       } 
      } 

      return null; 
     } 

     private static Node getPreviousNode(final Parent parent, 
              final Node node) { 
      final Iterator<Node> childIterator = 
        parent.getChildrenUnmodifiable().iterator(); 
      Node lastNode = null; 

      while (childIterator.hasNext()) { 
       final Node currentNode = childIterator.next(); 
       if (currentNode == node) { 
        return lastNode; 
       } 

       lastNode = currentNode; 
      } 

      return null; 
     } 
    } 

}

관련 문제