Nếu một giải pháp khác nhau cho các Tab - vấn đề Focus. Hành vi mặc định của TextArea cho phím CTRL + TAB là di chuyển tiêu điểm đến điều khiển tiếp theo. Vì vậy, tôi đã thay thế sự kiện khóa TAB bằng sự kiện khóa CTRL + TAB và khi người dùng nhấn CTRL + TAB, một ký tự tab được chèn vào TextArea.
Câu hỏi của tôi: OK để kích hoạt sự kiện trong bộ lọc sự kiện? Và có thể thay thế văn bản của KeyEvent bằng FOCUS_EVENT_TEXT, để có chỉ báo nếu đó là sự kiện do người dùng tạo hoặc từ sự kiện được tạo trong bộ lọc sự kiện.
Bộ lọc sự kiện:
javafx.scene.control.TextArea textArea1 = new javafx.scene.control.TextArea();
textArea1.addEventFilter(KeyEvent.KEY_PRESSED, new TextAreaTabToFocusEventHandler());
Các xử lý sự kiện:
public class TextAreaTabToFocusEventHandler implements EventHandler<KeyEvent>
{
private static final String FOCUS_EVENT_TEXT = "TAB_TO_FOCUS_EVENT";
@Override
public void handle(final KeyEvent event)
{
if (!KeyCode.TAB.equals(event.getCode()))
{
return;
}
// handle events where the TAB key or TAB + CTRL key is pressed
// so don't handle the event if the ALT, SHIFT or any other modifier key is pressed
if (event.isAltDown() || event.isMetaDown() || event.isShiftDown())
{
return;
}
if (!(event.getSource() instanceof TextArea))
{
return;
}
final TextArea textArea = (TextArea) event.getSource();
if (event.isControlDown())
{
// if the event text contains the special focus event text
// => do not consume the event, and let the default behaviour (= move focus to the next control) happen.
//
// if the focus event text is not present, then the user has pressed CTRL + TAB key,
// then consume the event and insert or replace selection with tab character
if (!FOCUS_EVENT_TEXT.equalsIgnoreCase(event.getText()))
{
event.consume();
textArea.replaceSelection("\t");
}
}
else
{
// The default behaviour of the TextArea for the CTRL+TAB key is a move of focus to the next control.
// So we consume the TAB key event, and fire a new event with the CTRL + TAB key.
event.consume();
final KeyEvent tabControlEvent = new KeyEvent(event.getSource(), event.getTarget(), event.getEventType(), event.getCharacter(),
FOCUS_EVENT_TEXT, event.getCode(), event.isShiftDown(), true, event.isAltDown(), event.isMetaDown());
textArea.fireEvent(tabControlEvent);
}
}
}
Nguồn
2017-10-11 10:24:57
Một vấn đề nhỏ: cần có dấu kiểm cho event.isShiftDown() sẽ gọi là "TraversePrevious", không phải là "TraverseNext". –
Ít nhất đối với JavaFX 8, SkinBase nên được thay đổi thành TextAreaSkin. – tunabot