Copy and Paste using Swing
스윙을 사용하여, 클립보드를 통한 Copy/Paste연산이 가능하다. 다음과 같이 텍스트 영역과 버튼 세 개가 프레임에 배열되어 있다고 할 때, 텍스트 필드의 값을 클립보드에 올리고, 클립보드의 내용을 텍스트 필드에 붙이는 작업을 할 수 있다.
JFrame frame = new JFrame("Clipboard demo"); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); // 텍스트 영역 생성 final JTextArea textarea = new JTextArea(10, 40); // 버튼 세 개 생성 JPanel buttonpanel = new JPanel(); JButton copybutton = new JButton("Copy"); JButton pastebutton = new JButton("Paste"); JButton exitbutton = new JButton("Exit"); // 콤포넌트를 컨테이너에 삽입한다. buttonpanel.add(copybutton); buttonpanel.add(pastebutton); buttonpanel.add(exitbutton); panel.add("North", textarea); panel.add("South", buttonpanel); frame.getContentPane().add("Center", panel); frame.pack();
우선, 클립보드를 다루는 객체를 생성해야 한다. java.awt.datatransfer.Clipboard 클래스는
클립보드에 관한 연산을 수행해 주는데, 이 객체를 얻어내는 방법은 다음과 같다
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
클립보드 클래스가 가지고 있는 메쏘드는 다음과 같다
- Transferable getContents(Object requestor) : 클립보드에 존재하는 데이타를 requestor에게 전달한다
- String getName() : 클립보드 객체의 이름
- void setContents(Transferable contents, ClipboardOwner owner) : 클립보드에 데이타를 올린다.
클립보드에 데이타 복사
이 메쏘드의 결과로 시스템 클립보드 객체를 얻어낼 수 있다. 그러면, 어떤 객체가 클립보드와의 통신에 사용가능할까? 모든 객체를 클립보드에 올릴 수 있는 것은 아니다. 반드시 java.awt.datatransfer.Transferable 인터페이스를 구현해야만, 그 객체가 클립보드에 올라갈 수 있다. 대표적인 구현 객체로는 String을 클립보드에 올릴 수 있는 StringSelection 클래스이다. 이것을 사용해, 세 개의 버튼 중, Copy 버튼이 눌려지면, 현재 텍스트 영역의 문자열을 클립보드로 옮기는 연산을 수행해 보면, 다음과 같다
copybutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); String s = textarea.getText(); StringSelection contents = new StringSelection(s); cb.setContents(contents, null); textarea.setText(""); } });
클립보드의 데이타 복사
클립보드의 데이타를 복사해 오기 위해서는, 역과정을 거친다. 클립보드 객체를 얻어내었으면, 존재하는 Transferable 객체를 얻어낸다.
pastebutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable content = cb.getContents(this); try { String s = (String)content.getTransferData(DataFlavor.stringFlavor); textarea.setText(s); } catch (Throwable exc) { System.err.println(e); } } });
DataFlavor 객체는 클립보드로부터 날아오는 데이타의 특성(MIME TYPE,String 등)을 가지고 있으며, 이는 Transferable.getTransferDataFlavors()로 알아낼 수 있다. 하지만, 타입을 이미 알고 있는 상태라면, Transferable.getTransferData를 사용해 객체를 바로 얻어낼 수 있다.
더 간단한 TextAction처리방법
위와 같이 TextComponent내의 연산들을 직접 처리할 수도 있지만, 다수의 작업들이 이미 DefaultEditorKit에 정의되어 있다. 여기에는 클립보드를 이용하는 연산뿐 아니라, 텍스트 컴포넌트 내의 캐럿의 위치나 삭제,삽입등의 에디터에서 할 수 있는 광범위한 작업들에 대한 이벤트 객체가 이미 마련되어 있다.
우선 이것을 쓰는 것부터 미리 알아보자. 위의 클립 보드 연산이 가능하도록 DefaultEditorKit의 힘을 빌려 보자. 이들 수많은 액션들은 ActionCommand라는 문자열 이름을 통해 구분된다. 물론, 버튼이나 기타 ActionEvent를 발생시킬 수 있는 컴포넌트에 이벤트를 추가하면서 setActionCommand, getActionCommand 등의 메쏘드를 많이 사용해 보았을 것이다. 너무 종류가 많으므로 이들의 이름을 키값으로 하고, 실제 Action객체의 레퍼런스를 값으로 가지는 해쉬 테이블을 하나 준비해, 이름만 주면 쉽게 객체의 레퍼런스를 구할 수 있게 하자.
java.util.Hashtable cmdTable;
이제 이 해쉬 테이블 객체를 생성하고, 모든 텍스트 Action에 대한 객체를 얻어와 해쉬 테이블에 넣자.
protected Action[] getActions() {
return TextAction.augmentList(textPane.getActions(), actions); // 현재 사용자정의된 Action객체들과 DefaultEditorKit으로부터 얻어오는 Action객체들을 // 합쳐서 하나의 리스트로 만들어 반환한다 } protected void setTextAction() { cmdTable = new java.util.Hashtable(); Action[] allactions = getActions(); for (int i = 0; i < allactions.length; i++) { Action a = allactions[i]; cmdTable.put(a.getValue(Action.NAME), a); } }
이제 이 해쉬테이블을 이용해 Cut,Copy,Paste 세 가지 작업을 해 보자. 직접 클립보드를 다루었을 때 사용했던 세 버튼의 이벤트 리스너를 다음과 같이 일일이 정의하지 않고도 설정해 줄 수 있다.
JButton[] editButtons = new JButton[] { cutButton, copyButton,pasteButton }; String[] editButtonNames = new String[] {"잘라내기","복사하기","붙여넣기"}; String[] editButtonsActionCommands = new String[] { // 이 이름들이 DefaultEditorKit에 정의되어 있다. "cut-to-clipboard", // 또는 DefaultEditorKit.cutAction "copy-to-clipboard", // 또는 DefaultEditorKit.copyAction "paste-from-clipboard" // 또는 DefaultEditorKit.pasteAction };
for(int i=0; i < editMenuItemNum; i++) { try { editButtons[i] = new JButton(editButtonNames[i]); editButtons[i].setActionCommand(editButtonsActionCommands[i]); Action action = getAction(editButtonsActionCommands[i]); if(action != null) editMenuItems[i].addActionListener(action); } catch(Exception e) { } } ......
protected Action getAction(String cmd) { return (Action)cmdTable.get(cmd); }
다른 Action에 대해서는 DefaultEditorKit 클래스의 명세를 통해 알아보기 바란다.
'IT_Programming > Java' 카테고리의 다른 글
JTable에 클립보드를 이용해서 붙이고 카피하기. (0) | 2008.03.29 |
---|---|
Thread로 구현한 HTML 다운로더 (0) | 2008.03.14 |
개발자가 놓치기 쉬운 자바의 기본원리 (0) | 2008.01.27 |
jxl.jar를 이용해서 Excel file 생성하기 (0) | 2008.01.25 |
[펌] java(자바)로 excel(엑셀) 파일 활용 (jxl api) 정리 (0) | 2008.01.25 |