Here is a second sample. It's not really a real-world sample, but should be useful to show that also JList of other "value" types than String, such as Integer, Long and Short, can profit from generics.
It also shows why JList should specify ListCellRenderer<? super E> cellRenderer rather than ListCellRenderer<E> cellRenderer (Here: a common Number-cell renderer is used.) -Florian Am Dienstag, 3. März 2009 schrieb Alexander Potochkin: > Hello Tom > > It's nice to see you here > > >> Could you please provide a complete example of a JList > >> with a custom ListCellRenderer that proves that renderer should be > >> generified > > > > I bet if you used NetBeans to find implementations of ListCellRenderer > > even within the JDK most useful implementations would cast the value > > argument. > > anyway, it is always better to have a fixed set of examples to discuss > > > (I prefer option 3, btw.) > > Thanks > alexp > > > Tom Hawtin
ListSample2Frame.form
Description: XML document
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package listsample2; import java.awt.Component; import java.text.NumberFormat; import javax.swing.DefaultListCellRenderer; import javax.swing.JList; import javax.swing.ListCellRenderer; /** * * @author puce */ public class NumberCellRenderer implements ListCellRenderer { private final ListCellRenderer delegateRenderer = new DefaultListCellRenderer(); public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { // runtime exception if value is not a number; could be checked with generics String formattedNumber = NumberFormat.getInstance().format(value); return delegateRenderer.getListCellRendererComponent(list, formattedNumber, index, isSelected, cellHasFocus); } }
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ /* * ListSample2Frame.java * * Created on 04.03.2009, 00:14:32 */ package listsample2; import java.text.NumberFormat; import java.util.Vector; import javax.swing.ListCellRenderer; /** * * @author puce */ public class ListSample2Frame extends javax.swing.JFrame { /** Creates new form ListSample2Frame */ public ListSample2Frame() { initComponents(); // use the same number cell renderer for Integer, Long and Short list ListCellRenderer numberCellRenderer = new NumberCellRenderer(); Vector<Integer> integers = new Vector<Integer>(); integers.add(1000); integers.add(-1000); integers.add(2000); integers.add(-2000); integers.add(4000); integers.add(-4000); integers.add(8000); integers.add(-8000); integers.add(16000); integers.add(-16000); integerValuesList.setListData(integers); integerValuesList.setCellRenderer(numberCellRenderer); Vector<Long> longs = new Vector<Long>(); longs.add(1000L); longs.add(-1000L); longs.add(2000L); longs.add(-2000L); longs.add(4000L); longs.add(-4000L); longs.add(8000L); longs.add(-8000L); longs.add(16000L); longs.add(-16000L); longValuesList.setListData(longs); longValuesList.setCellRenderer(numberCellRenderer); Vector<Short> shorts = new Vector<Short>(); short aShort =1000; shorts.add(aShort); aShort =-1000; shorts.add(aShort); aShort =2000; shorts.add(aShort); aShort =-2000; shorts.add(aShort); aShort =4000; shorts.add(aShort); aShort =-4000; shorts.add(aShort); aShort =8000; shorts.add(aShort); aShort =-8000; shorts.add(aShort); aShort =16000; shorts.add(aShort); aShort =-16000; shorts.add(aShort); shortValuesList.setListData(shorts); shortValuesList.setCellRenderer(numberCellRenderer); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; integerValuesLabel = new javax.swing.JLabel(); integerValuesScrollPane = new javax.swing.JScrollPane(); integerValuesList = new javax.swing.JList(); longValuesLabel = new javax.swing.JLabel(); longValuesScrollPane = new javax.swing.JScrollPane(); longValuesList = new javax.swing.JList(); shortValuesLabel = new javax.swing.JLabel(); shortValuesScrollPane = new javax.swing.JScrollPane(); shortValuesList = new javax.swing.JList(); integerValueCaptionLabel = new javax.swing.JLabel(); integerLabel = new javax.swing.JLabel(); longValueCaptionLabel = new javax.swing.JLabel(); longLabel = new javax.swing.JLabel(); shortValueCaptionLabel = new javax.swing.JLabel(); shortLabel = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("List Sample 2"); integerValuesLabel.setText("Integer Values:"); integerValuesScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); integerValuesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); integerValuesList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { public void valueChanged(javax.swing.event.ListSelectionEvent evt) { integerValuesListValueChanged(evt); } }); integerValuesScrollPane.setViewportView(integerValuesList); longValuesLabel.setText("Long Values:"); longValuesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); longValuesList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { public void valueChanged(javax.swing.event.ListSelectionEvent evt) { longValuesListValueChanged(evt); } }); longValuesScrollPane.setViewportView(longValuesList); shortValuesLabel.setText("Short Values:"); shortValuesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); shortValuesList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { public void valueChanged(javax.swing.event.ListSelectionEvent evt) { shortValuesListValueChanged(evt); } }); shortValuesScrollPane.setViewportView(shortValuesList); integerValueCaptionLabel.setText("Absolute Integer Value:"); longValueCaptionLabel.setText("Absolute Long Value:"); shortValueCaptionLabel.setText("Absolute Short Value:"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(25, 25, 25) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(integerValuesLabel) .addComponent(longValuesLabel) .addComponent(shortValuesLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(integerValuesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(longValuesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(shortValuesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(25, 25, 25) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(integerValueCaptionLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(integerLabel)) .addGroup(layout.createSequentialGroup() .addComponent(shortValueCaptionLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(shortLabel)) .addGroup(layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(longValueCaptionLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(longLabel)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(27, 27, 27) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(integerValuesLabel) .addComponent(integerValuesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(integerValueCaptionLabel) .addComponent(integerLabel))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(longValuesLabel) .addComponent(longValuesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(longValueCaptionLabel) .addComponent(longLabel))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(shortValuesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(shortValuesLabel) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(shortValueCaptionLabel) .addComponent(shortLabel))) .addContainerGap(35, Short.MAX_VALUE)) ); pack(); }// </editor-fold>//GEN-END:initComponents private void integerValuesListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_integerValuesListValueChanged if (!evt.getValueIsAdjusting()) { if (integerValuesList.isSelectionEmpty()) { integerLabel.setText(""); } else { // cast needed because JList doesn't use generics int selectedInteger = (Integer) integerValuesList. getSelectedValue(); // do something with the selected integer value selectedInteger *= Integer.signum(selectedInteger); integerLabel.setText(NumberFormat.getInstance().format( selectedInteger)); } } }//GEN-LAST:event_integerValuesListValueChanged private void longValuesListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_longValuesListValueChanged if (!evt.getValueIsAdjusting()) { if (longValuesList.isSelectionEmpty()) { longLabel.setText(""); } else { // cast needed because JList doesn't use generics long selectedLong = (Long) longValuesList.getSelectedValue(); // do something with the selected long value selectedLong *= Long.signum(selectedLong); longLabel.setText(NumberFormat.getInstance().format( selectedLong)); } } }//GEN-LAST:event_longValuesListValueChanged private void shortValuesListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_shortValuesListValueChanged if (!evt.getValueIsAdjusting()) { if (shortValuesList.isSelectionEmpty()) { shortLabel.setText(""); } else { // cast needed because JList doesn't use generics short selectedShort = (Short) shortValuesList. getSelectedValue(); // do something with the selected short value selectedShort *= Integer.signum(selectedShort); shortLabel.setText(NumberFormat.getInstance().format( selectedShort)); } } }//GEN-LAST:event_shortValuesListValueChanged /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new ListSample2Frame().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel integerLabel; private javax.swing.JLabel integerValueCaptionLabel; private javax.swing.JLabel integerValuesLabel; private javax.swing.JList integerValuesList; private javax.swing.JScrollPane integerValuesScrollPane; private javax.swing.JLabel longLabel; private javax.swing.JLabel longValueCaptionLabel; private javax.swing.JLabel longValuesLabel; private javax.swing.JList longValuesList; private javax.swing.JScrollPane longValuesScrollPane; private javax.swing.JLabel shortLabel; private javax.swing.JLabel shortValueCaptionLabel; private javax.swing.JLabel shortValuesLabel; private javax.swing.JList shortValuesList; private javax.swing.JScrollPane shortValuesScrollPane; // End of variables declaration//GEN-END:variables }