package pl.otros.logview.gui.renderers; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import org.apache.commons.lang.StringUtils; import pl.otros.logview.api.model.ClassWrapper; import javax.swing.*; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.io.IOException; import java.io.StringReader; import java.util.*; public class ClassWrapperRenderer implements TableCellRenderer { private final Comparator<String> stringLengthComparator = (o1, o2) -> { int result = o2.length() - o1.length(); if (result == 0) { result = o1.compareTo(o2); } return result; }; private SortedMap<String, String> replacements; private final JLabel label; public ClassWrapperRenderer() { replacements = toMap(""); label = new JLabel(); label.setOpaque(true); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { String abbreviatePackage = ""; if (value != null) { final ClassWrapper classWrapper = (ClassWrapper) value; final String className = Optional.ofNullable(classWrapper.getClassName()).orElse(""); abbreviatePackage = abbreviatePackageUsingMappings(className, replacements); int availableWidth = table.getColumnModel().getColumn(column).getWidth(); availableWidth -= table.getIntercellSpacing().getWidth(); if (label.getBorder() != null) { Insets borderInsets = label.getBorder().getBorderInsets(label); availableWidth -= (borderInsets.left + borderInsets.right); } FontMetrics fm = label.getFontMetrics(label.getFont()); abbreviatePackage = abbreviatePackagesToSingleLetter(abbreviatePackage, availableWidth, fm); while (fm.stringWidth(abbreviatePackage) > availableWidth && abbreviatePackage.length() > 0) { abbreviatePackage = abbreviatePackage.substring(1); } } label.setText(abbreviatePackage); return label; } public String abbreviatePackagesToSingleLetter(String abbreviatePackage, int availableWidth, FontMetrics fm) { String result = abbreviatePackage; if (fm.stringWidth(result) > availableWidth) { final java.util.List<String> split = Splitter.on('.').splitToList(result); int index = 0; while (fm.stringWidth(result) > availableWidth && index < split.size() - 1) { java.util.List<String> list = new ArrayList<>(split.size()); for (int i = 0; i < split.size(); i++) { final String s = split.get(i); list.add(i <= index && s.length() > 0 ? s.substring(0, 1) : s); } result = Joiner.on(".").join(list); index++; } } return result; } protected SortedMap<String, String> toMap(String configuration) { Properties p = new Properties(); SortedMap<String, String> result = new TreeMap<>(stringLengthComparator); try { p.load(new StringReader(StringUtils.defaultString(configuration))); for (Object o : p.keySet()) { final String key = o.toString(); final String value = p.getProperty(key); result.put(key, value); } } catch (IOException e) { e.printStackTrace(); } return result; } protected String abbreviatePackageUsingMappings(String clazz, SortedMap<String, String> abbreviations) { for (String s : abbreviations.keySet()) { if (StringUtils.startsWith(clazz,s)) { return StringUtils.replaceOnce(clazz, s, abbreviations.get(s)); } } return clazz; } public void reloadConfiguration(String propertyConfiguration) { replacements = toMap(propertyConfiguration); } }