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


Attachment: 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
}

Reply via email to