A simple extension of JTable that supports the use of a SortableTableModel.
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------------
* SortableTable.java
* ------------------
* (C) Copyright 2000-2004, by Object Refinery Limited.
*
* Original Author: David Gilbert (for Object Refinery Limited);
* Contributor(s): -;
*
* $Id: SortableTable.java,v 1.5 2005/11/16 15:58:41 taqua Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
/**
* A simple extension of JTable that supports the use of a SortableTableModel.
*
* @author David Gilbert
*/
public class SortableTable extends JTable {
/** A listener for sorting. */
private SortableTableHeaderListener headerListener;
/**
* Standard constructor - builds a table for the specified model.
*
* @param model the data.
*/
public SortableTable(final SortableTableModel model) {
super(model);
final SortButtonRenderer renderer = new SortButtonRenderer();
final TableColumnModel cm = getColumnModel();
for (int i = 0; i < cm.getColumnCount(); i++) {
cm.getColumn(i).setHeaderRenderer(renderer);
}
final JTableHeader header = getTableHeader();
this.headerListener = new SortableTableHeaderListener(model, renderer);
header.addMouseListener(this.headerListener);
header.addMouseMotionListener(this.headerListener);
model.sortByColumn(0, true);
}
/**
* Changes the model for the table. Takes care of updating the header listener at the
* same time.
*
* @param model the table model.
*
*/
public void setSortableModel(final SortableTableModel model) {
super.setModel(model);
this.headerListener.setTableModel(model);
final SortButtonRenderer renderer = new SortButtonRenderer();
final TableColumnModel cm = getColumnModel();
for (int i = 0; i < cm.getColumnCount(); i++) {
cm.getColumn(i).setHeaderRenderer(renderer);
}
model.sortByColumn(0, true);
}
}
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* --------------------------------
* SortableTableHeaderListener.java
* --------------------------------
* (C) Copyright 2000-2004, by Nabuo Tamemasa and Contributors.
*
* Original Author: Nabuo Tamemasa;
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* $Id: SortableTableHeaderListener.java,v 1.5 2007/11/02 17:50:36 taqua Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/
/**
* Captures mouse clicks on a table header, with the intention of triggering a sort. Adapted from
* code by Nabuo Tamemasa posted on http://www.codeguru.com.
*
* @author Nabuo Tamemasa
*/
class SortableTableHeaderListener implements MouseListener, MouseMotionListener {
/** A reference to the table model. */
private SortableTableModel model;
/** The header renderer. */
private SortButtonRenderer renderer;
/** The index of the column that is sorted - used to determine the state of the renderer. */
private int sortColumnIndex;
/**
* Standard constructor.
*
* @param model the model.
* @param renderer the renderer.
*/
public SortableTableHeaderListener(final SortableTableModel model,
final SortButtonRenderer renderer) {
this.model = model;
this.renderer = renderer;
}
/**
* Sets the table model for the listener.
*
* @param model the model.
*/
public void setTableModel(final SortableTableModel model) {
this.model = model;
}
/**
* Handle a mouse press event - if the user is NOT resizing a column and NOT dragging a column
* then give visual feedback that the column header has been pressed.
*
* @param e the mouse event.
*/
public void mousePressed(final MouseEvent e) {
final JTableHeader header = (JTableHeader) e.getComponent();
if (header.getResizingColumn() == null) { // resizing takes precedence over sorting
if (header.getDraggedDistance() < 1) { // dragging also takes precedence over sorting
final int columnIndex = header.columnAtPoint(e.getPoint());
final int modelColumnIndex
= header.getTable().convertColumnIndexToModel(columnIndex);
if (this.model.isSortable(modelColumnIndex)) {
this.sortColumnIndex = header.getTable().convertColumnIndexToModel(columnIndex);
this.renderer.setPressedColumn(this.sortColumnIndex);
header.repaint();
if (header.getTable().isEditing()) {
header.getTable().getCellEditor().stopCellEditing();
}
}
else {
this.sortColumnIndex = -1;
}
}
}
}
/**
* If the user is dragging or resizing, then we clear the sort column.
*
* @param e the mouse event.
*/
public void mouseDragged(final MouseEvent e) {
final JTableHeader header = (JTableHeader) e.getComponent();
if ((header.getDraggedDistance() > 0) || (header.getResizingColumn() != null)) {
this.renderer.setPressedColumn(-1);
this.sortColumnIndex = -1;
}
}
/**
* This event is ignored (not required).
*
* @param e the mouse event.
*/
public void mouseEntered(final MouseEvent e) {
// not required
}
/**
* This event is ignored (not required).
*
* @param e the mouse event.
*/
public void mouseClicked(final MouseEvent e) {
// not required
}
/**
* This event is ignored (not required).
*
* @param e the mouse event.
*/
public void mouseMoved(final MouseEvent e) {
// not required
}
/**
* This event is ignored (not required).
*
* @param e the mouse event.
*/
public void mouseExited(final MouseEvent e) {
// not required
}
/**
* When the user releases the mouse button, we attempt to sort the table.
*
* @param e the mouse event.
*/
public void mouseReleased(final MouseEvent e) {
final JTableHeader header = (JTableHeader) e.getComponent();
if (header.getResizingColumn() == null) { // resizing takes precedence over sorting
if (this.sortColumnIndex != -1) {
final SortableTableModel model = (SortableTableModel) header.getTable().getModel();
final boolean ascending = !model.isAscending();
model.setAscending(ascending);
model.sortByColumn(this.sortColumnIndex, ascending);
this.renderer.setPressedColumn(-1); // clear
header.repaint();
}
}
}
}
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------------
* SortableTableModel.java
* -----------------------
* (C) Copyright 2000-2005, by Object Refinery Limited;
*
* Original Author: David Gilbert (for Object Refinery Limited);
* Contributor(s): -;
*
* $Id: SortableTableModel.java,v 1.6 2008/09/10 09:26:11 mungady Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.* (DG);
* 20-Nov-2001 : Made constructor protected (DG);
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/
/**
* The base class for a sortable table model.
*
* @author David Gilbert
*/
abstract class SortableTableModel extends AbstractTableModel {
/** The column on which the data is sorted (-1 for no sorting). */
private int sortingColumn;
/** Indicates ascending (true) or descending (false) order. */
private boolean ascending;
/**
* Constructs a sortable table model.
*/
public SortableTableModel() {
this.sortingColumn = -1;
this.ascending = true;
}
/**
* Returns the index of the sorting column, or -1 if the data is not sorted
* on any column.
*
* @return the column used for sorting.
*/
public int getSortingColumn() {
return this.sortingColumn;
}
/**
* Returns <code>true</code> if the data is sorted in ascending order, and
* <code>false</code> otherwise.
*
* @return <code>true</code> if the data is sorted in ascending order, and
* <code>false</code> otherwise.
*/
public boolean isAscending() {
return this.ascending;
}
/**
* Sets the flag that determines whether the sort order is ascending or
* descending.
*
* @param flag the flag.
*/
public void setAscending(final boolean flag) {
this.ascending = flag;
}
/**
* Sorts the table.
*
* @param column the column to sort on (zero-based index).
* @param ascending a flag to indicate ascending order or descending order.
*/
public void sortByColumn(final int column, final boolean ascending) {
if (isSortable(column)) {
this.sortingColumn = column;
}
}
/**
* Returns a flag indicating whether or not a column is sortable.
*
* @param column the column (zero-based index).
*
* @return boolean.
*/
public boolean isSortable(final int column) {
return false;
}
}
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------------
* SortButtonRenderer.java
* -----------------------
* (C) Copyright 2000-2004, by Nobuo Tamemasa and Contributors.
*
* Original Author: Nobuo Tamemasa;
* Contributor(s): David Gilbert (for Object Refinery Limited);
* Gareth Davis;
*
* $Id: SortButtonRenderer.java,v 1.7 2008/09/10 09:26:11 mungady Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.* (DG);
* 26-Jun-2002 : Removed unnecessary import (DG);
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/
/**
* A table cell renderer for table headings - uses one of three JButton instances to indicate the
* sort order for the table column.
* <P>
* This class (and also BevelArrowIcon) is adapted from original code by Nobuo Tamemasa (version
* 1.0, 26-Feb-1999) posted on www.codeguru.com.
*
* @author David Gilbert
*/
class SortButtonRenderer implements TableCellRenderer {
/**
* Useful constant indicating NO sorting.
*/
public static final int NONE = 0;
/**
* Useful constant indicating ASCENDING (that is, arrow pointing down) sorting in the table.
*/
public static final int DOWN = 1;
/**
* Useful constant indicating DESCENDING (that is, arrow pointing up) sorting in the table.
*/
public static final int UP = 2;
/**
* The current pressed column (-1 for no column).
*/
private int pressedColumn = -1;
/**
* The three buttons that are used to render the table header cells.
*/
private JButton normalButton;
/**
* The three buttons that are used to render the table header cells.
*/
private JButton ascendingButton;
/**
* The three buttons that are used to render the table header cells.
*/
private JButton descendingButton;
/**
* Used to allow the class to work out whether to use the buttuns
* or labels. Labels are required when using the aqua look and feel cos the
* buttons won't fit.
*/
private boolean useLabels;
/**
* The normal label (only used with MacOSX).
*/
private JLabel normalLabel;
/**
* The ascending label (only used with MacOSX).
*/
private JLabel ascendingLabel;
/**
* The descending label (only used with MacOSX).
*/
private JLabel descendingLabel;
/**
* Creates a new button renderer.
*/
public SortButtonRenderer() {
this.pressedColumn = -1;
this.useLabels = UIManager.getLookAndFeel().getID().equals("Aqua");
final Border border = UIManager.getBorder("TableHeader.cellBorder");
if (this.useLabels) {
this.normalLabel = new JLabel();
this.normalLabel.setHorizontalAlignment(SwingConstants.LEADING);
this.ascendingLabel = new JLabel();
this.ascendingLabel.setHorizontalAlignment(SwingConstants.LEADING);
this.ascendingLabel.setHorizontalTextPosition(SwingConstants.LEFT);
this.ascendingLabel.setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));
this.descendingLabel = new JLabel();
this.descendingLabel.setHorizontalAlignment(SwingConstants.LEADING);
this.descendingLabel.setHorizontalTextPosition(SwingConstants.LEFT);
this.descendingLabel.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false));
this.normalLabel.setBorder(border);
this.ascendingLabel.setBorder(border);
this.descendingLabel.setBorder(border);
}
else {
this.normalButton = new JButton();
this.normalButton.setMargin(new Insets(0, 0, 0, 0));
this.normalButton.setHorizontalAlignment(SwingConstants.LEADING);
this.ascendingButton = new JButton();
this.ascendingButton.setMargin(new Insets(0, 0, 0, 0));
this.ascendingButton.setHorizontalAlignment(SwingConstants.LEADING);
this.ascendingButton.setHorizontalTextPosition(SwingConstants.LEFT);
this.ascendingButton.setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));
this.ascendingButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, true));
this.descendingButton = new JButton();
this.descendingButton.setMargin(new Insets(0, 0, 0, 0));
this.descendingButton.setHorizontalAlignment(SwingConstants.LEADING);
this.descendingButton.setHorizontalTextPosition(SwingConstants.LEFT);
this.descendingButton.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false));
this.descendingButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, true));
this.normalButton.setBorder(border);
this.ascendingButton.setBorder(border);
this.descendingButton.setBorder(border);
}
}
/**
* Returns the renderer component.
*
* @param table the table.
* @param value the value.
* @param isSelected selected?
* @param hasFocus focussed?
* @param row the row.
* @param column the column.
* @return the renderer.
*/
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row, final int column) {
if (table == null) {
throw new NullPointerException("Table must not be null.");
}
final JComponent component;
final SortableTableModel model = (SortableTableModel) table.getModel();
final int cc = table.convertColumnIndexToModel(column);
final boolean isSorting = (model.getSortingColumn() == cc);
final boolean isAscending = model.isAscending();
final JTableHeader header = table.getTableHeader();
final boolean isPressed = (cc == this.pressedColumn);
if (this.useLabels) {
final JLabel label = getRendererLabel(isSorting, isAscending);
label.setText((value == null) ? "" : value.toString());
component = label;
}
else {
final JButton button = getRendererButton(isSorting, isAscending);
button.setText((value == null) ? "" : value.toString());
button.getModel().setPressed(isPressed);
button.getModel().setArmed(isPressed);
component = button;
}
if (header != null) {
component.setForeground(header.getForeground());
component.setBackground(header.getBackground());
component.setFont(header.getFont());
}
return component;
}
/**
* Returns the correct button component.
*
* @param isSorting whether the render component represents the sort column.
* @param isAscending whether the model is ascending.
* @return either the ascending, descending or normal button.
*/
private JButton getRendererButton(final boolean isSorting, final boolean isAscending) {
if (isSorting) {
if (isAscending) {
return this.ascendingButton;
}
else {
return this.descendingButton;
}
}
else {
return this.normalButton;
}
}
/**
* Returns the correct label component.
*
* @param isSorting whether the render component represents the sort column.
* @param isAscending whether the model is ascending.
* @return either the ascending, descending or normal label.
*/
private JLabel getRendererLabel(final boolean isSorting, final boolean isAscending) {
if (isSorting) {
if (isAscending) {
return this.ascendingLabel;
}
else {
return this.descendingLabel;
}
}
else {
return this.normalLabel;
}
}
/**
* Sets the pressed column.
*
* @param column the column.
*/
public void setPressedColumn(final int column) {
this.pressedColumn = column;
}
}
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -------------------
* BevelArrowIcon.java
* -------------------
* (C) Copyright 2000-2004, by Nobuo Tamemasa and Contributors.
*
* Original Author: Nobuo Tamemasa;
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* $Id: BevelArrowIcon.java,v 1.5 2007/11/02 17:50:36 taqua Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 13-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/
/**
* An arrow icon that can point up or down (usually used to indicate the sort direction in a table).
* <P>
* This class (and also SortButtonRenderer) is based on original code by Nobuo Tamemasa (version
* 1.0, 26-Feb-1999) posted on www.codeguru.com.
*
* @author Nobuo Tamemasa
*/
class BevelArrowIcon implements Icon {
/** Constant indicating that the arrow is pointing up. */
public static final int UP = 0;
/** Constant indicating that the arrow is pointing down. */
public static final int DOWN = 1;
/** The default arrow size. */
private static final int DEFAULT_SIZE = 11;
/** Edge color 1. */
private Color edge1;
/** Edge color 2. */
private Color edge2;
/** The fill color for the arrow icon. */
private Color fill;
/** The size of the icon. */
private int size;
/** The direction that the arrow is pointing (UP or DOWN). */
private int direction;
/**
* Standard constructor - builds an icon with the specified attributes.
*
* @param direction .
* @param isRaisedView .
* @param isPressedView .
*/
public BevelArrowIcon(final int direction,
final boolean isRaisedView,
final boolean isPressedView) {
if (isRaisedView) {
if (isPressedView) {
init(UIManager.getColor("controlLtHighlight"),
UIManager.getColor("controlDkShadow"),
UIManager.getColor("controlShadow"),
DEFAULT_SIZE, direction);
}
else {
init(UIManager.getColor("controlHighlight"),
UIManager.getColor("controlShadow"),
UIManager.getColor("control"),
DEFAULT_SIZE, direction);
}
}
else {
if (isPressedView) {
init(UIManager.getColor("controlDkShadow"),
UIManager.getColor("controlLtHighlight"),
UIManager.getColor("controlShadow"),
DEFAULT_SIZE, direction);
}
else {
init(UIManager.getColor("controlShadow"),
UIManager.getColor("controlHighlight"),
UIManager.getColor("control"),
DEFAULT_SIZE, direction);
}
}
}
/**
* Standard constructor - builds an icon with the specified attributes.
*
* @param edge1 the color of edge1.
* @param edge2 the color of edge2.
* @param fill the fill color.
* @param size the size of the arrow icon.
* @param direction the direction that the arrow points.
*/
public BevelArrowIcon(final Color edge1,
final Color edge2,
final Color fill,
final int size,
final int direction) {
init(edge1, edge2, fill, size, direction);
}
/**
* Paints the icon at the specified position. Supports the Icon interface.
*
* @param c .
* @param g .
* @param x .
* @param y .
*/
public void paintIcon(final Component c,
final Graphics g,
final int x,
final int y) {
switch (this.direction) {
case DOWN: drawDownArrow(g, x, y); break;
case UP: drawUpArrow(g, x, y); break;
}
}
/**
* Returns the width of the icon. Supports the Icon interface.
*
* @return the icon width.
*/
public int getIconWidth() {
return this.size;
}
/**
* Returns the height of the icon. Supports the Icon interface.
* @return the icon height.
*/
public int getIconHeight() {
return this.size;
}
/**
* Initialises the attributes of the arrow icon.
*
* @param edge1 the color of edge1.
* @param edge2 the color of edge2.
* @param fill the fill color.
* @param size the size of the arrow icon.
* @param direction the direction that the arrow points.
*/
private void init(final Color edge1,
final Color edge2,
final Color fill,
final int size,
final int direction) {
this.edge1 = edge1;
this.edge2 = edge2;
this.fill = fill;
this.size = size;
this.direction = direction;
}
/**
* Draws the arrow pointing down.
*
* @param g the graphics device.
* @param xo ??
* @param yo ??
*/
private void drawDownArrow(final Graphics g, final int xo, final int yo) {
g.setColor(this.edge1);
g.drawLine(xo, yo, xo + this.size - 1, yo);
g.drawLine(xo, yo + 1, xo + this.size - 3, yo + 1);
g.setColor(this.edge2);
g.drawLine(xo + this.size - 2, yo + 1, xo + this.size - 1, yo + 1);
int x = xo + 1;
int y = yo + 2;
int dx = this.size - 6;
while (y + 1 < yo + this.size) {
g.setColor(this.edge1);
g.drawLine(x, y, x + 1, y);
g.drawLine(x, y + 1, x + 1, y + 1);
if (0 < dx) {
g.setColor(this.fill);
g.drawLine(x + 2, y, x + 1 + dx, y);
g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
}
g.setColor(this.edge2);
g.drawLine(x + dx + 2, y, x + dx + 3, y);
g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
x += 1;
y += 2;
dx -= 2;
}
g.setColor(this.edge1);
g.drawLine(
xo + (this.size / 2), yo + this.size - 1, xo + (this.size / 2), yo + this.size - 1
);
}
/**
* Draws the arrow pointing up.
*
* @param g the graphics device.
* @param xo ??
* @param yo ??
*/
private void drawUpArrow(final Graphics g, final int xo, final int yo) {
g.setColor(this.edge1);
int x = xo + (this.size / 2);
g.drawLine(x, yo, x, yo);
x--;
int y = yo + 1;
int dx = 0;
while (y + 3 < yo + this.size) {
g.setColor(this.edge1);
g.drawLine(x, y, x + 1, y);
g.drawLine(x, y + 1, x + 1, y + 1);
if (0 < dx) {
g.setColor(this.fill);
g.drawLine(x + 2, y, x + 1 + dx, y);
g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
}
g.setColor(this.edge2);
g.drawLine(x + dx + 2, y, x + dx + 3, y);
g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
x -= 1;
y += 2;
dx += 2;
}
g.setColor(this.edge1);
g.drawLine(xo, yo + this.size - 3, xo + 1, yo + this.size - 3);
g.setColor(this.edge2);
g.drawLine(xo + 2, yo + this.size - 2, xo + this.size - 1, yo + this.size - 2);
g.drawLine(xo, yo + this.size - 1, xo + this.size, yo + this.size - 1);
}
}
Related examples in the same category