Cell Renderers
in Java |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
JComboBox
,
JList
, JTable
,
JTree
) can contain
objects of any class but each must be rendered differently
toString()
method and
renders the String
paint()
method that can
be passed an appropriately configured (i.e., with the
correct bounds) Graphics
objectComponent
and its descendantsJList
/JComboBox
:
JTable
:
Component
:
Component
and implements the
renderer interfaceContainer
:
Container
(e.g., JPanel
),
contains multiple appropriate components using an
appropriate layout, and implements the renderer
interfaceComponent
(e.g., JComponent
),
implements the renderer interface, and
overrides the paint
methodComponent
import java.awt.*; import javax.swing.*; /** * A cell renderer that can be used for cells containing Color objects. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ColorCellRenderer extends JLabel implements ListCellRenderer<Color> { private static final long serialVersionUID = 1L; private static final Font FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12); /** * Default Constructor. */ public ColorCellRenderer() { super(); setOpaque(true); setFont(FONT); } /** * Get the component that does the rendering. * * @param table The JTable that is being rendered * @param value The value of the cell to be rendered * @param isSelected true if the cell is to be rendered with highlighting * @param hasFocise true if the cell has the focus * @param row The row of the cell being rendered * @param column The column of the cell being rendered * @return The Component to use as the renderer */ public Component getListCellRendererComponent(JList<? extends Color> list, Color value, int index, boolean isSelected, boolean hasFocus) { int rr = value.getRed(); int gg = value.getGreen(); int bb = value.getBlue(); setText(String.format("%3d,%3d,%3d", rr, gg, bb)); setForeground(value); if (isSelected) setBorder(BorderFactory.createLineBorder(value)); else setBorder(BorderFactory.createLineBorder(getBackground())); return this; } }
Component
(cont.)
import java.awt.*; import javax.swing.*; /** * A demonstration of a simple ListCellRenderer. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ColorCellRendererDemo implements Runnable { /** * Create the GUI. * * @param args The command line arguments (which are ignored) * @throws Exception if something goes wrong */ public static void main(String[] args) throws Exception { SwingUtilities.invokeAndWait(new ColorCellRendererDemo()); } /** * The code to execute in the event dispatch thread. */ public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(640, 480); JPanel contentPane = (JPanel)f.getContentPane(); Color[] colors = {Color.RED, Color.GREEN, Color.BLUE}; JList<Color> list = new JList<Color>(colors); list.setCellRenderer(new ColorCellRenderer()); contentPane.add(list); f.setVisible(true); } }
Container
/** * A very simple immutable Fraction class that is used in the FractionLabel * class. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class Fraction { private int denominator, numerator; /** * Explicit Value Constructor. * * @param numerator The numerator * @param denominator The denominator */ public Fraction(int numerator, int denominator) { this.numerator = numerator; this.denominator = denominator; } /** * Get the denominator. * * @return The denominator */ public int getDenominator() { return denominator; } /** * Get the numerator. * * @return The numerator */ public int getNumerator() { return numerator; } }
Container
(cont.)
import java.awt.*; import javax.swing.*; /** * A GUI Component that can contain Fraction objects. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class FractionLabel extends JPanel { private static final long serialVersionUID = 1L; private Fraction fraction; private JLabel denominatorLabel, numeratorLabel; /** * Default Constructor. */ public FractionLabel() { super(); JPanel west = new JPanel(); west.setLayout(new GridLayout(2,1)); numeratorLabel = new JLabel(""); numeratorLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, numeratorLabel.getForeground())); west.add(numeratorLabel); denominatorLabel = new JLabel(""); west.add(denominatorLabel); setLayout(new BorderLayout()); add(west, BorderLayout.WEST); } /** * Get the Fraction that is on this Component. * * @return The Fraction */ public Fraction getFraction() { return fraction; } /** * Set the Fraction that is on this Component. * * @param f The Fraction */ public void setFraction(Fraction f) { this.fraction = f; numeratorLabel.setText(String.format("%d", f.getNumerator())); denominatorLabel.setText(String.format("%d", f.getDenominator())); } }
Container
(cont.)
import java.awt.*; import javax.swing.*; /** * A cell renderer that can be used for cells containing Fraction objects. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class FractionCellRenderer extends FractionLabel implements ListCellRenderer<Fraction> { private static final long serialVersionUID = 1L; /** * Default Constructor. */ public FractionCellRenderer() { super(); setOpaque(true); } /** * Get the component that does the rendering. * * @param table The JTable that is being rendered * @param value The value of the cell to be rendered * @param isSelected true if the cell is to be rendered with highlighting * @param hasFocus true if the cell has the focus * @param row The row of the cell being rendered * @param column The column of the cell being rendered * @return The Component to use as the renderer */ public Component getListCellRendererComponent(JList<? extends Fraction> list, Fraction value, int index, boolean isSelected, boolean hasFocus) { setFraction(value); if (isSelected) setBorder(BorderFactory.createLineBorder(getForeground())); else setBorder(BorderFactory.createLineBorder(getBackground())); return this; } }
Container
(cont.)
import javax.swing.*; /** * A demonstration of a simple ListCellRenderer. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class FractionCellRendererDemo implements Runnable { /** * Create the GUI. * * @param args The command line arguments (which are ignored) * @throws Exception if something goes wrong */ public static void main(String[] args) throws Exception { SwingUtilities.invokeAndWait(new FractionCellRendererDemo()); } /** * The code to execute in the event dispatch thread. */ public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(640, 480); JPanel contentPane = (JPanel)f.getContentPane(); Fraction[] fractions = {new Fraction(1,2), new Fraction(3,4), new Fraction(13,16)}; JList<Fraction> list = new JList<Fraction>(fractions); list.setCellRenderer(new FractionCellRenderer()); contentPane.add(list); f.setVisible(true); } }
Component
Component
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.AffineTransform; import javax.swing.*; public class ShapeLabel extends JLabel { private static final long serialVersionUID = 1L; private static final Dimension MINIMUM_SIZE = new Dimension(50,50); private static final Color GOLD = new Color(173, 156, 101); private static final Color PURPLE = new Color( 69, 0, 132); private Shape shape; /** * Default Constructor. */ public ShapeLabel() { super(); shape = null; } /** * Set the Shape. * * @param shape The shape. */ public void setShape(Shape shape) { this.shape = shape; } /** * Get the minimum size of this Component. * * @return The minimum size */ public Dimension getMinimumSize() { return MINIMUM_SIZE; } /** * Get the preferred size of this Component. * * @return The preferred size */ public Dimension getPreferredSize() { Rectangle bounds = shape.getBounds(); return new Dimension((int)bounds.getWidth()+(int)bounds.getX(), (int)bounds.getHeight()+(int)bounds.getY()); } /** * Render this Component. * * @param g The rendering engine to use */ public void paint(Graphics g) { super.paint(g); if (shape != null) { // Remember state information Graphics2D g2 = (Graphics2D)g; AffineTransform at = g2.getTransform(); Color color = g2.getColor(); Paint paint = g2.getPaint(); RenderingHints hints = g2.getRenderingHints(); // Scale appropriately Rectangle componentBounds = getBounds(); Rectangle shapeBounds = shape.getBounds(); double xScale = (double)componentBounds.getWidth() / (double)(shapeBounds.getWidth() + shapeBounds.getX()); double yScale = (double)componentBounds.getHeight() / (double)(shapeBounds.getHeight() + shapeBounds.getY()); double scale = Math.min(xScale, yScale) - 0.10; // Render g2.scale(scale, scale); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(PURPLE); g2.fill(shape); g2.setColor(GOLD); g2.draw(shape); // Reset the state information g2.setPaint(paint); g2.setColor(color); g2.setRenderingHints(hints); g2.setTransform(at); } } }
Component
(cont.)
import java.awt.*; import javax.swing.*; /** * A ListCellRenderer that can be used for a JList containing Shape objects. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ShapeCellRenderer extends ShapeLabel implements ListCellRenderer<Shape> { private static final long serialVersionUID = 1L; /** * Default Constructor. */ public ShapeCellRenderer() { super(); } /** * Get the component that does the rendering. * * @param table The JTable that is being rendered * @param value The value of the cell to be rendered * @param isSelected true if the cell is to be rendered with highlighting * @param hasFocise true if the cell has the focus * @param row The row of the cell being rendered * @param column The column of the cell being rendered * @return The Component to use as the renderer */ public Component getListCellRendererComponent(JList<? extends Shape> list, Shape value, int index, boolean isSelected, boolean cellHasFocus) { if (isSelected) setBorder(BorderFactory.createLineBorder(list.getForeground())); else setBorder(BorderFactory.createLineBorder(list.getBackground())); setShape(value); return this; } }
Component
(cont.)
import java.awt.*; import java.awt.geom.*; import javax.swing.*; /** * A demonstration of a simple ListCellRenderer. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ShapeCellRendererDemo implements Runnable { /** * Create the GUI. * * @param args The command line arguments (which are ignored) * @throws Exception if something goes wrong */ public static void main(String[] args) throws Exception { SwingUtilities.invokeAndWait(new ShapeCellRendererDemo()); } /** * The code to execute in the event dispatch thread. */ public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(640, 480); JPanel contentPane = (JPanel)f.getContentPane(); Shape[] shapes = {new Rectangle2D.Double(10,10,50,50), new Ellipse2D.Double(10, 10, 50, 50), new Arc2D.Double(10, 10, 50, 50, 0., 270., Arc2D.PIE)}; JList<Shape> list = new JList<Shape>(shapes); list.setCellRenderer(new ShapeCellRenderer()); contentPane.add(list); f.setVisible(true); } }