2022년 2월 19일 토요일

Java Swing - Table

Java Swing - Table


package jlib5.swing;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.Map;
import java.util.TreeMap;

public class Table {

    public JTable ctrl;
    public JScrollPane layout;
    JPopupMenu menu;
    Runnable selectedHandler;
    boolean cellEditable;
    int selectedRow = -1;
    String highlightedWord;
    Map<String,Color> rowFgColor = new TreeMap<>();
    Map<String,Color> rowBgColor = new TreeMap<>();
    Map<Integer,Object> metaData = new TreeMap<>();

    static class StripedTableCellRenderer extends DefaultTableCellRenderer {
        public Component getTableCellRendererComponent (JTable table, Object value, boolean selected, boolean focused, int row, int column) {
            setEnabled(table == null || table.isEnabled());
            if ((row % 2) == 0) setBackground(Color.green);
            else setBackground(Color.lightGray);
            super.getTableCellRendererComponent(table, value, selected, focused, row, column);
            return this;
        }
    }
    String getKey(int row, int column) {
        return "" + row + "_" + column;
    } 
    
    String highlightWord(String line, String word, String fg, String bg) {
       StringBuilder sb = new StringBuilder();
       line = line.replace(word, String.format("<span style=\"background-color:%s\"><font color=\"%s\">" + word + "</font></span>", bg, fg));
       sb.append("<html><body>")
               .append(line)
               .append("</body></html>");
       return sb.toString();
    }
    class ColoredTableCellRenderer extends DefaultTableCellRenderer {
        public Component getTableCellRendererComponent (JTable table, Object value, boolean selected, boolean focused, int row, int column) {
            setEnabled(table == null || table.isEnabled());
            String key = getKey(row, column);
            Color fg = rowFgColor.get(key);
            Color bg = rowBgColor.get(key);
            if ( fg != null ) { setForeground(fg); } else setForeground(Color.black);
            if ( bg != null ) { setBackground(bg); } else setBackground(Color.white);
            if( value instanceof String && highlightedWord != null ) {
                value = highlightWord( (String)value, highlightedWord, "red", "yellow" ); 
            }
            super.getTableCellRendererComponent(table, value, selected, focused, row, column);
            return this;
        }
    }

