Skip to content

Commit

Permalink
'#1866: Custom renderer for bookmarks cell in the main table.
Browse files Browse the repository at this point in the history
  • Loading branch information
wladimirleite committed Sep 13, 2023
1 parent a1380b0 commit 60367ff
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 13 deletions.
6 changes: 3 additions & 3 deletions iped-app/src/main/java/iped/app/ui/BookmarksManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
import org.slf4j.LoggerFactory;

import iped.app.ui.bookmarks.BookmarkAndKey;
import iped.app.ui.bookmarks.BookmarkColorsManager;
import iped.app.ui.bookmarks.BookmarkColorsUtil;
import iped.app.ui.bookmarks.BookmarkEditDialog;
import iped.app.ui.bookmarks.BookmarkListRenderer;
import iped.data.IItem;
Expand Down Expand Up @@ -448,7 +448,7 @@ public void actionPerformed(final ActionEvent evt) {
multiBookmarks.newBookmark(name);
multiBookmarks.setBookmarkComment(name, comment);
multiBookmarks.setBookmarkColor(name,
BookmarkColorsManager.getInitialColor(multiBookmarks.getUsedColors(), name));
BookmarkColorsUtil.getInitialColor(multiBookmarks.getUsedColors(), name));
updateList();
}
list.clearSelection();
Expand Down Expand Up @@ -515,7 +515,7 @@ public void actionPerformed(final ActionEvent evt) {
if (newColor != null && !newColor.equals(currentColor)) {
multiBookmarks.setBookmarkColor(currentName, newColor);
changed = true;
BookmarkColorsManager.storeNameToColor(currentName, newColor);
BookmarkColorsUtil.storeNameToColor(currentName, newColor);
}

if (changed) {
Expand Down
50 changes: 42 additions & 8 deletions iped-app/src/main/java/iped/app/ui/TableCellRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package iped.app.ui;

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.IOException;

import javax.swing.Icon;
Expand All @@ -28,6 +30,7 @@

import org.apache.lucene.document.Document;

import iped.app.ui.bookmarks.BookmarkCellRenderer;
import iped.app.ui.bookmarks.BookmarkIcon;
import iped.data.IItemId;
import iped.data.IMultiBookmarks;
Expand All @@ -37,6 +40,8 @@
public class TableCellRenderer extends DefaultTableCellRenderer {

private static final long serialVersionUID = 1L;
private boolean customPaint;
private BookmarkCellRenderer bookmarkCellRenderer;

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
Expand All @@ -48,21 +53,35 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
int col = table.convertColumnIndexToModel(column);
TableModel model = table.getModel();
String colName = model.getColumnName(col);

Icon icon = null;
String toopTip = null;
if (model instanceof SearchResultTableModel && colName.equalsIgnoreCase(BookmarkIcon.columnName)) {
setText("");
if (value != null) {
customPaint = false;

if (model instanceof SearchResultTableModel) {
if (colName.equalsIgnoreCase(ResultTableModel.BOOKMARK_COL)) {
String str = (String) value;
if (!str.isEmpty()) {
toopTip = str;
IMultiBookmarks multiBookmarks = App.get().appCase.getMultiBookmarks();
icon = BookmarkIcon.getIcon(multiBookmarks, str);
if (bookmarkCellRenderer == null) {
bookmarkCellRenderer = new BookmarkCellRenderer();
}
bookmarkCellRenderer.setBookmarks(multiBookmarks, str);
customPaint = true;
}
}

} else if (model instanceof SearchResultTableModel) {
if (colName.equalsIgnoreCase(IndexItem.NAME)
} else if (colName.equalsIgnoreCase(BookmarkIcon.columnName)) {
setText("");
if (value != null) {
String str = (String) value;
if (!str.isEmpty()) {
toopTip = str;
IMultiBookmarks multiBookmarks = App.get().appCase.getMultiBookmarks();
icon = BookmarkIcon.getIcon(multiBookmarks, str);
}
}

} else if (colName.equalsIgnoreCase(IndexItem.NAME)
|| colName.equalsIgnoreCase(LocalizedProperties.getLocalizedField(IndexItem.NAME))
|| (model instanceof DuplicatesTableModel && (colName.equalsIgnoreCase(IndexItem.PATH)
|| colName.equalsIgnoreCase(LocalizedProperties.getLocalizedField(IndexItem.PATH))))) {
Expand All @@ -89,4 +108,19 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole

return this;
}

@Override
protected void paintComponent(Graphics g) {
if (customPaint) {
Graphics2D g2 = (Graphics2D) g;
int w = getWidth();
int h = getHeight();
g2.setBackground(getBackground());
g2.clearRect(0, 0, w, h);
g2.setFont(getFont());
bookmarkCellRenderer.paint(g2, w, h);
} else {
super.paintComponent(g);
}
}
}
155 changes: 155 additions & 0 deletions iped-app/src/main/java/iped/app/ui/bookmarks/BookmarkCellRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package iped.app.ui.bookmarks;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;

import iped.data.IMultiBookmarks;

public class BookmarkCellRenderer {
private static final RenderingHints renderingHints;

private String[] names;
private Color[] colors;
private final Map<Integer, ClippedString[]> clippedNamesMemo = new HashMap<Integer, ClippedString[]>();
private int maxSpacing;
private String lastStr;

static {
Map<Key, Object> hints = new HashMap<Key, Object>();
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
hints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
renderingHints = new RenderingHints(hints);
}

public void setBookmarks(IMultiBookmarks bookmarks, String str) {
boolean strChanged = false;
if (!str.equals(lastStr)) {
strChanged = true;
if (str.indexOf(" | ") < 0) {
if (names == null || names.length != 1) {
names = new String[] { str };
} else {
names[0] = str;
}
} else {
names = str.split(" \\| ");
}
lastStr = str;
}
if (colors == null || colors.length < names.length) {
colors = new Color[names.length];
}
for (int i = 0; i < names.length; i++) {
Color c = bookmarks.getBookmarkColor(names[i]);
colors[i] = c == null ? BookmarkStandardColors.defaultColor : c;
}
if (strChanged) {
maxSpacing = Integer.MAX_VALUE;
clippedNamesMemo.clear();
}
}

private synchronized ClippedString[] getClippedNames(FontMetrics fm, Graphics2D g, int w) {
if (w > maxSpacing) {
w = maxSpacing;
}
ClippedString[] cs = clippedNamesMemo.get(w);
if (cs == null) {
cs = new ClippedString[names.length];
int x = 0;
for (int i = 0; i < names.length; i++) {
String s = names[i].trim();
Rectangle2D rc = fm.getStringBounds(s, g);
int rw = (int) rc.getWidth() + 6;
cs[i] = new ClippedString(s, rw);
x += rw + 1;
}
x--;
if (x <= w) {
maxSpacing = w = x;
} else {
String el = "...";
int used = x;
int minW = 8;
while (used > w) {
int idx = -1;
int maxW = minW;
for (int i = 0; i < names.length; i++) {
ClippedString a = cs[i];
if (a.w > maxW && !a.str.isEmpty()) {
maxW = a.w;
idx = i;
}
}
if (idx == -1) {
break;
}
ClippedString a = cs[idx];
if (a.str.length() <= 1) {
a.str = "";
} else if (a.str.endsWith(el)) {
if (a.str.length() <= el.length() + 1) {
a.str = a.str.substring(0, 1).trim();
} else {
a.str = a.str.substring(0, a.str.length() - 1 - el.length()).trim() + el;
}
} else {
a.str = a.str.substring(0, a.str.length() - 1).trim() + el;
}
if (a.str.isEmpty()) {
a.w = minW;
} else {
Rectangle2D rc = fm.getStringBounds(a.str, g);
int rw = (int) rc.getWidth() + 6;
if (rw < minW) {
rw = minW;
a.str = "";
}
a.w = rw;
}
used -= maxW - a.w;
}
}
clippedNamesMemo.put(w, cs);
}
return cs;
}

public void paint(Graphics2D g, int w, int h) {
RenderingHints saveHints = g.getRenderingHints();
g.setRenderingHints(renderingHints);
FontMetrics fm = g.getFontMetrics();
ClippedString[] cn = getClippedNames(fm, g, w);
int y = (int) ((h - fm.getHeight()) / 2.0 + fm.getAscent());
int x = 0;
for (int i = 0; i < cn.length; i++) {
ClippedString cs = cn[i];
Color c = colors[i];
g.setColor(c);
g.fillRoundRect(x, 1, cs.w, h - 1, h / 2, h / 2);
g.setColor(BookmarkColorsUtil.getForeground(c));
g.drawString(cs.str, x + 3, y);
x += cs.w + 1;
}
g.setRenderingHints(saveHints);
}

private class ClippedString {
String str;
int w;

ClippedString(String str, int w) {
this.str = str;
this.w = w;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import iped.utils.IOUtil;

public class BookmarkColorsManager {
public class BookmarkColorsUtil {
private static final String colorsMemoFile = System.getProperty("user.home") + "/.iped/bkmclr.dat";

private static Map<Integer, Color> colorsMemo = Collections.synchronizedMap(new LinkedHashMap<Integer, Color>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private BookmarkIcon(Color color, Boolean checked) {
this.color = color;
this.colors = null;
this.checked = checked;
this.checkedColor = BookmarkColorsManager.getForeground(color);
this.checkedColor = BookmarkColorsUtil.getForeground(color);
}

@Override
Expand Down

0 comments on commit 60367ff

Please sign in to comment.