// -*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
// @homepage@

package example;

import java.awt.*;
import java.util.Objects;
import java.util.Optional;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

public final class MainPanel extends JPanel {
  private MainPanel() {
    super(new BorderLayout());
    String[] columnNames = {"String-String/String", "Integer", "Boolean"};
    Object[][] data = {
        {"1234567890123456789012345678901234567890", 12, true},
        {"BBB", 2, true}, {"EEE", 3, false},
        {"CCC", 4, true}, {"FFF", 5, false},
        {"DDD", 6, true}, {"GGG", 7, false}
    };
    TableModel model = new DefaultTableModel(data, columnNames) {
      @Override public Class<?> getColumnClass(int column) {
        return getValueAt(0, column).getClass();
      }
    };
    JTable table = new JTable(model) {
      @Override public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
        Component c = super.prepareRenderer(tcr, row, column);
        if (c instanceof JComponent) {
          JComponent l = (JComponent) c;
          Insets i = l.getInsets();
          Rectangle rect = getCellRect(row, column, false);
          rect.width -= i.left + i.right;
          FontMetrics fm = l.getFontMetrics(l.getFont());
          String str = Objects.toString(getValueAt(row, column), "");
          int cellTextWidth = fm.stringWidth(str);
          l.setToolTipText(cellTextWidth > rect.width ? str : null);
        }
        return c;
      }

      @Override public void updateUI() {
        super.updateUI();
        TableCellRenderer r = new ToolTipHeaderRenderer();
        for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
          getColumnModel().getColumn(i).setHeaderRenderer(r);
        }
        // JTableHeader h = getTableHeader();
        // h.setDefaultRenderer(new ToolTipHeaderRenderer(h.getDefaultRenderer()));
      }
    };
    table.setAutoCreateRowSorter(true);
    add(new JScrollPane(table));
    setPreferredSize(new Dimension(320, 240));
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(MainPanel::createAndShowGui);
  }

  private static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    JFrame frame = new JFrame("@title@");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

class ToolTipHeaderRenderer implements TableCellRenderer {
  // private final Icon icon = UIManager.getIcon("Table.ascendingSortIcon");

  @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();
    JLabel l = (JLabel) renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    Insets i = l.getInsets();
    Rectangle rect = table.getCellRect(row, column, false);
    rect.width -= i.left + i.right;
    // RowSorter<? extends TableModel> sorter = table.getRowSorter();
    // if (sorter != null && !sorter.getSortKeys().isEmpty() && sorter.getSortKeys().get(0).getColumn() == column) {
    //   rect.width -= icon.getIconWidth() + l.getIconTextGap();
    // }

    // Optional.ofNullable(table.getRowSorter())
    //   .filter(sorter -> !sorter.getSortKeys().isEmpty() && sorter.getSortKeys().get(0).getColumn() == column)
    //   .filter(sorter -> Objects.nonNull(l.getIcon()))
    //   .ifPresent(sorter -> rect.width -= icon.getIconWidth() + l.getIconTextGap());

    Optional.ofNullable(l.getIcon())
        .ifPresent(icon -> rect.width -= icon.getIconWidth() + l.getIconTextGap());

    FontMetrics fm = l.getFontMetrics(l.getFont());
    String str = Objects.toString(value, "");
    int cellTextWidth = fm.stringWidth(str);
    l.setToolTipText(cellTextWidth > rect.width ? str : null);
    return l;
  }
}

@@ -143,35 +143,8 @@
 ts;%0A
-import java.util.Optional;%0A
 impo
@@ -3114,23 +3114,16 @@
 nderer r
-enderer
  = table
@@ -3170,35 +3170,22 @@
     
-JLabel l = (JLabel) rendere
+Component c = 
 r.ge
@@ -3258,24 +3258,86 @@
 w, column);%0A
+    if (c instanceof JLabel) %7B%0A      JLabel l = (JLabel) c;%0A  
     Insets i
@@ -3358,30 +3358,23 @@
 ();%0A    
-Rectangle rect
+  int w
  = table
@@ -3409,26 +3409,16 @@
 lse)
-;%0A    rect
 .width -
 = i.
@@ -3405,33 +3405,32 @@
 , false).width -
-=
  i.left + i.righ
@@ -3440,235 +3440,21 @@
     
-// RowSorter%3C? extends TableModel%3E sorter = table.getRowSorter();%0A    // if (sorter != null && !sorter.getSortKeys().isEmpty() && sorter.getSortKeys().get(0).getColumn() == column) %7B%0A    //   rect.width -= icon.getIconWidth() +
+  Icon icon =
  l.g
@@ -3463,23 +3463,16 @@
 Icon
-TextGap
 ();%0A    
 // %7D
@@ -3471,273 +3471,39 @@
     
-// %7D%0A%0A    // Optional.ofNullable(table.getRowSorter())%0A    //   .filter(sorter -%3E !sorter.getSortKeys().isEmpty() && sorter.getSortKeys().get(0).getColumn() == column)%0A    //   .filter(sorter -%3E Objects.nonNull(l.getIcon()))
+  if (icon != null) %7B
 %0A    
-//
    
-.ifPresent(sorter -%3E rect.width
+ w
  -= 
@@ -3546,134 +3546,20 @@
 ap()
-);%0A
+;
 %0A    
-Optional.ofNullable(l.getIcon())%0A        .ifPresent(icon -%3E rect.width -= icon.getIconWidth() + l.getIconTextGap());%0A%0A
+  %7D%0A  
     
@@ -3606,24 +3606,26 @@
 ont());%0A    
+  
 String str =
@@ -3654,24 +3654,26 @@
 e, %22%22);%0A    
+ 
+ 
 int cellText
@@ -3697,24 +3697,26 @@
 Width(str);%0A
+  
     l.setToo
@@ -3736,34 +3736,25 @@
 TextWidth %3E 
-rect.width
+w
  ? str : nul
@@ -3753,24 +3753,30 @@
 tr : null);%0A
+    %7D%0A
     return l
@@ -3774,17 +3774,17 @@
  return 
-l
+c
 ;%0A  %7D%0A%7D%0A

add instanceof check