    public Table(String[] colNames, int[] widths, int[] aligns, Runnable handler) {
        DefaultTableModel tableModel = new DefaultTableModel(colNames,0);
        ctrl = new JTable(tableModel) {
            private static final long serialVersionUID = 1L;
            public boolean isCellEditable(int row, int column) {
                return cellEditable;
            };
            /*@Override
            public boolean getScrollableTracksViewportWidth() {
                return getPreferredSize().width < getParent().getWidth();
            }*/
        };
        setCelleditable(false);
        ctrl.setFillsViewportHeight(true);
        ctrl.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        ctrl.setAutoCreateRowSorter(true);
        ctrl.setPreferredScrollableViewportSize(ctrl.getPreferredSize());

        int colCount = ctrl.getModel().getColumnCount();
        if( widths != null ) {
            for (int col = 0; col < colCount && col < widths.length; col++) {
                ctrl.getColumnModel().getColumn(col).setPreferredWidth(widths[col]);
            }
        }
        if( aligns != null ) {
            for( int col = 0; col < colCount && col < aligns.length; col++ ) {
                //DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
                ColoredTableCellRenderer centerRenderer = new ColoredTableCellRenderer();
                if( aligns[col] < 0 ) centerRenderer.setHorizontalAlignment( SwingConstants.LEFT );
                if( aligns[col] == 0 ) centerRenderer.setHorizontalAlignment( SwingConstants.CENTER );
                if( aligns[col] > 0 ) centerRenderer.setHorizontalAlignment( SwingConstants.RIGHT );
                ctrl.getColumnModel().getColumn(col).setCellRenderer(centerRenderer);
            }
        }
        selectedHandler = handler;
        ctrl.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
            public void valueChanged(ListSelectionEvent event) {
                if( ctrl.getSelectedRow() >= 0 && selectedRow != ctrl.getSelectedRow() ) {
                    selectedRow = ctrl.getSelectedRow();
                    if( selectedHandler != null ) {
                        selectedHandler.run();
                    }
                }
            }
        });
        layout = new JScrollPane(ctrl);
    }
    public void setCelleditable( boolean enable ) {
        cellEditable = enable;
    }
    public void setAutoResize( boolean enable ) {
        if( enable ) {
            ctrl.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        } else {
            ctrl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        }
    }
    public void disableMultipleSelection() {
        ctrl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    }       
    public void enableMultipleSelection() {
        ctrl.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
    }
    public void enableMultipleSelection2() {
        ctrl.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    }    
    public int[] getSelectedRows() {
        int[] rows = ctrl.getSelectedRows();
        for( int i = 0; i < rows.length; i++ ) {
            rows[i] = ctrl.convertRowIndexToModel( rows[i] );
        }
        return rows;
    }    
    
    public void clear() {
        ctrl.getSelectionModel().clearSelection();
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        int rowCount = model.getRowCount();
        for (int i = rowCount - 1; i >= 0; i--) {
            model.removeRow(i);
        }
    }    
    public Object getValue(int row, int col) {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        return model.getValueAt(ctrl.convertRowIndexToModel(row), col );        
    }
    public void setValue( int row, int col, Object value ) {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        model.setValueAt( value, ctrl.convertRowIndexToModel(row), col );
    }    
    public void removeRow(int index) {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        model.removeRow(index);
    }       
    public void removeSelectedRows() {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        int[] rows = getSelectedRows();
        for( int i = rows.length-1; i >= 0; i-- ) {
            model.removeRow( ctrl.convertRowIndexToModel(rows[i]) );
        }
    }       
    public void addRow( Object[] row, Object metaData) {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        model.addRow(row);
        this.metaData.put(model.getRowCount()-1, metaData);
    }
    public void addRow( Object[] row) {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        model.addRow(row);
    }

    public int getRowCount() {
        DefaultTableModel model = (DefaultTableModel) ctrl.getModel();
        return model.getRowCount();
    }
    public Object[] getRow(int index) {
        int count = ctrl.getModel().getColumnCount();
        Object[] row = new Object[count];
        if( index >= 0 && index < getRowCount() ) {
            for (int r = 0; r < count; r++) {
                row[r] = ctrl.getValueAt(index, r);
            }
        }
        return row; 
    }
    public int getSelectedRowIndex() {
        int viewRow = ctrl.getSelectedRow();
        int modelRow = ctrl.convertRowIndexToModel(viewRow);
        return modelRow;
    }
    public Object[] getSelectedRow() {
        int count = ctrl.getModel().getColumnCount();
        Object[] row = new Object[count];
        if( ctrl.getSelectedRow() >= 0 ) {
            for (int r = 0; r < count; r++) {
                row[r] = ctrl.getValueAt(ctrl.getSelectedRow(), r);
            }
        }
        return row;
    }
    public Object getMetaData(int row) {
        return this.metaData.get(row);
    }

    public void setRowColor(int row, Color fg, Color bg) {
        for( int i = 0; i < ctrl.getColumnCount(); i++ ) {
            String key = getKey(row, i);
            rowFgColor.put(key, fg);
            rowBgColor.put(key, bg);
        }
    }
    public void setColor(int row, int column, Color fg, Color bg) {
        String key = getKey(row, column);
        rowFgColor.put(key, fg);
        rowBgColor.put(key, bg);
    }
    public void setHighLight(String word) {
        highlightedWord = word;
    }

    public void addContextMenu(String name, Runnable handler) {
        JMenuItem item = new JMenuItem(name);
        item.addActionListener( (e) -> handler.run() );
        if( this.menu == null ) {
            this.menu = new JPopupMenu();
            this.menu.add(item);
            ctrl.setComponentPopupMenu(this.menu);
        } else {
            menu.add(item);
        }
    }
    
    public void scrollToRow(int row) {
        this.ctrl.scrollRectToVisible(new Rectangle(this.ctrl.getCellRect(row, 0, true)));
    }

    public void selectRows(int begin, int end) {
        this.ctrl.getSelectionModel().setSelectionInterval(begin, end);
    }
}

댓글 없음:

댓글 쓰기