Path: csiph.com!usenet.pasdenom.info!gegeweb.org!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Knute Johnson Newsgroups: comp.lang.java.programmer Subject: Generic JList and ListCellRenderer? Date: Fri, 28 Dec 2012 11:01:58 -0800 Organization: A noiseless patient Spider Lines: 181 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Fri, 28 Dec 2012 19:01:58 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="9b3fcb0d22708969e4dc99e7aa0ef1f9"; logging-data="31683"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/O/R2sOzCdFZKqRz3IUMiD" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/17.0 Thunderbird/17.0 Cancel-Lock: sha1:IYi7BO4JT6393JxXmTWKTaOlT18= Xref: csiph.com comp.lang.java.programmer:20773 I've been trying to clean up some really old code and I've hit some snags. I've got several modified JLists and the ListCellRenderers for them and thought it would make sense to have generic classes that could be extended for different data types that need to be displayed. The example below displays InetAddresses in the JList. I've got another implementation of JList that does a lot more than what this one does but I wanted to keep this example simple and focus on the ListCellRenderer. MyListCellRenderer extends the getListCellRenderer method of DefaultListCellRenderer and adds a new method, textToDisplay(). I added a field to the constructor that specifies the class of the data element to be displayed. That class information is the test to make the call to the textToDisplay() method. The InetAddressListCellRenderer class extends MyListCellRenderer to get this to display nice neat Strings for the InetAddresses. I think this whole thing is a little kludgie. I've been playing with it for so long now I'm not getting anywhere anymore. I was hoping somebody would say "gee you ought to go this way" or "no that is really brilliant code my man!" and I'll leave it as is :-). Anyway, please take a look and if you have any great ideas, I would appreciate the feedback. Thanks, import java.awt.*; import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; public class test6 extends JPanel { public test6() throws UnknownHostException { Vector v = new Vector<>(); v.addElement(InetAddress.getByName("216.240.58.139")); v.addElement(InetAddress.getByName("4.2.2.1")); v.addElement(InetAddress.getByName("knutejohnson.com")); v.addElement(InetAddress.getByName("192.168.3.6")); MyJList list = new MyJList<>(new DefaultListModel()); list.setCellRenderer(new InetAddressListCellRenderer()); list.setListData(v); add(list); } public class MyJList extends JList { private final DefaultListModel model; public MyJList(DefaultListModel lm) { super(lm); this.model = lm; } public void setListData(E[] listData) { model.clear(); for (E e : listData) model.addElement(e); } public void setListData(Vector v) { model.clear(); Iterator iter = v.iterator(); while (iter.hasNext()) model.addElement(iter.next()); } } public class MyListCellRenderer extends DefaultListCellRenderer { private final Class clazz; public MyListCellRenderer(Class clazz) { super(); setOpaque(true); setBorder(new EmptyBorder(1,1,1,1)); setName("List.cellRenderer"); this.clazz = clazz; } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setComponentOrientation(list.getComponentOrientation()); UIDefaults defaults = UIManager.getDefaults(); Color bg = null; Color fg = null; JList.DropLocation dropLocation = list.getDropLocation(); if (dropLocation != null && !dropLocation.isInsert() && dropLocation.getIndex() == index) { bg = (Color)defaults.get("List.dropCellBackground"); fg = (Color)defaults.get("List.dropCellForeground"); isSelected = true; } if (isSelected) { setBackground(bg == null ? list.getSelectionBackground() : bg); setForeground(fg == null ? list.getSelectionForeground() : fg); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } if (value instanceof Icon) { setIcon((Icon)value); setText(""); } else if (clazz.isInstance(value)) { setIcon(null); // setText(((InetAddress)value).getHostAddress()); setText(textToDisplay(value)); /* } else { setIcon(null); setText((value == null) ? "" : value.toString()); */ } setEnabled(list.isEnabled()); setFont(list.getFont()); Border border = null; if (cellHasFocus) { if (isSelected) border = (Border)defaults.get( "List.focusSelectedCellHighlightBorder"); if (border == null) border = (Border)defaults.get( "List.focusCellHighlightBorder"); } else border = new EmptyBorder(1,1,1,1); setBorder(border); return this; } public String textToDisplay(Object value) { return value == null ? "" : value.toString(); } } public class InetAddressListCellRenderer extends MyListCellRenderer { public InetAddressListCellRenderer() { super(InetAddress.class); } public String textToDisplay(Object value) { return ((InetAddress)value).getHostAddress(); } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); test6 t6 = new test6(); f.add(t6); f.pack(); f.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } } -- Knute Johnson