001package jmri.jmrit.consisttool; 002 003import java.awt.*; 004import java.awt.image.BufferedImage; 005 006import javax.swing.*; 007 008import jmri.*; 009import jmri.jmrit.roster.*; 010import jmri.util.gui.GuiLafPreferencesManager; 011 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014 015/** 016 * 017 * A ListCellRenderer for the ConsistComboBox 018 * 019 * @author Lionel Jeanson Copyright (c) 2023 020 * 021 */ 022public class ConsistListCellRenderer extends JLabel implements ListCellRenderer<Object> { 023 024 @Override 025 public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 026 if (value == null) { 027 return null; 028 } 029 030 if (value instanceof String) { 031 setText((String) value); 032 setIcon(null); 033 return this; 034 } 035 036 if (value instanceof LocoAddress) { 037 LocoAddress consistAddress = (LocoAddress) value; 038 setText(consistAddress.toString()); 039 setIcon(getConsistIcon(consistAddress)); 040 } 041 return this; 042 } 043 044 public static ImageIcon getConsistIcon(LocoAddress consistAddress) { 045 return getConsistIcon(consistAddress, InstanceManager.getDefault(RosterIconFactory.class)); 046 } 047 048 public static ImageIcon getConsistIcon(LocoAddress consistAddress, RosterIconFactory iconFact ) { 049 if (iconFact == null) { 050 iconFact = InstanceManager.getDefault(RosterIconFactory.class); 051 } 052 int iconHeight = iconFact.getIconFactoryHeight(); 053 BufferedImage bi = new BufferedImage( 1, iconHeight, BufferedImage.TYPE_INT_ARGB); 054 Consist consist = InstanceManager.getDefault(jmri.ConsistManager.class).getConsist(consistAddress); 055 Font f = new Font("Monospaced", Font.PLAIN, InstanceManager.getDefault(GuiLafPreferencesManager.class).getFontSize()); 056 057 for (DccLocoAddress loco : consist.getConsistList()) { 058 log.debug("Loco : {} - Position : {}", loco, consist.getPosition(loco)); 059 String reName = consist.getRosterId(loco); 060 String label = null; 061 if (reName != null) { 062 ImageIcon icon; 063 Boolean dir = consist.getLocoDirection(loco); 064 if (dir) { 065 icon = iconFact.getIcon(reName); 066 } else { 067 icon = iconFact.getReversedIcon(reName); 068 } 069 if ( (icon != null) && (bi.getWidth() + icon.getIconWidth() > 0) ) { 070 BufferedImage ti = new BufferedImage(bi.getWidth() + icon.getIconWidth(), iconHeight, BufferedImage.TYPE_INT_ARGB); 071 Graphics g = ti.createGraphics(); 072 g.drawImage(icon.getImage(), ti.getHeight()/2-icon.getIconHeight()/2, 0, null); 073 g.drawImage(bi, icon.getIconWidth(), 0, null); 074 g.dispose(); 075 bi = ti; 076 } else { 077 label = "["+reName+"]"; 078 } 079 } else { 080 label = "["+loco.toString()+"]"; 081 } 082 if (label != null) { 083 // write label for that locomotive in a buffered image 084 BufferedImage li = new BufferedImage( label.length()*f.getSize(), iconHeight, BufferedImage.TYPE_INT_ARGB); 085 Graphics gli = li.createGraphics(); 086 gli.setFont(f); 087 //gli.setColor(this.getForeground()); 088 gli.drawString(label, 0, iconHeight/2 + gli.getFontMetrics().getMaxAscent()/2); 089 // expand existing buffered image 090 BufferedImage ti = new BufferedImage( gli.getFontMetrics().stringWidth(label) + bi.getWidth() +2, iconHeight, BufferedImage.TYPE_INT_ARGB); 091 Graphics gti = ti.createGraphics(); 092 gti.drawImage(li, 0, 0, null); 093 gti.drawImage(bi, gli.getFontMetrics().stringWidth(label)+2, 0, null); 094 // update and free ressources 095 bi = ti; 096 gli.dispose(); 097 gti.dispose(); 098 } 099 } 100 return (new ImageIcon(bi)); 101 } 102 103 private static final Logger log = LoggerFactory.getLogger(ConsistListCellRenderer.class); 104}