JTable에 있는 값을 더블 클릭했을 때 해당하는 값을 복사해보자. 위 gif에서는 커서가 보이지 않기 때문에 무엇을 클릭하는지 자세히 보이지 않을 수 있는데 자세히 보면 클릭되는 셀의 테두리가 굵게 되는 것을 볼 수 있다.
기본적으로 JFrame, JTable을 다룰 줄 알아야 하고 MouseListener 혹은 MouseAdapter를 사용할 줄 알면 좋다. 전체 코드를 포스팅에 포함시킬 예정이지만 테이블 생성에 관한 기본적인 설명은 하지 않는다.
MouseListener는 인터페이스이기 때문에 마우스의 핵심적인 이벤트(드래그, 이동, 클릭 전후) 메서드를 강제적으로 구현해야 하지만 아답터를 쓰면 필요한 메서드만을 오버라이드하여 사용할 수 있다. 현재 구현에 있어서는 클릭한 후 이벤트만 필요하기 때문에 리스너가 아닌 아답터를 사용하여 구현할 것이다. 아답터를 사용할 줄 모른다면 리스너로 구현해도 문제없다.
테이블에서 선택된 값, 문자열을 복사하면 클립보드(Clipboard)에 저장된다. 클립보드에 대해 깊게 알 필요는 없고 우리가 복사한 값이 클립보드에 저장되고 복사한 값을 읽어올 때에는 붙여넣기(혹은 Ctrl+V)를 통해 클립보드에서 꺼내온다는 것만 알면 되겠다.
아래는 코드다.
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
public class MyFrame extends JFrame{
private JTable jtab;
private DefaultTableModel dtm;
private Clipboard clipboard;
private ArrayList<Person> list;
private final String[] TABLE_HEADER = {"No", "Name", "Age"};
public static void main(String[] args) {
MyFrame myFrame = new MyFrame();
myFrame.setVisible(true);
}
public MyFrame() {
setTitle("MyFrame");
setBounds(10, 10, 300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(Color.white);
setLayout(null);
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
setComponent();
setTable();
}
private void setComponent() {
dtm = new DefaultTableModel(TABLE_HEADER, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
jtab = new JTable(dtm);
jtab.getTableHeader().setReorderingAllowed(false);
jtab.getTableHeader().setEnabled(false);
jtab.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jtab.setRowHeight(25);
jtab.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (e.getClickCount() == 2) {
int row = jtab.getSelectedRow();
int col = jtab.getSelectedColumn();
StringSelection value = null;
switch(col) {
case 0:
value = new StringSelection(list.get(row).no + "");
break;
case 1:
value = new StringSelection(list.get(row).name);
break;
case 2:
value = new StringSelection(list.get(row).age + "");
}
clipboard.setContents(value, value);
}
}
});
JScrollPane tablePan = new JScrollPane(jtab, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
tablePan.setBounds(10, 10, 265, 140);
add(tablePan);
}
private void setTable() {
list = new ArrayList<>();
list.add(new Person(1, "김철수", 21));
list.add(new Person(2, "이영미", 22));
list.add(new Person(3, "신지수", 19));
for(Person person : list)
dtm.addRow(person.toArray());
}
class Person {
int no, age;
String name;
public Person(int no, String name, int age) {
this.no = no;
this.name = name;
this.age = age;
}
public Object[] toArray() {
return new Object[] {no, name, age};
}
}
}
기본적인 코드만 존재하기 때문에 JTable을 한 번이라도 생성해봤다면 코드를 어렵지 않게 이해할 수 있을 것이다. 데이터 클래스인 Person의 경우 예제 코드를 줄이기 위해서 getter를 생략하였다. 핵심은 멤버 변수인 Clipboard 객체와 JTable 객체에 마우스 이벤트를 추가한 addMouseListener 메서드가 되겠다.
JTable에 추가된 값을 마우스로 클릭했을 때 이벤트를 발생시키기 위해서 MouseAdapter를 추가한 뒤 마우스 이벤트 중 클릭이 때어진 순간 이벤트를 발생시키는 mouseClicked 메서드를 오버라이드 한다. 여기서 더블 클릭을 구현하기 위해서 getClickCount를 통해 연속으로 클릭된 횟수를 체크하여 2번 클릭되었을 경우에 이벤트를 처리한다.
더블 클릭이 발생하면 먼저 클릭된 행(row), 열(column)의 인덱스를 구한다. 행은 리스트의 인덱스로 사용되고 열은 리스트에서 읽어온 객체에서 특정한 값을 읽는데 사용될 것이다. 값을 읽었으면 StringSelection 객체에 초기화한 후 해당 객체를 클립보드에 세팅한다. 여기까지 문제없이 수행되었다면 클립보드에 값이 복사되었을 것이다. 텍스트를 입력할 수 있는 곳(메모장 등)에다가 "붙여넣기" 혹은 Ctrl+v를 수행하면 값이 복사된 것을 확인할 수 있다.
'자바 > Swing' 카테고리의 다른 글
[Java/Swing] JOptionPane 아이콘 커스텀하기 (0) | 2022.12.05 |
---|---|
[Java/Swing] Drag and Drop 구현하기 (0) | 2021.12.03 |
[Java/Swing] 화면에 컴포넌트가 보이지 않을 때 (0) | 2021.12.02 |