시소당
TextArea, JTextArea, JEditorPane, JTextPane등 각종 TextComponent형 객체들의 키액션에 대해 질문들을 종종 볼수가 있어서,, 정리할겸 참고하실겸 해서 올려놉니다.
AWT/SWING에 적합한 게시물이 될지도 모르겠네요
제시할 개념은 위와같은 객체들에서 엔터를 누르면 줄바꿈이되고 방향키나 end, pageup/down키를 누르면 커서가 이동되는 원리입니다.
TextComponent(JTextComponent도마찬가지로)를 상속한 객체들은
ActionMap과 연결되어있는 InputMap이 객체에 포함되어 키가 바인딩되어 있게 됩니다.
생성자를 호출하여 생성함과 동시에 이러한 초기화가 이루어지게 됩니다.
엔터키를 예를들면 VK_ENTER에 해당하는 키스트ㅤㄹㅗㅋ이 InputMap에 등록이 되어있고,
생성된 ActionMap의 줄바꿈 액션과 바인딩되어 있는 것이지요
그래서 엔터키를 입력하면 자동으로 줄바꿈이 되는것입니다.
방향키를 눌렀을때 커서가 이동하는것도 마찬가지로 이런방식으로 구현이 되어있는 것이지요
이것을 제어하는 방법은 이 InputMap과 연결해서 생각을 해봐야 합니다.
간단하게 키리스너를 달아서 엔터키를 눌렀을겨우에 다른작업을 정의해주면 되지 않을까 라는 안일한생각으로 코딩을 하게되면 원하는바대로 동작을 하지않는 낭패를 보게 될겁니다.
키리스너로 엔터키에 해당하는 액션을 달아주면
엔터키를 눌렀을시에 해당하는 액션이 돌아가긴 하겠지만,, InputMap에 등록되어있는 액션에 의한 줄바뀜 액션 또한 역시 일어나게 됩니다.
엔터키의 동작을 막는경우를 예를들어보겠습니다.
먼저 엔터키 즉, VK_ENTER의 키스트록(KeyStroke)가 등록되어있는 InputMap객체를 얻어와야합니다.
getInputMap메소드를 사용하면 InputMap객체를 얻을 수 있지만, InputMap객체는 기존의 InputMap객체를 Parent객체로하여 참조사용이 가능합니다.
즉, getInputMap메소드로 얻어온 InputMap객체에 등록이 되어있을수도있고, 그 InputMap의 Parent InputMap에 등록되어있을수도 아니면 Parent InputMap의 Parent에 등록되어있을수도 있습니다.
getInputMap메소드로 InputMap을 얻어낸후, parent가 있으면 parent를 얻어오는식으로 parent로 연결되어잇는 모든 InputMap객체에대한 판단을 해줘야합니다.
이런점을 착안하여 궁극적으로 VK_ENTER의 키스트록이 등록되어있는 InputMap을 찾아서 VK_ENTER에 바인딩되어있는 액션을 없애줘야 겠지요..
null 로 대체시켜주면 되던것으로 기억합니다.
null이 아닌 액션오브젝트를 대체시키면 엔터를 눌렀을때 줄바꿈이 되는것이 아니라 다른일을 하게 만들수도 있습니다.
예를들어 엔터가 눌리면 TextArea에 모든영역이 선택되는 액션따위를 넣어줄수도 있겠죠..
방향키를 눌렀을때 커서가 이동되는것도 마찬가지방식입니다..
각종 에디터툴을 개발할때나 활용이 가능하겠네요..
채팅프로그램 작성시 엔터키를 누르면 키이벤트로 텍스트를 전송하고 텍스트를 지워준 후에도
줄바꿈이 된상태가 되버리는것도 이런개념으로 해결이 가능합니다.
그냥 많은분들이 궁금해하시는것 같아서 올려놉니다...
많은분들께 도움되셨으면 합니다.
참고로 Sun에서 제공해주는 자바 내장객체 소스를 분석해서 알아낸 것임을 알립니다.
//나도 퍼옴 : http://javanuri.devpia.com/devforum/boardView.jsp?Id=298334&menuId=9
출처 키스트로크|작성자 바이오