PageRenderTime 329ms CodeModel.GetById 23ms app.highlight 263ms RepoModel.GetById 2ms app.codeStats 1ms

/trunk/org.mwc.cmap.TimeController/src/com/visutools/nav/bislider/BiSliderPresentation.java

https://bitbucket.org/haris_peco/debrief
Java | 1437 lines | 996 code | 210 blank | 231 comment | 271 complexity | 5aa582ce331ca49358a3da68e2e205ac MD5 | raw file
   1package com.visutools.nav.bislider;
   2
   3import java.awt.AWTException;
   4import java.awt.BorderLayout;
   5import java.awt.Color;
   6import java.awt.Dimension;
   7import java.awt.Font;
   8import java.awt.FontMetrics;
   9import java.awt.Graphics;
  10import java.awt.Graphics2D;
  11import java.awt.Point;
  12import java.awt.Polygon;
  13import java.awt.Rectangle;
  14import java.awt.RenderingHints;
  15import java.awt.Robot;
  16import java.awt.Shape;
  17import java.awt.SystemColor;
  18import java.awt.event.ActionEvent;
  19import java.awt.event.ActionListener;
  20import java.awt.event.ComponentEvent;
  21import java.awt.event.ComponentListener;
  22import java.awt.event.InputEvent;
  23import java.awt.event.KeyAdapter;
  24import java.awt.event.KeyEvent;
  25import java.awt.event.MouseAdapter;
  26import java.awt.event.MouseEvent;
  27import java.awt.event.MouseListener;
  28import java.awt.event.MouseMotionListener;
  29import java.awt.geom.Rectangle2D;
  30import java.awt.geom.RoundRectangle2D;
  31import java.io.Serializable;
  32import java.text.ParseException;
  33import java.util.Hashtable;
  34import java.util.Vector;
  35
  36import javax.swing.BorderFactory;
  37import javax.swing.JComponent;
  38import javax.swing.JLabel;
  39import javax.swing.JPanel;
  40import javax.swing.JSlider;
  41import javax.swing.JTextField;
  42import javax.swing.Popup;
  43import javax.swing.PopupFactory;
  44import javax.swing.SwingConstants;
  45import javax.swing.SwingUtilities;
  46import javax.swing.UIManager;
  47import javax.swing.event.ChangeEvent;
  48import javax.swing.event.ChangeListener;
  49import javax.swing.event.DocumentEvent;
  50import javax.swing.event.DocumentListener;
  51import javax.swing.plaf.ColorUIResource;
  52import javax.swing.plaf.metal.MetalLookAndFeel;
  53
  54import MWC.Utilities.ReaderWriter.XML.MWCXMLReader;
  55
  56/**
  57 * The graphical interface of the bean (drawing and mouse event handling). <br>
  58 * <br>
  59 * <table border=1 width="90%">
  60 * <tr>
  61 * <td> Copyright 1997-2005 Frederic Vernier. All Rights Reserved.<br>
  62 * <br>
  63 * Permission to use, copy, modify and distribute this software and its
  64 * documentation for educational, research and non-profit purposes, without fee,
  65 * and without a written agreement is hereby granted, provided that the above
  66 * copyright notice and the following three paragraphs appear in all copies.<br>
  67 * <br>
  68 * To request Permission to incorporate this software into commercial products
  69 * contact Frederic Vernier, 19 butte aux cailles street, Paris, 75013, France.
  70 * Tel: (+33) 871 747 387. eMail: Frederic.Vernier@laposte.net / Web site:
  71 * http://vernier.frederic.free.fr <br>
  72 * IN NO EVENT SHALL FREDERIC VERNIER BE LIABLE TO ANY PARTY FOR DIRECT,
  73 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
  74 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  75 * IF FREDERIC VERNIER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.<br>
  76 * <br>
  77 * FREDERIC VERNIER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
  78 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  79 * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HERE UNDER IS ON AN "AS IS" BASIS,
  80 * AND FREDERIC VERNIER HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
  81 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.<br>
  82 * </td>
  83 * </tr>
  84 * </table> <br>
  85 * <b>Project related :</b> FiCell, FieldExplorer<br>
  86 * <br>
  87 * <b>Dates:</b> <br>
  88 * <li> Format : 01/11/2001
  89 * <li> Last Modif : 11/02/2003 <br>
  90 * <b>Bugs:</b> <br>
  91 * <li> ??? <br>
  92 * <b>To Do:</b> <br>
  93 * <li> alt or shift pressed -> repaint
  94 * 
  95 * @author Frederic Vernier, Frederic.Vernier@laposte.net
  96 * @version 1.4.1
  97 * @created 16 f�vrier 2004
  98 */
  99
 100public class BiSliderPresentation implements Serializable, MouseListener,
 101		MouseMotionListener, ComponentListener
 102{
 103	// ------------ MODIFIERS|--------------------
 104	// Type|----------------------------------------------- Name = Init value
 105	protected final static javax.swing.text.html.parser.ParserDelegator MAXIMUM_VARIABLE_SIZE_FOR_NAME = null;
 106
 107	final static long serialVersionUID = 6420110040552724883L;
 108
 109	protected SwingBiSlider Ctrl = null;
 110
 111	protected JComponent JComponent1 = null;
 112
 113	protected int[][] ColorTable = null;
 114
 115	protected long j = 0;
 116
 117	protected int NbAff = 0;
 118
 119	// for feedback
 120	protected final int NOTHING = 200;
 121
 122	protected final int RIGHT_POLYGON = 201;
 123
 124	protected final int LEFT_POLYGON = 202;
 125
 126	protected final int SELECTION = 203;
 127
 128	protected final int FIRST_LABEL = 204;
 129
 130	protected final int LAST_LABEL = 205;
 131
 132	protected int MouseUnder = NOTHING;
 133
 134	// Triangle polygons for the rulers
 135	protected Polygon TheLeft_Polygon = null;
 136
 137	protected Polygon TheRight_Polygon = null;
 138
 139	protected Rectangle2D RectFirstLabel = null;
 140
 141	protected Rectangle2D RectLastLabel = null;
 142
 143	protected Rectangle2D RectangleSegment = null;
 144
 145	// indicate if the tool has already been painted on screen or never.
 146	protected boolean NeverDrawn = true;
 147
 148	// graduation variables
 149	protected double GraduationWidth = 1;
 150
 151	// we need to remember the precise value opened when the precise popup shows
 152	// up because we will move around it
 153	protected double PreciseOpenedValue = 0;
 154
 155	// Constants for the Dragging variable
 156	protected final static int NONE = 100;
 157
 158	protected final static int LEFT_RULER = 101;
 159
 160	protected final static int RIGHT_RULER = 102;
 161
 162	protected final static int SHIFT_LEFT_RULER = 103;
 163
 164	protected final static int SHIFT_RIGHT_RULER = 104;
 165
 166	protected final static int SEGMENT = 105;
 167
 168	protected final static int SHIFT_SEGMENT = 106;
 169
 170	protected final static int ALT_LEFT_RULER = 107;
 171
 172	protected final static int ALT_RIGHT_RULER = 108;
 173
 174	protected final static int SEGMENT_SIZE = 109;
 175
 176	protected final static int SEGMENT_SIZE_INT = 110;
 177
 178	protected final static int PRECISE_LEFT_RULER = 111;
 179
 180	protected final static int PRECISE_RIGHT_RULER = 112;
 181
 182	protected int Dragging = NONE;
 183
 184	protected int LeftValue = 0;
 185
 186	protected int RightValue = 0;
 187
 188	protected int DeplBef = 0;
 189
 190	protected int DeplAft = 0;
 191
 192	protected double Center = 0;
 193
 194	// The width and height can change when the tool is resized
 195	protected int RulerWidth = 0;
 196
 197	protected final static int MINIMUM_RULER_HEIGHT = 20;
 198
 199	protected final static int PREFERRED_RULER_HEIGHT = 20;
 200
 201	protected int RulerHeight = PREFERRED_RULER_HEIGHT;
 202
 203	// but not the margins.
 204	protected final static int MARGIN_RULER_LEFT = 20;
 205
 206	protected int Margin_Ruler_Top = 13;
 207
 208	protected final static int MARGIN_RULER_RIGHT = 20;
 209
 210	protected final static int MARGIN_RULER_BOTTOM = 3;
 211
 212	// protected Dimension PreferredSize = new Dimension(5, 5);
 213	// protected Dimension MinimumSize = new Dimension(5, 5);
 214
 215	protected JTextField JTextFieldMin = new JTextField("");
 216
 217	protected JTextField JTextFieldMax = new JTextField("");
 218
 219	protected Vector<Point> LastFiveEvents = null;
 220
 221	protected JPanel JPanel1 = new JPanel();
 222
 223	protected JSlider JSlider1 = new JSlider(JSlider.VERTICAL, -100, 100, 0);
 224
 225	protected JLabel JLabel1 = new JLabel("0");
 226
 227	protected ContentPainterSupport ContentPainterSupport1 = null;
 228	
 229	
 230	protected FormatLong _myFormatter;
 231
 232	/**
 233	 * Contructor, create the polygons and other nested object then register mouse
 234	 * callbacks.
 235	 * 
 236	 * @param Ctrl_Arg
 237	 *          Description of the Parameter
 238	 */
 239	public BiSliderPresentation(SwingBiSlider Ctrl_Arg, ContentPainterSupport ContentPainterSupport_Arg,
 240			FormatLong formatter)
 241	{
 242		this.Ctrl = Ctrl_Arg;
 243		this.ContentPainterSupport1 = ContentPainterSupport_Arg;
 244
 245		if(formatter != null)
 246		{
 247			_myFormatter = formatter;
 248		}
 249		else
 250		{
 251			_myFormatter = new FormatLong();
 252		}
 253		
 254		Ctrl.setBackground(null);
 255
 256		JPanel1.setLayout(new BorderLayout());
 257		JPanel1.setBorder(BorderFactory.createLineBorder(Ctrl.getForeground()));
 258		JSlider1.setPaintLabels(true);
 259		JSlider1.setMajorTickSpacing(20);
 260		JSlider1.setMinorTickSpacing(1);
 261		JPanel1.add(JSlider1, BorderLayout.CENTER);
 262		JPanel1.add(JLabel1, BorderLayout.SOUTH);
 263		JLabel1.setHorizontalAlignment(SwingConstants.CENTER);
 264		JLabel1.setOpaque(true);
 265		JSlider1.setOpaque(true);
 266		JPanel1.revalidate();
 267
 268		/*
 269		 * JSlider1.addMouseListener(new MouseAdapter(){ public void
 270		 * mousePressed(MouseEvent MouseEvent_Arg){
 271		 * System.out.println(""+MouseEvent_Arg); } });
 272		 */
 273
 274		JSlider1.addChangeListener(new ChangeListener()
 275		{
 276			public void stateChanged(ChangeEvent ChangeEvent_Arg)
 277			{
 278
 279				double MiddleVal = PreciseOpenedValue;
 280
 281				double Amplitude = Ctrl.getSegmentSize() / Ctrl.getSegmentCount();
 282				if (Dragging == PRECISE_RIGHT_RULER
 283						&& MiddleVal - Amplitude < Ctrl.getMinimumColoredValue())
 284				{
 285					MiddleVal = Ctrl.getMinimumColoredValue() + Amplitude;
 286				}
 287				else if (Dragging == PRECISE_LEFT_RULER
 288						&& MiddleVal + Amplitude > Ctrl.getMaximumColoredValue())
 289				{
 290					MiddleVal = Ctrl.getMaximumColoredValue() - Amplitude;
 291				}
 292				else if (MiddleVal - Amplitude < Ctrl.getMinimumValue())
 293				{
 294					MiddleVal = Ctrl.getMinimumValue() + Amplitude;
 295				}
 296				else if (MiddleVal + Amplitude > Ctrl.getMaximumValue())
 297				{
 298					MiddleVal = Ctrl.getMaximumValue() - Amplitude;
 299				}
 300
 301				double Val = MiddleVal + ((double) JSlider1.getValue()) / 100d * Amplitude;
 302				JLabel1.setText(Ctrl.getDecimalFormater().format(Val));
 303
 304				if (Dragging == PRECISE_LEFT_RULER)
 305					Ctrl.setMinimumColoredValue(Val);
 306				if (Dragging == PRECISE_RIGHT_RULER)
 307					Ctrl.setMaximumColoredValue(Val);
 308			}
 309		});
 310
 311		if (UIManager.getLookAndFeel().getName().equals("Metal"))
 312		{
 313			int[] xp1 = { LeftValue, LeftValue - 7, LeftValue - 7, LeftValue - 6,
 314					LeftValue + 6, LeftValue + 7, LeftValue + 7 };
 315			int[] yp1 = { Margin_Ruler_Top + RulerHeight + 1 - 14,
 316					Margin_Ruler_Top + RulerHeight + 1 - 7, Margin_Ruler_Top + RulerHeight + 1,
 317					Margin_Ruler_Top + RulerHeight + 1 + 1, Margin_Ruler_Top + RulerHeight + 1 + 1,
 318					Margin_Ruler_Top + RulerHeight + 1, Margin_Ruler_Top + RulerHeight + 1 - 7 };
 319			TheLeft_Polygon = new Polygon(xp1, yp1, 7);
 320
 321			int[] xp2 = { RightValue - 7, RightValue - 7, RightValue - 6, RightValue + 6,
 322					RightValue + 7, RightValue + 7, RightValue };
 323			int[] yp2 = { Margin_Ruler_Top - 1 + 7, Margin_Ruler_Top - 1,
 324					Margin_Ruler_Top - 1 - 1, Margin_Ruler_Top - 1 - 1, Margin_Ruler_Top - 1,
 325					Margin_Ruler_Top - 1 + 7, Margin_Ruler_Top - 1 + 14, };
 326			TheRight_Polygon = new Polygon(xp2, yp2, 7);
 327
 328		}
 329		else
 330		{ // Triangles by default
 331			TheLeft_Polygon = new Polygon();
 332			TheLeft_Polygon.addPoint(LeftValue, Margin_Ruler_Top + RulerHeight - RulerHeight
 333					/ 2 - 1);
 334			TheLeft_Polygon.addPoint(LeftValue + RulerHeight / 2 + 2, Margin_Ruler_Top
 335					+ RulerHeight + 1);
 336			TheLeft_Polygon.addPoint(LeftValue, Margin_Ruler_Top + RulerHeight + 1);
 337			TheLeft_Polygon.addPoint(LeftValue, Margin_Ruler_Top + RulerHeight - RulerHeight
 338					/ 2 - 1);
 339
 340			TheRight_Polygon = new Polygon();
 341			TheRight_Polygon.addPoint(RightValue - 2 - RulerHeight / 2, Margin_Ruler_Top - 1);
 342			TheRight_Polygon.addPoint(RightValue, Margin_Ruler_Top - 1);
 343			TheRight_Polygon.addPoint(RightValue, Margin_Ruler_Top + RulerHeight / 2 + 1);
 344			TheRight_Polygon.addPoint(RightValue - 2 - RulerHeight / 2, Margin_Ruler_Top - 1);
 345		}
 346		JComponent1 = Ctrl;
 347
 348		JComponent1.addMouseListener(this);
 349		JComponent1.addMouseMotionListener(this);
 350		JComponent1.addComponentListener(this);
 351
 352		JComponent1.setLayout(null);
 353		// PreferredSize =
 354		// MinimumSize = );
 355		Ctrl.setPreferredSize(new Dimension(MARGIN_RULER_LEFT + MARGIN_RULER_RIGHT + 16
 356				* Ctrl.getSegmentCount(), Margin_Ruler_Top + MARGIN_RULER_BOTTOM
 357				+ MINIMUM_RULER_HEIGHT));
 358		Ctrl.setMinimumSize(new Dimension(MARGIN_RULER_LEFT + MARGIN_RULER_RIGHT + 8
 359				* Ctrl.getSegmentCount(), Margin_Ruler_Top + MARGIN_RULER_BOTTOM
 360				+ PREFERRED_RULER_HEIGHT));
 361
 362		JTextFieldMin.setVisible(false);
 363		JTextFieldMax.setVisible(false);
 364
 365		JTextFieldMin.getDocument().addDocumentListener(new DocumentListener()
 366		{
 367			public void changedUpdate(DocumentEvent DocumentEvent_Arg)
 368			{
 369			}
 370
 371			public void insertUpdate(DocumentEvent DocumentEvent_Arg)
 372			{
 373				try
 374				{
 375					JTextFieldMin.setBackground(Color.WHITE);
 376				}
 377				catch (NumberFormatException NumberFormatException_Arg)
 378				{
 379					JTextFieldMin.setBackground(new Color(255, 128, 128));
 380				}
 381			}
 382
 383			public void removeUpdate(DocumentEvent DocumentEvent_Arg)
 384			{
 385				try
 386				{
 387					JTextFieldMin.setBackground(Color.WHITE);
 388				}
 389				catch (NumberFormatException NumberFormatException_Arg)
 390				{
 391					JTextFieldMin.setBackground(new Color(255, 128, 128));
 392				}
 393			}
 394
 395		});
 396
 397		JTextFieldMin.addKeyListener(new KeyAdapter()
 398		{
 399			public void keyTyped(KeyEvent e)
 400			{
 401				if (e.getKeyChar() == KeyEvent.VK_ESCAPE)
 402				{
 403					while (JTextFieldMin.getActionListeners().length > 0)
 404					{
 405						JTextFieldMin.removeActionListener(JTextFieldMin.getActionListeners()[0]);
 406					}
 407					JTextFieldMin.setVisible(false);
 408				}
 409
 410				JTextFieldMin.setSize(JTextFieldMin.getPreferredSize().width + 10, JTextFieldMin
 411						.getPreferredSize().height);
 412			}
 413		});
 414
 415		JComponent1.add(JTextFieldMin);
 416
 417		JTextFieldMax.getDocument().addDocumentListener(new DocumentListener()
 418		{
 419			public void changedUpdate(DocumentEvent DocumentEvent_Arg)
 420			{
 421			}
 422
 423			public void insertUpdate(DocumentEvent DocumentEvent_Arg)
 424			{
 425				try
 426				{
 427					JTextFieldMax.setBackground(Color.WHITE);
 428				}
 429				catch (NumberFormatException NumberFormatException_Arg)
 430				{
 431					JTextFieldMax.setBackground(new Color(255, 128, 128));
 432				}
 433			}
 434
 435			public void removeUpdate(DocumentEvent DocumentEvent_Arg)
 436			{
 437				try
 438				{
 439					JTextFieldMax.setBackground(Color.WHITE);
 440				}
 441				catch (NumberFormatException NumberFormatException_Arg)
 442				{
 443					JTextFieldMax.setBackground(new Color(255, 128, 128));
 444				}
 445			}
 446
 447		});
 448
 449		JTextFieldMax.addKeyListener(new KeyAdapter()
 450		{
 451			public void keyTyped(KeyEvent e)
 452			{
 453				if (e.getKeyChar() == KeyEvent.VK_ESCAPE)
 454				{
 455					while (JTextFieldMax.getActionListeners().length > 0)
 456					{
 457						JTextFieldMax.removeActionListener(JTextFieldMax.getActionListeners()[0]);
 458					}
 459					JTextFieldMax.setVisible(false);
 460				}
 461
 462				int OldX = JTextFieldMax.getLocation().x;
 463				int OldWidth = JTextFieldMax.getSize().width;
 464				JTextFieldMax.setSize(JTextFieldMax.getPreferredSize().width + 10, JTextFieldMax
 465						.getPreferredSize().height);
 466				JTextFieldMax.setLocation(OldX + (OldWidth - JTextFieldMax.getSize().width),
 467						JTextFieldMax.getLocation().y);
 468			}
 469		});
 470
 471		JComponent1.add(JTextFieldMax);
 472
 473		JComponent1.setDoubleBuffered(true);
 474		// JComponent1.setSize(300, 50);
 475	} // constructor()
 476
 477	/**
 478	 * @param Color_Arg
 479	 *          Description of the Parameter
 480	 * @return the opposite color to make shadow of text with it
 481	 */
 482	protected Color getOppositeColor(Color Color_Arg)
 483	{
 484		int R = Color_Arg.getRed();
 485		int G = Color_Arg.getGreen();
 486		int B = Color_Arg.getBlue();
 487		R = 255 - R;
 488		int R2 = (Color_Arg.getRed() + 128) % 255;
 489		if (Math.abs(R - Color_Arg.getRed()) < Math.abs(R2 - Color_Arg.getRed()))
 490		{
 491			R = R2;
 492		}
 493
 494		G = 255 - G;
 495		int G2 = (Color_Arg.getGreen() + 128) % 255;
 496		if (Math.abs(G - Color_Arg.getGreen()) < Math.abs(G2 - Color_Arg.getGreen()))
 497		{
 498			G = G2;
 499		}
 500
 501		B = 255 - B;
 502		int B2 = (Color_Arg.getBlue() + 128) % 255;
 503		if (Math.abs(B - Color_Arg.getBlue()) < Math.abs(B2 - Color_Arg.getBlue()))
 504		{
 505			B = B2;
 506		}
 507
 508		return new Color(R, G, B);
 509	} // getOppositeColor()
 510
 511	/**
 512	 * Sets the rulers value if the new values are coherents.
 513	 * 
 514	 * @param Min_Arg
 515	 *          the value of the min triangle
 516	 * @param Max_Arg
 517	 *          the value of the max triangle
 518	 */
 519	public void setRulerValues(double Min_Arg, double Max_Arg)
 520	{
 521
 522		int SegmentCount = Ctrl.getSegmentCount();
 523
 524		if (SegmentCount == 0)
 525		{
 526			SegmentCount = 1;
 527		}
 528
 529		RulerWidth = JComponent1.getSize().width - MARGIN_RULER_LEFT - MARGIN_RULER_RIGHT;
 530		GraduationWidth = (RulerWidth * Ctrl.getSegmentSize())
 531				/ (Ctrl.getMaximumValue() - Ctrl.getMinimumValue());
 532
 533		NeverDrawn = false;
 534
 535		int NewLeftValue = (int) (MARGIN_RULER_LEFT + ((Min_Arg - Ctrl.getMinimumValue()) * RulerWidth)
 536				/ (Ctrl.getMaximumValue() - Ctrl.getMinimumValue()));
 537		int NewRightValue = (int) (MARGIN_RULER_LEFT + ((Max_Arg - Ctrl.getMinimumValue()) * RulerWidth)
 538				/ (Ctrl.getMaximumValue() - Ctrl.getMinimumValue()));
 539
 540		if (NewLeftValue <= NewRightValue && NewLeftValue >= MARGIN_RULER_LEFT
 541				&& NewRightValue <= MARGIN_RULER_LEFT + RulerWidth)
 542		{
 543			LeftValue = NewLeftValue;
 544			RightValue = NewRightValue;
 545
 546			int TriangleSide = RulerHeight / 2;
 547			TriangleSide = Math.max(Math.min(TriangleSide, 20), 10);
 548
 549			if (UIManager.getLookAndFeel().getName().equals("Metal"))
 550			{
 551				int[] xp1 = { LeftValue, LeftValue - 7, LeftValue - 7, LeftValue - 6,
 552						LeftValue + 6, LeftValue + 7, LeftValue + 7 };
 553				int[] yp1 = { Margin_Ruler_Top + RulerHeight + 1 - 14,
 554						Margin_Ruler_Top + RulerHeight + 1 - 7, Margin_Ruler_Top + RulerHeight + 1,
 555						Margin_Ruler_Top + RulerHeight + 1 + 1,
 556						Margin_Ruler_Top + RulerHeight + 1 + 1, Margin_Ruler_Top + RulerHeight + 1,
 557						Margin_Ruler_Top + RulerHeight + 1 - 7 };
 558				TheLeft_Polygon = new Polygon(xp1, yp1, 7);
 559
 560				int[] xp2 = { RightValue - 7, RightValue - 7, RightValue - 6, RightValue + 6,
 561						RightValue + 7, RightValue + 7, RightValue };
 562				int[] yp2 = { Margin_Ruler_Top - 1 + 7, Margin_Ruler_Top - 1,
 563						Margin_Ruler_Top - 1 - 1, Margin_Ruler_Top - 1 - 1, Margin_Ruler_Top - 1,
 564						Margin_Ruler_Top - 1 + 7, Margin_Ruler_Top - 1 + 14, };
 565				TheRight_Polygon = new Polygon(xp2, yp2, 7);
 566
 567			}
 568			else
 569			{ // Triangles by default
 570				TheLeft_Polygon = new Polygon();
 571				TheLeft_Polygon.addPoint(LeftValue, Margin_Ruler_Top + RulerHeight - TriangleSide
 572						- 1);
 573				TheLeft_Polygon.addPoint(LeftValue + TriangleSide + 2, Margin_Ruler_Top
 574						+ RulerHeight + 1);
 575				TheLeft_Polygon.addPoint(LeftValue, Margin_Ruler_Top + RulerHeight + 1);
 576				TheLeft_Polygon.addPoint(LeftValue, Margin_Ruler_Top + RulerHeight - TriangleSide
 577						- 1);
 578
 579				TheRight_Polygon = new Polygon();
 580				TheRight_Polygon.addPoint(RightValue - 2 - TriangleSide, Margin_Ruler_Top - 1);
 581				TheRight_Polygon.addPoint(RightValue, Margin_Ruler_Top - 1);
 582				TheRight_Polygon.addPoint(RightValue, Margin_Ruler_Top + TriangleSide + 1);
 583				TheRight_Polygon.addPoint(RightValue - 2 - TriangleSide, Margin_Ruler_Top - 1);
 584			}
 585		}
 586		else if (Ctrl.getSize().width == 0 || Ctrl.getSize().height == 0)
 587		{
 588
 589		}
 590		else
 591		{
 592			System.err.println("\nsetRulerValues()");
 593			System.err.println("  Size              = " + Ctrl.getSize());
 594			System.err.println("  NewLeftValue      = " + NewLeftValue);
 595			System.err.println("  NewRightValue     = " + NewRightValue);
 596			System.err.println("  MARGIN_RULER_LEFT = " + MARGIN_RULER_LEFT);
 597			System.err.println("  MARGIN_RULER_LEFT + RulerWidth = "
 598					+ (MARGIN_RULER_LEFT + RulerWidth));
 599			// Debug.debug(0, "");
 600		}
 601	} // setRulerValues()
 602
 603	/**
 604	 * Method called by the awt-swing mechanism when the area needs to be
 605	 * refreshed
 606	 * 
 607	 * @param Graphics_Arg
 608	 *          the graphic context to draw things
 609	 */
 610	public void paint(Graphics Graphics_Arg)
 611	{
 612		if (Graphics_Arg == null)
 613		{
 614			return;
 615		}
 616
 617		Graphics2D Graphics2 = (Graphics2D) Graphics_Arg;
 618		RenderingHints RenderingHints2 = new RenderingHints(null);
 619		RenderingHints2.put(RenderingHints.KEY_INTERPOLATION,
 620				RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
 621		RenderingHints2.put(RenderingHints.KEY_TEXT_ANTIALIASING,
 622				RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
 623		RenderingHints2.put(RenderingHints.KEY_ANTIALIASING,
 624				RenderingHints.VALUE_ANTIALIAS_OFF);
 625		RenderingHints2.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
 626		Graphics2.setRenderingHints(RenderingHints2);
 627
 628		Font Font1 = Ctrl.getFont();
 629		Font Font2 = new Font(Font1.getName(), Font.BOLD, Font1.getSize());
 630		Shape OldClip = Graphics2.getClip();
 631		// Shape NewClip = new Rectangle2D.Float(MARGIN_RULER_LEFT,
 632		// Margin_Ruler_Top,RulerWidth, RulerHeight);
 633		Shape NewClip = new RoundRectangle2D.Float(MARGIN_RULER_LEFT + 2, Margin_Ruler_Top,
 634				RulerWidth - 3, RulerHeight, Ctrl.getArcSize(), Ctrl.getArcSize());
 635
 636		int SegmentCount = Ctrl.getSegmentCount();
 637		FontMetrics TheFontMetrics = Graphics2.getFontMetrics();
 638		RulerWidth = JComponent1.getSize().width - MARGIN_RULER_LEFT - MARGIN_RULER_RIGHT;
 639		double ValuesWidth = Ctrl.getMaximumValue() - Ctrl.getMinimumValue();
 640
 641		if (NeverDrawn)
 642		{
 643			LeftValue = (int) (MARGIN_RULER_LEFT + ((Ctrl.getMinimumColoredValue() - Ctrl
 644					.getMinimumValue()) * RulerWidth)
 645					/ (Ctrl.getMaximumValue() - Ctrl.getMinimumValue()));
 646			RightValue = (int) (MARGIN_RULER_LEFT + ((Ctrl.getMaximumColoredValue() - Ctrl
 647					.getMinimumValue()) * RulerWidth)
 648					/ (Ctrl.getMaximumValue() - Ctrl.getMinimumValue()));
 649			TheRight_Polygon.translate(RulerWidth, 0);
 650			NeverDrawn = false;
 651		}
 652
 653		if (RulerWidth != JComponent1.getSize().width - MARGIN_RULER_LEFT
 654				- MARGIN_RULER_RIGHT)
 655		{
 656			int NewRulerWidth = JComponent1.getSize().width - MARGIN_RULER_LEFT
 657					- MARGIN_RULER_RIGHT;
 658
 659			NewRulerWidth = NewRulerWidth - NewRulerWidth % SegmentCount;
 660
 661			int NewLeftValue = MARGIN_RULER_LEFT
 662					+ ((LeftValue - MARGIN_RULER_LEFT) * (NewRulerWidth)) / RulerWidth;
 663			int NewRightValue = MARGIN_RULER_LEFT
 664					+ ((RightValue - MARGIN_RULER_LEFT) * (NewRulerWidth)) / RulerWidth;
 665
 666			TheLeft_Polygon.translate(NewLeftValue - LeftValue, 0);
 667			TheRight_Polygon.translate(NewRightValue - RightValue, 0);
 668
 669			LeftValue = NewLeftValue;
 670			RightValue = NewRightValue;
 671
 672			RulerWidth = NewRulerWidth;
 673
 674			GraduationWidth = (float) ((RulerWidth * Ctrl.getSegmentSize()) / (Ctrl
 675					.getMaximumValue() - Ctrl.getMinimumValue()));
 676		}
 677
 678		Color BackColor = null;
 679		Object SliderBackColor = UIManager.getLookAndFeel().getDefaults().get(
 680				"Slider.background");
 681
 682		if (SliderBackColor != null || !(SliderBackColor instanceof ColorUIResource))
 683			BackColor = (Color) SliderBackColor;
 684		if (BackColor == null || Ctrl.getBackground() != null)
 685			BackColor = Ctrl.getBackground();
 686
 687		if (BackColor != null)
 688			Graphics2.setColor(BackColor);
 689		Graphics2.fillRect(0, 0, JComponent1.getSize().width, JComponent1.getSize().height);
 690
 691		Graphics2.setClip(NewClip);
 692
 693		Graphics2.setColor(Ctrl.getSliderBackground());
 694		Graphics2.fillRoundRect(MARGIN_RULER_LEFT, Margin_Ruler_Top, RulerWidth, RulerHeight,
 695				Ctrl.getArcSize(), Ctrl.getArcSize());
 696
 697		Graphics2.setColor(Ctrl.getSliderBackground().darker());
 698		Graphics2.drawArc(MARGIN_RULER_LEFT + 1, Margin_Ruler_Top, Ctrl.getArcSize(), Ctrl
 699				.getArcSize(), 90, 90);
 700		Graphics2.drawArc(MARGIN_RULER_LEFT + RulerWidth - Ctrl.getArcSize() - 1,
 701				Margin_Ruler_Top, Ctrl.getArcSize(), Ctrl.getArcSize(), 0, 90);
 702
 703		Graphics2.setColor(Ctrl.getSliderBackground().brighter());
 704		Graphics2.drawArc(MARGIN_RULER_LEFT + RulerWidth - Ctrl.getArcSize() - 1,
 705				Margin_Ruler_Top + RulerHeight - Ctrl.getArcSize(), Ctrl.getArcSize(), Ctrl
 706						.getArcSize(), 270, 90);
 707		Graphics2.drawArc(MARGIN_RULER_LEFT + 1, Margin_Ruler_Top + RulerHeight
 708				- Ctrl.getArcSize(), Ctrl.getArcSize(), Ctrl.getArcSize(), 180, 90);
 709
 710		Graphics2.setColor(Ctrl.getSliderBackground().darker());
 711		Graphics2.drawLine(MARGIN_RULER_LEFT + Ctrl.getArcSize() / 2 - 1,
 712				Margin_Ruler_Top + 1, MARGIN_RULER_LEFT + RulerWidth - Ctrl.getArcSize() / 2 + 1,
 713				Margin_Ruler_Top + 1);
 714		Graphics2.drawLine(MARGIN_RULER_LEFT + 1, Margin_Ruler_Top + Ctrl.getArcSize() / 2,
 715				MARGIN_RULER_LEFT + 1, Margin_Ruler_Top + RulerHeight - Ctrl.getArcSize() / 2);
 716		Graphics2.setColor(Ctrl.getSliderBackground().brighter());
 717		Graphics2.drawLine(MARGIN_RULER_LEFT + Ctrl.getArcSize() / 2 - 1, Margin_Ruler_Top
 718				+ RulerHeight - 1, MARGIN_RULER_LEFT + RulerWidth - Ctrl.getArcSize() / 2 + 1,
 719				Margin_Ruler_Top + RulerHeight - 1);
 720		Graphics2.drawLine(MARGIN_RULER_LEFT + RulerWidth - 1, Margin_Ruler_Top
 721				+ Ctrl.getArcSize() / 2 + 1, MARGIN_RULER_LEFT + RulerWidth - 1, Margin_Ruler_Top
 722				+ RulerHeight - Ctrl.getArcSize() / 2);
 723		Graphics2.setClip(OldClip);
 724
 725		int LastMax = 0;
 726
 727		/*
 728		 * NewClip = new RoundRectangle2D.Float( MARGIN_RULER_LEFT+2,
 729		 * Margin_Ruler_Top, RulerWidth-3, RulerHeight, Ctrl.getArcSize(),
 730		 * Ctrl.getArcSize());
 731		 */
 732
 733		// it is the right opportunity to look for how many full non colored
 734		// segments there are before the fisrt one
 735		int SegmentCountBefore = 0;
 736		double[][] ColTable = Ctrl.getColorTable();
 737
 738		// Graphics2.setClip(NewClip);
 739		for (int i = 0; i <= SegmentCount; i++)
 740		{
 741			double Val = Ctrl.getMinimumValue() + i * Ctrl.getSegmentSize();
 742			double Val2 = Ctrl.getMinimumValue() + (i + 1) * Ctrl.getSegmentSize();
 743
 744			if (Val <= ColTable[0][0] && ColTable[0][0] < Val2)
 745				SegmentCountBefore = i;
 746
 747			String Unit = Ctrl.getUnit();
 748
 749			String NumberString = "";
 750			int NumberWidth = 0;
 751			int x = 0;
 752
 753			String MaxNumberString = "";
 754			if (Ctrl.getMaximumValue() == (long) Ctrl.getMaximumValue())
 755			{
 756				MaxNumberString = "" + (_myFormatter.format((long) Ctrl.getMaximumValue())) + Unit;
 757			}
 758			else
 759			{
 760				MaxNumberString = "" + _myFormatter.format((((long) (Ctrl.getMaximumValue() * 10)) / 10)) + Unit;
 761			}
 762
 763			if (Val > Ctrl.getMaximumValue())
 764			{
 765				Val = Ctrl.getMaximumValue();
 766				if (Val == (long) Val)
 767				{
 768					NumberString = "" + _myFormatter.format(((long) Val)) + Unit;
 769				}
 770				else
 771				{
 772					NumberString = "" + _myFormatter.format((long)(((long) (Val * 10)) / 10f)) + Unit;
 773				}
 774				NumberWidth = TheFontMetrics.stringWidth(NumberString);
 775
 776				x = JComponent1.getSize().width - MARGIN_RULER_RIGHT - NumberWidth;
 777			}
 778			else
 779			{
 780				if (Val == (long) Val)
 781				{
 782					NumberString = "" + _myFormatter.format(((long) Val)) + Unit;
 783				}
 784				else
 785				{
 786					NumberString = "" + _myFormatter.format((long)(((long) (Val * 10)) / 10f)) + Unit;
 787				}
 788				NumberWidth = TheFontMetrics.stringWidth(NumberString);
 789
 790				x = MARGIN_RULER_LEFT + (int) (GraduationWidth * i)
 791						- (int) ((NumberWidth * ((float) i / SegmentCount)));
 792			}
 793
 794			// get the color
 795			Graphics_Arg.setColor(Ctrl.getForeground());
 796
 797			if (Val == Ctrl.getMaximumValue() || Val == Ctrl.getMinimumValue())
 798			{
 799				Graphics2.setFont(Font2);
 800				Graphics2.drawString(NumberString, x, Margin_Ruler_Top - 1);
 801
 802				// restore the font
 803				Graphics2.setFont(Font1);
 804				LastMax = x + NumberWidth;
 805			} // if not too close to the last one or too close to the previous one
 806			else if (x + NumberWidth < JComponent1.getSize().width - MARGIN_RULER_RIGHT
 807					- TheFontMetrics.stringWidth(MaxNumberString)
 808					&& x >= LastMax + 8)
 809			{
 810				Graphics2.drawString(NumberString, x, Margin_Ruler_Top - 1);
 811				LastMax = x + NumberWidth;
 812			}
 813
 814			if (LastMax == x + NumberWidth)
 815			{
 816				Graphics2.setColor(Ctrl.getSliderBackground().darker().darker());
 817			}
 818			else
 819			{
 820				Graphics2.setColor(Ctrl.getSliderBackground().darker());
 821			}
 822
 823			if (ContentPainterSupport1.getPainterListenerNumber() > 0
 824					&& Val < Ctrl.getMaximumValue())
 825			{
 826				int x0 = MARGIN_RULER_LEFT + (int) (GraduationWidth * i);
 827				int x3 = MARGIN_RULER_LEFT + (int) (GraduationWidth * (i + 1));
 828				Rectangle Rect1bis = new Rectangle(x0, Margin_Ruler_Top + 2, x3 - x0,
 829						RulerHeight - 3);
 830
 831				x3 = Math.min(x3, MARGIN_RULER_LEFT + RulerWidth);
 832				Rectangle RectClip = new Rectangle(x0, Margin_Ruler_Top + 2, x3 - x0 + 2,
 833						RulerHeight - 3);
 834
 835				Shape ShapeClip = Graphics2.getClip();
 836				Color Color0 = Graphics2.getColor();
 837				Graphics2.setClip(RectClip);
 838				ContentPainterSupport1.firePaint(Ctrl, Graphics2, Val, Val2, i, null, Rect1bis,
 839						Rect1bis);
 840				Graphics2.setClip(ShapeClip);
 841				Graphics2.setColor(Color0);
 842			}
 843
 844			if (i != 0 && Val < Ctrl.getMaximumValue())
 845			{
 846				if (ContentPainterSupport1.getPainterListenerNumber() == 0)
 847					Graphics2.drawLine(MARGIN_RULER_LEFT + (int) (GraduationWidth * i),
 848							Margin_Ruler_Top + 2, MARGIN_RULER_LEFT + (int) (GraduationWidth * i),
 849							Margin_Ruler_Top + RulerHeight - 2);
 850			}
 851
 852			if (i == 0)
 853			{
 854				RectFirstLabel = new Rectangle(x - 1, Margin_Ruler_Top
 855						- TheFontMetrics.getAscent(), NumberWidth + 1, TheFontMetrics.getAscent());
 856			}
 857
 858			if (i == SegmentCount)
 859			{
 860				RectLastLabel = new Rectangle(x - 1, Margin_Ruler_Top
 861						- TheFontMetrics.getAscent(), NumberWidth + 1, TheFontMetrics.getAscent());
 862			}
 863
 864			if (MouseUnder == FIRST_LABEL)
 865			{
 866				Graphics2.draw(RectFirstLabel);
 867			}
 868			if (MouseUnder == LAST_LABEL)
 869			{
 870				Graphics2.draw(RectLastLabel);
 871			}
 872		}
 873
 874		if (MouseUnder == SEGMENT && RectangleSegment != null)
 875		{
 876			Graphics2.setColor(SystemColor.control.darker());
 877			Graphics2.draw(RectangleSegment);
 878		}
 879
 880		// ColorisationEvent CE1 = new ColorisationEvent(this,
 881		// Ctrl.getColorTable());
 882		// colored segment
 883		for (int i = 0; i < ColTable.length; i++)
 884		{
 885			Graphics2.setColor(new Color((int) (ColTable[i][2])));
 886			if (ColTable[i][0] < ColTable[i][1])
 887			{
 888				// the selection only
 889				int x1 = (int) (MARGIN_RULER_LEFT + (RulerWidth * (ColTable[i][0] - Ctrl
 890						.getMinimumValue()))
 891						/ ValuesWidth) + 1;
 892				int x2 = (int) (MARGIN_RULER_LEFT + (RulerWidth * ((ColTable[i][1]) - Ctrl
 893						.getMinimumValue()))
 894						/ ValuesWidth);
 895
 896				// the full segment
 897				int x0 = MARGIN_RULER_LEFT + (int) (GraduationWidth * (int) ColTable[i][3]);
 898				int x3 = MARGIN_RULER_LEFT + (int) (GraduationWidth * (int) (ColTable[i][3] + 1));
 899				Rectangle Rect1bis = new Rectangle(x1, Margin_Ruler_Top + 2, x2 - x1,
 900						RulerHeight - 3);
 901
 902				x3 = Math.min(x3, MARGIN_RULER_LEFT + RulerWidth);
 903				Rectangle Rect1 = new Rectangle(x1, Margin_Ruler_Top + 2, x2 - x1,
 904						RulerHeight - 3);
 905				Rectangle RectClip = new Rectangle(x1 - 1, Margin_Ruler_Top + 2, x2 - x1 + 2,
 906						RulerHeight - 3);
 907				Rectangle Rect2 = new Rectangle(x0, Margin_Ruler_Top + 2, x3 - x0,
 908						RulerHeight - 3);
 909
 910				if (ContentPainterSupport1.getPainterListenerNumber() == 0)
 911				{
 912					Graphics2.fill(Rect1);
 913					if (i != 0)
 914					{
 915						Graphics2.setColor(new Color(Graphics2.getColor().getRed(), Graphics2
 916								.getColor().getGreen(), Graphics2.getColor().getBlue(), 192));
 917						Graphics2.drawLine(x1 - 1, Margin_Ruler_Top + 3, x1 - 1, Margin_Ruler_Top
 918								+ RulerHeight - 3);
 919					}
 920				}
 921				else
 922				{
 923					Color Color0 = Graphics2.getColor();
 924					Graphics2.setClip(NewClip);
 925					Graphics2.clip(RectClip);
 926					ContentPainterSupport1.firePaint(Ctrl, Graphics2, ColTable[i][0],
 927							ColTable[i][1], i + SegmentCountBefore, Graphics2.getColor(), Rect1bis,
 928							Rect2);
 929					Graphics2.setClip(OldClip);
 930					Graphics2.setColor(Color0);
 931				}
 932			}
 933		}
 934
 935		Graphics2.setClip(OldClip);
 936
 937		if (Dragging == ALT_LEFT_RULER || Dragging == ALT_RIGHT_RULER)
 938		{
 939			Rectangle Rect1 = TheRight_Polygon.getBounds();
 940			Rectangle Rect2 = TheLeft_Polygon.getBounds();
 941			Rectangle2D Rectangle2D1 = Rect1.createUnion(Rect2);
 942
 943			Graphics2.setColor(SystemColor.scrollbar.darker());
 944			Graphics2.fillRect((int) (Rectangle2D1.getX() + Rectangle2D1.getWidth() / 2),
 945					Margin_Ruler_Top, 2, RulerHeight);
 946		}
 947
 948		// Graphics2.setColor(getOppositeColor(Ctrl.getBackground()));
 949		Graphics2.setColor(Color.BLACK);
 950		Graphics2.drawRoundRect(MARGIN_RULER_LEFT, Margin_Ruler_Top, RulerWidth, RulerHeight,
 951				Ctrl.getArcSize(), Ctrl.getArcSize());
 952
 953		paintThumbs(Graphics2);
 954
 955		if (Dragging == ALT_RIGHT_RULER || Dragging == ALT_LEFT_RULER
 956				|| Dragging == RIGHT_RULER || Dragging == SEGMENT || Dragging == SHIFT_SEGMENT
 957				|| Dragging == SHIFT_RIGHT_RULER)
 958		{
 959			String ValString = "";
 960			if (Math.abs(((int) Ctrl.getMaximumColoredValue()) - Ctrl.getMaximumColoredValue()) < 0.0001)
 961			{
 962				ValString = "" + _myFormatter.format((int) Ctrl.getMaximumColoredValue());
 963			}
 964			else
 965			{
 966				ValString = _myFormatter.format((long) Ctrl.getMaximumColoredValue());
 967			}
 968
 969			Graphics2.setColor(getOppositeColor(Ctrl.getForeground()));
 970			Graphics2.drawString(ValString, RightValue + 3, Margin_Ruler_Top
 971					+ TheFontMetrics.getAscent() + 1);
 972			Graphics2.setColor(Ctrl.getForeground());
 973			Graphics2.drawString(ValString, RightValue + 2, Margin_Ruler_Top
 974					+ TheFontMetrics.getAscent());
 975		}
 976
 977		if (Dragging == ALT_RIGHT_RULER || Dragging == ALT_LEFT_RULER
 978				|| Dragging == LEFT_RULER || Dragging == SEGMENT || Dragging == SHIFT_SEGMENT
 979				|| Dragging == SHIFT_LEFT_RULER)
 980		{
 981			String ValString = "";
 982			if (Math.abs(((int) Ctrl.getMinimumColoredValue()) - Ctrl.getMinimumColoredValue()) < 0.0001)
 983			{
 984				ValString = "" + _myFormatter.format((int) Ctrl.getMinimumColoredValue());
 985			}
 986			else
 987			{
 988				ValString = _myFormatter.format((long) Ctrl.getMinimumColoredValue());
 989			}
 990
 991			Graphics2.setColor(getOppositeColor(Ctrl.getForeground()));
 992			Graphics2.drawString(ValString, LeftValue - TheFontMetrics.stringWidth(ValString)
 993					- 1, Margin_Ruler_Top + RulerHeight - 1);
 994			Graphics2.setColor(Ctrl.getForeground());
 995			Graphics2.drawString(ValString, LeftValue - TheFontMetrics.stringWidth(ValString)
 996					- 2, Margin_Ruler_Top + RulerHeight - 2);
 997		}
 998
 999		if (JTextFieldMax.isVisible())
1000		{
1001			JTextFieldMax.repaint();
1002		}
1003		if (JTextFieldMin.isVisible())
1004		{
1005			JTextFieldMin.repaint();
1006		}
1007	} // paint()
1008
1009	/**
1010	 * paint a thumb
1011	 */
1012	public void paintThumbs(Graphics Graphics_Arg)
1013	{
1014		Graphics2D Graphics2 = (Graphics2D) Graphics_Arg;
1015		// System.out.println("getLookAndFeel="+UIManager.getLookAndFeel().getName());
1016		// System.out.println("getCurrentTheme="+MetalLookAndFeel.getCurrentTheme().getName());
1017		// TODO : Ocean Theme
1018		if (UIManager.getLookAndFeel().getName().equals("Metal"))
1019		{
1020			if (Dragging == LEFT_RULER || Dragging == SHIFT_LEFT_RULER
1021					|| Dragging == ALT_LEFT_RULER)
1022				paintThumb(Graphics_Arg, true, TheLeft_Polygon, MetalLookAndFeel
1023						.getPrimaryControlShadow(), MetalLookAndFeel.getPrimaryControlDarkShadow(),
1024						MetalLookAndFeel.getPrimaryControl());
1025			else if (MouseUnder == LEFT_POLYGON)
1026				paintThumb(Graphics_Arg, true, TheLeft_Polygon, MetalLookAndFeel
1027						.getControlShadow(), MetalLookAndFeel.getControlDarkShadow(),
1028						MetalLookAndFeel.getControl());
1029			else
1030				paintThumb(Graphics_Arg, true, TheLeft_Polygon, MetalLookAndFeel.getControl(),
1031						MetalLookAndFeel.getControlShadow(), MetalLookAndFeel.getControlHighlight());
1032
1033			if (Dragging == RIGHT_RULER || Dragging == SHIFT_RIGHT_RULER
1034					|| Dragging == ALT_RIGHT_RULER)
1035				paintThumb(Graphics_Arg, false, TheRight_Polygon, MetalLookAndFeel
1036						.getPrimaryControlShadow(), MetalLookAndFeel.getPrimaryControlDarkShadow(),
1037						MetalLookAndFeel.getPrimaryControl());
1038			else if ((MouseUnder == RIGHT_POLYGON))
1039				paintThumb(Graphics_Arg, false, TheRight_Polygon, MetalLookAndFeel
1040						.getControlShadow(), MetalLookAndFeel.getControlDarkShadow(),
1041						MetalLookAndFeel.getControl());
1042			else
1043				paintThumb(Graphics_Arg, false, TheRight_Polygon, MetalLookAndFeel.getControl(),
1044						MetalLookAndFeel.getControlShadow(), MetalLookAndFeel.getControlHighlight());
1045
1046		}
1047		else
1048		{ // default thumb = triangle
1049			Graphics2.setColor(SystemColor.control);
1050			if (Dragging == LEFT_RULER || Dragging == SHIFT_LEFT_RULER
1051					|| Dragging == ALT_LEFT_RULER)
1052				Graphics2.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1053			else if (MouseUnder == LEFT_POLYGON)
1054				Graphics2.setColor(MetalLookAndFeel.getControlHighlight());
1055			Graphics2.fillPolygon(TheLeft_Polygon);
1056
1057			Graphics2.setColor(SystemColor.control);
1058			if (Dragging == RIGHT_RULER || Dragging == SHIFT_RIGHT_RULER
1059					|| Dragging == ALT_RIGHT_RULER)
1060				Graphics2.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1061			else if (MouseUnder == RIGHT_POLYGON)
1062				Graphics2.setColor(MetalLookAndFeel.getControlHighlight());
1063			Graphics2.fillPolygon(TheRight_Polygon);
1064
1065			// shadow
1066			Graphics2.setColor(SystemColor.control.brighter());
1067			Graphics2.drawLine(TheLeft_Polygon.xpoints[0] + 1, TheLeft_Polygon.ypoints[0] + 2,
1068					TheLeft_Polygon.xpoints[2] + 1, TheLeft_Polygon.ypoints[2] - 1);
1069			Graphics2.drawLine(TheRight_Polygon.xpoints[0] + 1,
1070					TheRight_Polygon.ypoints[0] + 1, TheRight_Polygon.xpoints[1] - 1,
1071					TheRight_Polygon.ypoints[1] + 1);
1072			Graphics2.setColor(SystemColor.control.darker());
1073			Graphics2.drawLine(TheLeft_Polygon.xpoints[1] - 2, TheLeft_Polygon.ypoints[1] - 1,
1074					TheLeft_Polygon.xpoints[2] + 1, TheLeft_Polygon.ypoints[2] - 1);
1075			Graphics2.drawLine(TheRight_Polygon.xpoints[1] - 1,
1076					TheRight_Polygon.ypoints[1] + 1, TheRight_Polygon.xpoints[2] - 1,
1077					TheRight_Polygon.ypoints[2] - 1);
1078
1079			if (MouseUnder == SELECTION)
1080			{
1081				Rectangle Rect1 = TheRight_Polygon.getBounds();
1082				Rectangle Rect2 = TheLeft_Polygon.getBounds();
1083				Rectangle2D Rectangle2D1 = Rect1.createUnion(Rect2);
1084
1085				Graphics2.draw(Rectangle2D1);
1086			}
1087			else if (MouseUnder == LEFT_POLYGON)
1088			{
1089				// Graphics2.fillPolygon(TheLeft_Polygon);
1090				Graphics2.setColor(SystemColor.control.darker().darker());
1091				Graphics2.drawLine(TheLeft_Polygon.xpoints[0] + 1,
1092						TheLeft_Polygon.ypoints[0] + 2, TheLeft_Polygon.xpoints[2] + 1,
1093						TheLeft_Polygon.ypoints[2] - 1);
1094				Graphics2.setColor(SystemColor.control);
1095				Graphics2.drawLine(TheLeft_Polygon.xpoints[1] - 2,
1096						TheLeft_Polygon.ypoints[1] - 1, TheLeft_Polygon.xpoints[2] + 1,
1097						TheLeft_Polygon.ypoints[2] - 1);
1098			}
1099			else if (MouseUnder == RIGHT_POLYGON)
1100			{
1101				// Graphics2.fillPolygon(TheRight_Polygon);
1102				Graphics2.setColor(SystemColor.control.darker().darker());
1103				Graphics2.drawLine(TheRight_Polygon.xpoints[0] + 1,
1104						TheRight_Polygon.ypoints[0] + 1, TheRight_Polygon.xpoints[1] - 1,
1105						TheRight_Polygon.ypoints[1] + 1);
1106				Graphics2.setColor(SystemColor.control);
1107				Graphics2.drawLine(TheRight_Polygon.xpoints[1] - 1,
1108						TheRight_Polygon.ypoints[1] + 1, TheRight_Polygon.xpoints[2] - 1,
1109						TheRight_Polygon.ypoints[2] - 1);
1110			}
1111
1112			// Graphics2.setColor(getOppositeColor(Ctrl.getBackground()));
1113			Graphics2.setColor(Color.BLACK);
1114			Graphics2.drawPolygon(TheLeft_Polygon);
1115			Graphics2.drawPolygon(TheRight_Polygon);
1116		}
1117	}// paintThumb()
1118
1119	// Parameters of the widget
1120	/**
1121	 * Paints shadowed dots on the given <tt>Graphics</tt> objects. The
1122	 * coordinates of the points must be given in arrays.
1123	 * 
1124	 * @param g
1125	 *          the <tt>Graphics</tt> object on which we wand to paint the dots
1126	 * @param xCoords
1127	 *          array containing the X coordinates of the dots
1128	 * @param yCoords
1129	 *          array containing the Y coordinates of the dots
1130	 * @param num
1131	 *          the number of dots
1132	 * @author Christophe Jacquet, Frederic Vernier
1133	 */
1134	private void paintShadowedDots(Graphics g, int[] xCoords, int[] yCoords, int num,
1135			Color DarkColor_Arg, Color BrightColor_Arg)
1136	{
1137		for (int s = 0; s < 2; s++)
1138		{
1139			g.setColor(s == 0 ? BrightColor_Arg : DarkColor_Arg);
1140			for (int i = 0; i < num; i++)
1141			{
1142				g.drawLine(xCoords[i] + s, yCoords[i] + s, xCoords[i] + s, yCoords[i] + s);
1143			}
1144		}
1145	}// paintShadowedDots()
1146
1147	/**
1148	 * Draws an arrow (upward or downward) on a given <tt>Graphics</tt> object.
1149	 * 
1150	 * @param g
1151	 *          the <tt>Graphics</tt> object on which we want to paint the arrow
1152	 * @param up
1153	 *          if <tt>true</tt>, the arrow will be painted upward. If
1154	 * @author Christophe Jacquet, Frederic Vernier <tt>false</tt>, it will be
1155	 *         painted downward
1156	 */
1157	private void paintThumb(Graphics Graphics_Arg, boolean up, Polygon Thumb_Arg,
1158			Color MainColor_Arg, Color DarkColor_Arg, Color BrightColor_Arg)
1159	{
1160
1161		Graphics2D G2 = (Graphics2D) Graphics_Arg;
1162		
1163		// HACK: commented out the next block of code.  Because it's being compared with 
1164		// 'false', it can never run anyway.  I suspect it's part of Borlander's workaround
1165		
1166//
1167//		if (UIManager.getLookAndFeel().getName().equals("Metal") && false)
1168//		{
1169//			Color BackColor = null;
1170//			Object SliderBackColor = UIManager.getLookAndFeel().getDefaults().get(
1171//					"Slider.gradient");
1172//			if (SliderBackColor != null && SliderBackColor instanceof List)
1173//			{
1174//				List GradientProperties = (List) SliderBackColor;
1175//				Float Cut1 = (Float) GradientProperties.get(0);
1176//				Float Cut2 = (Float) GradientProperties.get(1);
1177//				Color Color1 = (Color) GradientProperties.get(2);
1178//				Color Color2 = (Color) GradientProperties.get(3);
1179//				Color Color3 = (Color) GradientProperties.get(4);
1180//				float Rem = 1f - Cut2.floatValue() - 2 * Cut1.floatValue();
1181//				int x1 = up ? Thumb_Arg.xpoints[0] : Thumb_Arg.xpoints[6];
1182//				int y1 = up ? Thumb_Arg.ypoints[0] : Thumb_Arg.ypoints[6];
1183//
1184//				int x2 = up ? Thumb_Arg.xpoints[1] : Thumb_Arg.xpoints[5];
1185//				int y2 = up ? Thumb_Arg.ypoints[1] : Thumb_Arg.ypoints[5];
1186//
1187//				Shape Shape0 = G2.getClip();
1188//				G2.setClip(Thumb_Arg);
1189//				if (up)
1190//				{
1191//					GradientPaint GradientPaint1 = new GradientPaint(x1 - 7, y1, Color3, x1, y1
1192//							+ (int) (16f * Rem), Color1);
1193//					GradientPaint GradientPaint2 = new GradientPaint(x1, y1 + (int) (16f * Rem),
1194//							Color1, x1, y1 + (int) (16f * (Rem + Cut1.floatValue())), Color2);
1195//					GradientPaint GradientPaint3 = new GradientPaint(x1, y1
1196//							+ (int) (16f * (Rem + Cut1.floatValue() + Cut2.floatValue())), Color2, x1,
1197//							y1 + 16, Color3);
1198//
1199//					G2.setPaint(GradientPaint1);
1200//					G2.fillRect(x1 - 7, y1, 15, (int) (16f * Rem));
1201//					G2.setPaint(GradientPaint2);
1202//					G2.fillRect(x1 - 7, y1 + (int) (16f * Rem), 15,
1203//							(int) (16f * Cut1.floatValue()) + 1);
1204//					G2.setColor(Color2);
1205//					G2.fillRect(x1 - 7, y1 + (int) (16f * (Rem + Cut1.floatValue())), 15,
1206//							(int) (16f * Cut2.floatValue()) + 1);
1207//					G2.setPaint(GradientPaint3);
1208//					G2.fillRect(x1 - 7, y1
1209//							+ (int) (16f * (Rem + Cut1.floatValue() + Cut2.floatValue())), 15,
1210//							(int) (16f * Cut1.floatValue()) + 1);
1211//				}
1212//				else
1213//				{
1214//					GradientPaint GradientPaint1 = new GradientPaint(x1 - 7, y1, Color3, x1, y1
1215//							- (int) (16f * Rem), Color1);
1216//					GradientPaint GradientPaint2 = new GradientPaint(x1, y1 - (int) (16f * Rem),
1217//							Color1, x1, y1 - (int) (16f * (Rem + Cut1.floatValue())), Color2);
1218//					GradientPaint GradientPaint3 = new GradientPaint(x1, y1
1219//							- (int) (16f * (Rem + Cut1.floatValue() + Cut2.floatValue())), Color2, x1,
1220//							y1 - 16, Color3);
1221//
1222//					G2.setPaint(GradientPaint1);
1223//					G2.fillRect(x1 - 7, y1 - (int) (16f * Rem), 15, (int) (16f * Rem));
1224//					G2.setPaint(GradientPaint2);
1225//					G2.fillRect(x1 - 7, y1 - (int) (16f * (Rem + Cut1.floatValue())), 15,
1226//							(int) (16f * Cut1.floatValue()) + 1);
1227//					G2.setColor(Color2);
1228//					G2.fillRect(x1 - 7, y1
1229//							- (int) (16f * (Rem + Cut1.floatValue() + Cut2.floatValue())), 15,
1230//							(int) (16f * Cut2.floatValue()) + 1);
1231//					G2.setPaint(GradientPaint3);
1232//					G2.fillRect(x1 - 7, y1 - 16, 15, (int) (16f * Cut1.floatValue()) + 1);
1233//				}
1234//				G2.setClip(Shape0);
1235//			}
1236//
1237//		}
1238//		else
1239//		{
1240			G2.setColor(new Color(MainColor_Arg.getRed(), MainColor_Arg.getGreen(),
1241					MainColor_Arg.getBlue(), 196));
1242			G2.fillPolygon(Thumb_Arg);
1243	//	}
1244
1245
1246		G2.setColor(Color.BLACK);
1247		G2.drawPolygon(Thumb_Arg);
1248		int yy = up ? Thumb_Arg.ypoints[0] + 8 : Thumb_Arg.ypoints[6] - 13;
1249		int xx = up ? Thumb_Arg.xpoints[0] : Thumb_Arg.xpoints[6];
1250		int[] xp = { xx - 5, xx - 1, xx + 3, xx - 3, xx + 1, xx - 5, xx - 1, xx + 3 };
1251		int[] yp = { yy, yy, yy, yy + 2, yy + 2, yy + 4, yy + 4, yy + 4 };
1252
1253		paintShadowedDots(G2, xp, yp, 8, DarkColor_Arg, BrightColor_Arg);
1254	}// paintThumb()
1255
1256	/**
1257	 * Method called by the awt-swing mechanism when the user press the mouse
1258	 * button over this component
1259	 * 
1260	 * @param MouseEvent_Arg
1261	 *          the mouse event generatedby the awt-swing mechanism
1262	 */
1263	public void mousePressed(MouseEvent MouseEvent_Arg)
1264	{
1265
1266		LastFiveEvents = new Vector<Point>();
1267		LastFiveEvents.add(MouseEvent_Arg.getPoint());
1268
1269		if (JTextFieldMin.isVisible())
1270		{
1271			JTextFieldMin.postActionEvent();
1272			while (JTextFieldMin.getActionListeners().length > 0)
1273			{
1274				JTextFieldMin.removeActionListener(JTextFieldMin.getActionListeners()[0]);
1275			}
1276			JTextFieldMin.setVisible(false);
1277			Ctrl.requestFocus();
1278		}
1279		if (JTextFieldMax.isVisible())
1280		{
1281			JTextFieldMax.postActionEvent();
1282			while (JTextFieldMax.getActionListeners().length > 0)
1283			{
1284				JTextFieldMax.removeActionListener(JTextFieldMax.getActionListeners()[0]);
1285			}
1286			JTextFieldMax.setVisible(false);
1287			Ctrl.requestFocus();
1288		}
1289
1290		if (Ctrl.isPrecise() && MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1291				&& MouseEvent_Arg.getClickCount() > 1
1292				&& TheLeft_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY()))
1293		{
1294			openPrecisionPopup(LEFT_POLYGON, new Point(MouseEvent_Arg.getX(), MouseEvent_Arg
1295					.getY()));
1296			return;
1297		}
1298		else if (Ctrl.isPrecise() && MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1299				&& MouseEvent_Arg.getClickCount() > 1
1300				&& TheRight_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY()))
1301		{
1302			openPrecisionPopup(RIGHT_POLYGON, new Point(MouseEvent_Arg.getX(), MouseEvent_Arg
1303					.getY()));
1304			return;
1305		} // Clic the first number to drag it and change the SegmentCount
1306		else if (RectFirstLabel != null && MouseEvent_Arg.getClickCount() == 1
1307				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1308				&& RectFirstLabel.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1309				&& MouseEvent_Arg.isShiftDown())
1310		{
1311			Dragging = SEGMENT_SIZE_INT;
1312		}
1313		else if (RectFirstLabel != null && MouseEvent_Arg.getClickCount() == 1
1314				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1315				&& RectFirstLabel.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1316				&& !MouseEvent_Arg.isShiftDown())
1317		{
1318			Dragging = SEGMENT_SIZE;
1319		} // The user want to modify the minimum by draging the left triangle
1320		else if (TheLeft_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1321				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1322				&& !MouseEvent_Arg.isAltDown() && !MouseEvent_Arg.isShiftDown())
1323		{
1324
1325			Dragging = LEFT_RULER;
1326
1327			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1328			DeplAft = RightValue - MouseEvent_Arg.getX();
1329
1330			JComponent1.repaint();
1331		}
1332		else if (TheLeft_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1333				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1334				&& !MouseEvent_Arg.isAltDown() && MouseEvent_Arg.isShiftDown())
1335		{
1336
1337			Dragging = SHIFT_LEFT_RULER;
1338
1339			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1340			DeplAft = RightValue - MouseEvent_Arg.getX();
1341
1342			JComponent1.repaint();
1343		} // the user want to modify the maximum by draging the left triangle
1344		else if (TheRight_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1345				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1346				&& !MouseEvent_Arg.isAltDown() && !MouseEvent_Arg.isShiftDown())
1347		{
1348			Dragging = RIGHT_RULER;
1349
1350			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1351			DeplAft = RightValue - MouseEvent_Arg.getX();
1352
1353			JComponent1.repaint();
1354		} // the user want to modify the maximum by draging the left triangle
1355		else if (TheRight_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1356				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1357				&& !MouseEvent_Arg.isAltDown() && MouseEvent_Arg.isShiftDown())
1358		{
1359			Dragging = SHIFT_RIGHT_RULER;
1360
1361			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1362			DeplAft = RightValue - MouseEvent_Arg.getX();
1363
1364			JComponent1.repaint();
1365		} // The user may want to drag the segment.
1366		else if (MouseEvent_Arg.getX() > LeftValue
1367				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1368				&& MouseEvent_Arg.getX() < RightValue && MouseEvent_Arg.getY() > Margin_Ruler_Top
1369				&& MouseEvent_Arg.getY() < Margin_Ruler_Top + RulerHeight
1370				&& !MouseEvent_Arg.isAltDown() && !MouseEvent_Arg.isShiftDown())
1371		{
1372			Dragging = SEGMENT;
1373
1374			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1375			DeplAft = RightValue - MouseEvent_Arg.getX();
1376
1377			JComponent1.repaint();
1378		} // The user may want to drag the segment (but stay aligned on graduations)
1379		else if (MouseEvent_Arg.getX() > LeftValue
1380				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1381				&& MouseEvent_Arg.getX() < RightValue && MouseEvent_Arg.getY() > Margin_Ruler_Top
1382				&& MouseEvent_Arg.getY() < Margin_Ruler_Top + RulerHeight
1383				&& !MouseEvent_Arg.isAltDown() && MouseEvent_Arg.isShiftDown())
1384		{
1385			Dragging = SHIFT_SEGMENT;
1386
1387			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1388			DeplAft = RightValue - MouseEvent_Arg.getX();
1389
1390			JComponent1.repaint();
1391		} // The user may want to drag the segment.
1392		else if (TheRight_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1393				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1 && MouseEvent_Arg.isAltDown())
1394		{
1395			Dragging = ALT_RIGHT_RULER;
1396
1397			Center = (Ctrl.getMinimumColoredValue() + Ctrl.getMaximumColoredValue()) / 2;
1398			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1399			DeplAft = RightValue - MouseEvent_Arg.getX();
1400
1401			JComponent1.repaint();
1402		} // The user may want to drag the segment.
1403		else if (TheLeft_Polygon.contains(MouseEvent_Arg.getX(), MouseEvent_Arg.getY())
1404				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1 && MouseEvent_Arg.isAltDown())
1405		{
1406			Dragging = ALT_LEFT_RULER;
1407
1408			Center = (Ctrl.getMinimumColoredValue() + Ctrl.getMaximumColoredValue()) / 2;
1409			DeplBef = MouseEvent_Arg.getX() - LeftValue;
1410			DeplAft = RightValue - MouseEvent_Arg.getX();
1411
1412			JComponent1.repaint();
1413		} // Double click in a new segment with SHIFT pressed for concatenation of
1414		// the segment
1415		else if (MouseEvent_Arg.isShiftDown()
1416				&& MouseEvent_Arg.getButton() == MouseEvent.BUTTON1
1417				&& MouseEvent_Arg.getClickCount() > 1
1418				&& MouseEvent_Arg.getX() > MARGIN_RULER_LEFT
1419				&& MouseEvent_Arg.getX() < MARGIN_RULER_LEFT + RulerWidth
1420				&& MouseEvent_Arg.getY() > Margin_Ruler_Top
1421				&& MouseEvent_Arg.getY() < Margin_Ruler_Top + RulerHeight)
1422		{
1423
1424			int d1 = MouseEvent_Arg.getX() - MARGIN_RULER_LEFT;
1425			int GraduationCount = (int) Math.floor(d1 / GraduationWidth);
1426
1427			double Min = Ctrl.getMinimumValue()
1428					+ (float) ((GraduationCount * GraduationWidth)
1429							* (Ctrl.getMaximumValue() - Ctrl.getMinimumValue()) / RulerWidth);
1430			double Max = Ctrl.getMinimumValue()
1431					+ (float) (((GraduationCount + 1) * GraduationWidth)
1432							* (Ctrl.getMaximumValue() - Ctrl.getMinimumValue()) / RulerWidth);
1433
1434			// because the last segment is maybe smaller than a regular one
1435			if (Max > Ctrl.getMaximumValue())
1436			{
1437				Max = Ctrl.getMaximumValue