Code
class TableOfContentsTreeCellRenderer extends DefaultTreeCellRenderer {
private static BasicStroke READER = new BasicStroke(
1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
1f, new float[] { 1f }, 0f);
private String pn;
private Point pnPt = new Point();
private int rxs, rxe, ry;
private boolean isSynth = false;
private final JPanel p = new JPanel(new BorderLayout()) {
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (pn != null) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(isSynth ? getForeground() : getTextNonSelectionColor());
g2.drawString(pn, pnPt.x - getX(), pnPt.y);
g2.setStroke(READER);
g2.drawLine(rxs, pnPt.y, rxe - getX(), pnPt.y);
g2.dispose();
}
}
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.width = Short.MAX_VALUE;
return d;
}
};
public TableOfContentsTreeCellRenderer() {
super();
p.setOpaque(false);
}
@Override public void updateUI() {
super.updateUI();
isSynth = getUI().getClass().getName().contains("Synth");
if (isSynth) {
//System.out.println("XXX: FocusBorder bug?, JDK 1.7.0, Nimbus start LnF");
setBackgroundSelectionColor(new Color(0x0, true));
}
}
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
JLabel l = (JLabel) super.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode n = (DefaultMutableTreeNode) value;
Object o = n.getUserObject();
if (o instanceof TableOfContents) {
TableOfContents toc = (TableOfContents) o;
FontMetrics metrics = l.getFontMetrics(l.getFont());
int gap = l.getIconTextGap();
int h = l.getPreferredSize().height;
Insets ins = tree.getInsets();
p.removeAll();
p.add(l, BorderLayout.WEST);
if (isSynth) p.setForeground(l.getForeground());
pn = String.format("%3d", toc.page);
pnPt.x = tree.getWidth() - metrics.stringWidth(pn) - gap;
pnPt.y = (h + metrics.getAscent()) / 2;
rxs = l.getPreferredSize().width + gap;
rxe = tree.getWidth() - ins.right - metrics.stringWidth("000") - gap;
ry = h / 2;
return p;
}
}
pn = null;
return l;
}
}
References