Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java Swing에서 JTable 셀에 JButton을 추가하는 방법

JTableJComponent 클래스의 하위 클래스로, 정보를 여러 행(row)과 열(column) 형태로 표시하는 테이블을 만들 때 사용됩니다. JTable에서 값이 선택되면 TableModelEvent가 발생하며, 이 이벤트는 TableModelListener 인터페이스를 구현하여 처리할 수 있습니다.

JTable 셀에 버튼을 넣는 핵심 원리

JTable의 셀에는 기본적으로 문자열이나 숫자 같은 단순한 값만 표시되지만, TableCellRenderer 인터페이스를 구현하고 getTableCellRendererComponent() 메서드를 오버라이드하면 셀 안에 JButton 같은 컴포넌트를 렌더링할 수 있습니다. 또한 DefaultTableModel이나 AbstractTableModel을 커스터마이징하여 모델 쪽에서 버튼 객체를 값으로 관리할 수 있습니다.

구현 절차 요약

  • AbstractTableModel을 상속받아 테이블 모델을 정의하고, 셀 값으로 JButton 객체를 저장합니다.
  • getColumnClass() 메서드가 해당 열의 실제 클래스(JButton.class)를 반환하도록 합니다.
  • TableCellRenderer 인터페이스를 구현한 커스텀 렌더러를 만들고, getTableCellRendererComponent()에서 값이 Component 타입이면 그대로 반환합니다.
  • setDefaultRenderer(JButton.class, ...)를 호출해 JTable에 커스텀 렌더러를 등록합니다.

예제 코드

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class JTableButtonTest extends JFrame {
    private JTable table;
    private JScrollPane scrollPane;

    public JTableButtonTest() {
        setTitle("JTableButton Test");
        TableCellRenderer tableRenderer;
        table = new JTable(new JTableButtonModel());
        tableRenderer = table.getDefaultRenderer(JButton.class);
        table.setDefaultRenderer(JButton.class, new JTableButtonRenderer(tableRenderer));
        scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setSize(400, 300);
        setVisible(true);
    }

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

class JTableButtonRenderer implements TableCellRenderer {
    private TableCellRenderer defaultRenderer;

    public JTableButtonRenderer(TableCellRenderer renderer) {
        defaultRenderer = renderer;
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (value instanceof Component)
            return (Component) value;
        return defaultRenderer.getTableCellRendererComponent(table, value,
                isSelected, hasFocus, row, column);
    }
}

class JTableButtonModel extends AbstractTableModel {
    private Object[][] rows = {{"Button1", new JButton("Button1")},
                               {"Button2", new JButton("Button2")},
                               {"Button3", new JButton("Button3")},
                               {"Button4", new JButton("Button4")}};
    private String[] columns = {"Count", "Buttons"};

    public String getColumnName(int column) {
        return columns[column];
    }

    public int getRowCount() {
        return rows.length;
    }

    public int getColumnCount() {
        return columns.length;
    }

    public Object getValueAt(int row, int column) {
        return rows[row][column];
    }

    public boolean isCellEditable(int row, int column) {
        return false;
    }

    public Class getColumnClass(int column) {
        return getValueAt(0, column).getClass();
    }
}

코드 설명

JTableButtonRenderer 클래스는 기본 렌더러를 감싸는(wrapper) 역할을 합니다. getTableCellRendererComponent() 메서드는 전달받은 값이 Component 타입인 경우 해당 컴포넌트를 그대로 반환하여 셀에 버튼이 그려지도록 하고, 그렇지 않으면 기본 렌더러에 위임합니다.

JTableButtonModel 클래스는 AbstractTableModel을 확장하여 각 행에 문자열과 JButton 객체를 함께 저장합니다. getColumnClass()가 JButton.class를 반환하기 때문에 JTable은 두 번째 열을 렌더링할 때 커스텀 렌더러를 사용하게 됩니다.

실행 결과

프로그램을 실행하면 왼쪽 열에는 "Button1"~"Button4"라는 텍스트가 표시되고, 오른쪽 "Buttons" 열에는 실제 클릭 가능한 형태로 보이는 JButton이 각 셀에 나타납니다.

Java Swing에서 JTable 셀에 JButton을 추가하는 방법

참고 사항

렌더러만으로는 버튼이 시각적으로 표시될 뿐 실제 클릭 이벤트는 발생하지 않습니다. 버튼 클릭을 처리하려면 TableCellEditor를 함께 구현하거나, JTable에 MouseListener를 등록하여 마우스 클릭 위치의 행·열을 계산한 후 로직을 처리하는 방식을 추가로 적용해야 합니다.