00001
00002
00003
00004
00005
00006
00007 package org.swtchart.internal.axis;
00008
00009 import java.util.ArrayList;
00010
00011 import org.eclipse.swt.SWT;
00012 import org.eclipse.swt.events.PaintEvent;
00013 import org.eclipse.swt.events.PaintListener;
00014 import org.eclipse.swt.graphics.Color;
00015 import org.eclipse.swt.graphics.GC;
00016 import org.eclipse.swt.graphics.Rectangle;
00017 import org.eclipse.swt.widgets.Display;
00018 import org.swtchart.Chart;
00019 import org.swtchart.IAxis.Position;
00020 import org.swtchart.internal.ChartLayoutData;
00021
00025 public class AxisTickMarks implements PaintListener {
00026
00028 private Chart chart;
00029
00031 private Axis axis;
00032
00034 private Color foreground;
00035
00037 private int widthHint;
00038
00040 private int heightHint;
00041
00043 private Rectangle bounds;
00044
00046 protected static final int LINE_WIDTH = 1;
00047
00049 public static final int TICK_LENGTH = 5;
00050
00052 private static final int DEFAULT_FOREGROUND = SWT.COLOR_BLUE;
00053
00062 public AxisTickMarks(Chart chart, Axis axis) {
00063 this.chart = chart;
00064 this.axis = axis;
00065
00066 foreground = Display.getDefault().getSystemColor(DEFAULT_FOREGROUND);
00067 chart.addPaintListener(this);
00068 }
00069
00076 public void setForeground(Color color) {
00077 if (color == null) {
00078 foreground = Display.getDefault()
00079 .getSystemColor(DEFAULT_FOREGROUND);
00080 } else {
00081 foreground = color;
00082 }
00083 }
00084
00090 protected Color getForeground() {
00091 if (foreground.isDisposed()) {
00092 foreground = Display.getDefault()
00093 .getSystemColor(DEFAULT_FOREGROUND);
00094 }
00095 return foreground;
00096 }
00097
00103 public Axis getAxis() {
00104 return axis;
00105 }
00106
00110 protected void updateLayoutData() {
00111 widthHint = SWT.DEFAULT;
00112 heightHint = SWT.DEFAULT;
00113 if (!axis.getTick().isVisible()) {
00114 widthHint = 0;
00115 heightHint = 0;
00116 } else {
00117 if (axis.isHorizontalAxis()) {
00118 heightHint = Axis.MARGIN + TICK_LENGTH;
00119 } else {
00120 widthHint = TICK_LENGTH + Axis.MARGIN;
00121 }
00122 }
00123 }
00124
00130 public ChartLayoutData getLayoutData() {
00131 return new ChartLayoutData(widthHint, heightHint);
00132 }
00133
00146 public void setBounds(int x, int y, int width, int height) {
00147 bounds = new Rectangle(x, y, width, height);
00148 }
00149
00155 protected Rectangle getBounds() {
00156 return bounds;
00157 }
00158
00162 protected void dispose() {
00163 if (!chart.isDisposed()) {
00164 chart.removePaintListener(this);
00165 }
00166 }
00167
00168
00169
00170
00171 public void paintControl(PaintEvent e) {
00172 ArrayList<Integer> tickLabelPositions = axis.getTick()
00173 .getAxisTickLabels().getTickLabelPositions();
00174 Color oldBackground = e.gc.getBackground();
00175 e.gc.setBackground(chart.getBackground());
00176 Color oldForeground = e.gc.getForeground();
00177 e.gc.setForeground(getForeground());
00178 Rectangle oldClipping = e.gc.getClipping();
00179 e.gc.setClipping(bounds);
00180
00181 if (axis.isHorizontalAxis()) {
00182 drawXTickMarks(e.gc, tickLabelPositions, axis.getPosition());
00183 } else {
00184 drawYTickMarks(e.gc, tickLabelPositions, axis.getPosition());
00185 }
00186
00187 e.gc.setClipping(oldClipping);
00188 e.gc.setBackground(oldBackground);
00189 e.gc.setForeground(oldForeground);
00190 }
00191
00202 private void drawXTickMarks(GC gc, ArrayList<Integer> tickLabelPositions,
00203 Position position) {
00204
00205
00206 gc.setLineStyle(SWT.LINE_SOLID);
00207 if (axis.isValidCategoryAxis()) {
00208 if (tickLabelPositions.size() > 1) {
00209 int step = tickLabelPositions.get(1).intValue()
00210 - tickLabelPositions.get(0).intValue();
00211 for (int i = 0; i < tickLabelPositions.size() + 1; i++) {
00212 int x;
00213 if (i < tickLabelPositions.size()) {
00214 x = (int) (tickLabelPositions.get(i).intValue() - step / 2d);
00215 } else {
00216 x = (int) (tickLabelPositions.get(i - 1).intValue() + step / 2d);
00217 }
00218 int y = 0;
00219 if (position == Position.Secondary) {
00220 y = bounds.height - 1 - LINE_WIDTH - TICK_LENGTH;
00221 }
00222 gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x,
00223 bounds.y + y + TICK_LENGTH);
00224 }
00225 }
00226 } else {
00227 for (int i = 0; i < tickLabelPositions.size(); i++) {
00228 int x = tickLabelPositions.get(i);
00229 int y = 0;
00230 if (position == Position.Secondary) {
00231 y = bounds.height - 1 - LINE_WIDTH - TICK_LENGTH;
00232 }
00233 gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x, bounds.y
00234 + y + TICK_LENGTH);
00235 }
00236 }
00237
00238
00239 if (position == Position.Primary) {
00240 gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width - 1,
00241 bounds.y);
00242 } else {
00243 gc.drawLine(bounds.x, bounds.y + bounds.height - 1, bounds.x
00244 + bounds.width - 1, bounds.y + bounds.height - 1);
00245 }
00246 }
00247
00258 private void drawYTickMarks(GC gc, ArrayList<Integer> tickLabelPositions,
00259 Position position) {
00260
00261
00262 gc.setLineStyle(SWT.LINE_SOLID);
00263 if (axis.isValidCategoryAxis()) {
00264 if (tickLabelPositions.size() > 1) {
00265 int step = tickLabelPositions.get(1).intValue()
00266 - tickLabelPositions.get(0).intValue();
00267 for (int i = 0; i < tickLabelPositions.size() + 1; i++) {
00268 int x = 0;
00269 int y;
00270 if (i < tickLabelPositions.size()) {
00271 y = (int) (tickLabelPositions.get(i).intValue() - step / 2d);
00272 } else {
00273 y = (int) (tickLabelPositions.get(i - 1).intValue() + step / 2d);
00274 }
00275
00276 if (position == Position.Primary) {
00277 x = bounds.width - 1 - LINE_WIDTH - TICK_LENGTH;
00278 } else {
00279 x = LINE_WIDTH;
00280 }
00281 gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x
00282 + TICK_LENGTH, bounds.y + y);
00283 }
00284 }
00285 } else {
00286 int y = 0;
00287 for (int i = 0; i < tickLabelPositions.size(); i++) {
00288 int x = 0;
00289 if (position == Position.Primary) {
00290 x = bounds.width - 1 - LINE_WIDTH - TICK_LENGTH;
00291 } else {
00292 x = LINE_WIDTH;
00293 }
00294 y = bounds.height - 1 - tickLabelPositions.get(i);
00295 gc.drawLine(bounds.x + x, bounds.y + y, bounds.x + x
00296 + TICK_LENGTH, bounds.y + y);
00297 }
00298 }
00299
00300
00301 if (position == Position.Primary) {
00302 gc.drawLine(bounds.x + bounds.width - 1, bounds.y, bounds.x
00303 + bounds.width - 1, bounds.y + bounds.height - 1);
00304 } else {
00305 gc.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height
00306 - 1);
00307 }
00308 }
00309 }