What use of having double precision in java.awt.geom?
Hi,
I am trying to draw a line using Line2D with this param:
g2d.draw( new Line2D.Double( 1.1d, 1.5d, 1.9d, 1.5d ) );
in my own JPanel paint method.
However, the result is that the panel does not display a line nor a dot at all. Only when i change it to:
g2d.draw( new Line2D.Double( 1.0d, 1.5d, 2.0d, 1.5d ) );
that it draws a dot in the panel's first pixel.
Can someone please guide or tell me why is this so? And what is the purpose of providing a double value for a geom ( such as Rentagle2D, Line2D, etc )?
The actual case is that I have created a graph with x and y axis. I set the graph to be 400pixel * 400 pixels. And the scale for the graph is 1 million unit * 1 million unit which means a pixel would have contain (1000000/400) units, or 0.004 pixels represent 1 unit. The problem occurs when i try to draw a line that is only 10 unit.(which nothing is draw on the panel). I try to use all 2D geom with double precision, yet i could not get the result that I wanted. Isn't that java 2D will handle the double precision for graphing or drawing?
Your help and reply is very much appreciated.
Thank you.
have in mind that you always have to fill 1 pixel to see anything as the panel has a 1 pixel grid.
i guess the thing about double precision is in the contains(...) or crosses(...) methods of the geom.* objects.
its nothing about drawing. how can you draw finer than the 1 pixel grid.
even the antialias has to fill more pixel to make you thing the line is smooth. (BTW: antialias makes fonts widt less than 10px look terrible :))
Similar Messages
-
I am pretty frustrated about having to write my own Serializable classes. I'm not sure if this is the right place to ask, but will the next version of Java supports Serializable 2D objects?
Further, I was trying to write my own class to extend java.awt.geom.GeneralPath to become Serializable, but it's declared "final". What should I do? (I had no problems with Rectangle2D.Double, Line2D.Double, etc.)
Any help is greatly appreciated.
SelwynYour code for serializing the state of the General path forgets two things:
1. the winding rule
2. the segments types!
You could use a vector, but I just directly wrote to the file:
private void writeObject(ObjectOutputStream oos) throws IOException
{ out.defaultWriteObject();
//write state of transient GeneralPath _gp;
out.writeInt(_gp.getWindingRule());
float[] coord = new float[6];
PathIterator i = _gp.getPathIterator(null);
while(!i.isDone())
{ int seg = i.currentSegment(coords);
writeInt(seg);
//switch on seg, writing correct # of floats from coords
i.next();
out.writeInt(-1); //sentinel for end-of-data: SEG_LINETO etc are [0,4]
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{ in.defaultReadObject();
int rule = in.readInt();
_gp = new GeneralPath(rule);
//etc...
}3. I'm just winging this code -- haven't tested it
--Nax -
Bug in java.awt.geom.Rectangle2D.contains method
I cannot understand why not awt.geom.Rectangle2D.contains() return the right value??? Or maybe i don�t understand it properly. Check out this code snippet
import java.awt.geom.*;
public class Test
public static void main(String[] args)
//Rectangle has a width of 2 and a height of 2 and starts drawing on cordinate 1,1
Rectangle2D rect = new Rectangle2D.Double(1,1,2,2);
if (rect.contains(1,3))
System.out.println("The cordinate is inside rectangle");
else
System.out.println("The cordinate is NOT NOT NOT inside rectangle");
}The cordinate (1,3) is clearly contained in the rectangle or not?
When you change the cordinate to (1,1) the method works correctly, so why diesn�t it work right with the cordinate (1,3). Can somebody please enlight me?
Edited by: ripper079 on Dec 6, 2007 4:27 AMThe cordinate (1,3) is clearly contained in the rectangle or not?Actually, it's a matter of opinion whether a point on the perimeter of a shape is considered contained in the shape or not. This is the implementation of java.awt.geom.Rectangle2D.contains (double x, double y) public boolean contains(double x, double y) {
double x0 = getX();
double y0 = getY();
return (x >= x0 &&
y >= y0 &&
x < x0 + getWidth() &&
y < y0 + getHeight());
}As can be seen from the code, the design team adopted a philosophy of returning false for coordinates that lie along the bottom and right sides of the Rectangle.
If you require different behavior, you can always extend Rectangle2D.Double and override the methodimport java.awt.geom.Rectangle2D;
public class Test extends Rectangle2D.Double {
public Test (double x, double y, double w, double h) {
super (x, y, w, h);
public boolean contains (double x, double y) {
double x0 = getX ();
double y0 = getY ();
return (x >= x0 &&
y >= y0 &&
x <= x0 + getWidth () &&
y <= y0 + getHeight ());
public static void main (String[] args) {
//Rectangle has a width of 2 and a height of 2 and starts drawing on cordinate 1,1
Rectangle2D rect = new Test (1, 1, 2, 2);
//Rectangle2D rect = new Rectangle2D.Double (1, 1, 2, 2);
if (rect.contains (1,3))
System.out.println ("The cordinate is inside rectangle");
else
System.out.println ("The cordinate is NOT inside rectangle");
}db -
Bug in java.awt.geom.Line2D?
The method,
public static double ptLineDistSq(double X1,
double Y1,
double X2,
double Y2,
double PX,
double PY)calculates the squared distance between a line segment and a point.
If however you pass in a line segment of zero length (X1=X2, Y1=Y2), the method performs a div by zero, which causes NaN to be returned.
I believe this is a bug, as the method makes no exceptions to valid input, also mathmatically the distance from a point to a line segment still has a value even if the line segment has a zero length.
A simple sanity check at the start of the method would fix it,
if(X1==X2 && Y1==Y2) return (X1-PX)*(X1-PX)+(Y1-PY)*(Y1-PY);Yeah, im already working around it (i've actually just stolen their code, and switched it all from doubles to floats :D - it isn't a serious app. just a problem I encountered when answering a question in this Thread http://forum.java.sun.com/thread.jsp?forum=406&thread=420363&start=30&range=15&tstart=0&trange=15)
I was realy just posting here for confirmation that it is a bug, before I reported it. -
Need help locating a Polygon class that works in double precision
The title says it all even though a class with floating points would be good too. ty :)
You could always make your own polygon class that encapsulates
java.awt.geom.Line2D
Line2D has float and double implementations -
Custom graphics in java.awt.ScrollPane
Hi all,
I have to draw a custom created image in a scroll pane. As the image is very large I want to display it in a scroll pane. As parts of the image may change within seconds, and drawing the whole image is very time consuming (several seconds) I want to draw only the part of the image that is currently visible to the user.
My idea: creating a new class that extends from java.awt.ScrollPane, overwrite the paint(Graphics) method and do the drawings inside. Unfortunately, it does not work. The background of the scoll pane is blue, but it does not show the red box (the current viewport is not shown in red).
Below please find the source code that I am using:
package graphics;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.ScrollPane;
import java.awt.event.AdjustmentEvent;
public class CMyComponent extends ScrollPane {
/** <p>Listener to force a component to repaint when a scroll bar changes its
* position.</p>
private final class ScrollBarAdjustmentListener implements java.awt.event.AdjustmentListener {
/** <p>The component to force to repaint.</p> */
private final Component m_Target;
/** <p>Default constructor.</p>
* @param Target The component to force to repaint.
private ScrollBarAdjustmentListener(Component Target) { m_Target = Target; }
/** <p>Forces to component to repaint upon adjustment of the scroll bar.</p>
* @see java.awt.event.AdjustmentListener#adjustmentValueChanged(java.awt.event.AdjustmentEvent)
public void adjustmentValueChanged(AdjustmentEvent e) { m_Target.paint(m_Target.getGraphics()); }
public CMyComponent() {
// Ensure that the component repaints upon changing of the scroll bars
ScrollBarAdjustmentListener sbal = new ScrollBarAdjustmentListener(this);
getHAdjustable().addAdjustmentListener(sbal);
getVAdjustable().addAdjustmentListener(sbal);
public void paint(Graphics g) {
setBackground(Color.BLUE);
g.setColor(Color.RED);
g.fillRect(getScrollPosition().x, getScrollPosition().y, getViewportSize().width, getViewportSize().height);
public final static void main(String[] args) {
java.awt.Frame f = new java.awt.Frame();
f.add(new CMyComponent());
f.pack();
f.setVisible(true);
}Dear all,
I used the last days and tried several things. I think now I have a quite good working solution (just one bug remains) and it is very performant. To give others a chance to see what I have done I post the source code of the main class (a canvas drawing and implementing scrolling) here. As soon as the sourceforge project is accepted, I will publish the whole sources at there. Enjoy. And if you have some idea for my last bug in getElementAtPixel(Point), then please tell me.
package internetrail.graphics.hexgrid;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.util.WeakHashMap;
import java.util.Map;
/** <p>Hex grid view.</p>
* <p>Visualizes a {@link IHexGridModel}.</p>
* @version 0.1, 03.06.2006
* @author Bjoern Wuest, Germany
public final class CHexGridView extends Canvas implements ComponentListener, IHexGridElementListener {
/** <p>Serial version unique identifier.</p> */
private static final long serialVersionUID = -965902826101261530L;
/** <p>Instance-constant parameter for the width of a hex grid element.</p> */
public final int CONST_Width;
/** <p>Instance-constant parameter for 1/4 of the width of a hex grid element.</p> */
public final int CONST_Width1fourth;
/** <p>Instance-constant parameter for 3/4 of the width of a hex grid element.</p> */
public final int CONST_Width3fourth;
/** <p>Instance-constant parameter for 1.5 times of the width of a hex grid element.</p> */
public final int CONST_Width1dot5;
/** <p>Instance-constant parameter for 4 times of the width of a hex grid element.</p> */
public final int CONST_Widthquad;
/** <p>Instance-constant parameter for the height of a hex grid element.</p> */
public final int CONST_Height;
/** <p>Instance-constant parameter for 1/2 of the height of a hex grid element.</p> */
public final int CONST_Heighthalf;
/** <p>Instance-constant parameter for the double height of a hex grid element.</p> */
public final int CONST_Heightdouble;
/** <p>The steepness of a side of the hex grid element (calculated for the upper left arc).</p> */
public final double CONST_Steepness;
/** <p>The model of this hex grid </p> */
private final IHexGridModel m_Model;
/** <p>A cache for already created images of the hex map.</p> */
private final Map<Point, Image> m_Cache = new WeakHashMap<Point, Image>();
/** <p>The graphical area to draw the selection ring around a hex element.</p> */
private final Area m_SelectionRing;
/** <p>The image of the selection ring around a hex element.</p> */
private final BufferedImage m_SelectionRingImage;
/** <p>The current position of the hex grid in pixels (top left visible corner).</p> */
private Point m_ScrollPosition = new Point(0, 0);
/** <p>Flag to define if a grid is shown ({@code true}) or not ({@code false}).</p> */
private boolean m_ShowGrid = true;
/** <p>Flag to define if the selected hex grid element should be highlighted ({@code true}) or not ({@code false}).</p> */
private boolean m_ShowSelected = true;
/** <p>The offset of hex grid elements shown on the screen, measured in hex grid elements.</p> */
private Point m_CurrentOffset = new Point(0, 0);
/** <p>The offset of the image shown on the screen, measured in pixels.</p> */
private Point m_PixelOffset = new Point(0, 0);
/** <p>The index of the currently selected hex grid element.</p> */
private Point m_CurrentSelected = new Point(0, 0);
/** <p>The width of a buffered pre-calculated image in pixel.</p> */
private int m_ImageWidth;
/** <p>The height of a buffered pre-calculated image in pixel.</p> */
private int m_ImageHeight;
/** <p>The maximum number of columns of hex grid elements to be shown at once on the screen.</p> */
private int m_MaxColumn;
/** <p>The maximum number of rows of hex grid elements to be shown at once on the screen.</p> */
private int m_MaxRow;
/** <p>Create a new hex grid view.</p>
* <p>The hex grid view is bound to a {@link IHexGridModel} and registers at
* that model to listen for {@link IHexGridElement} updates.</p>
* @param Model The model backing this view.
public CHexGridView(IHexGridModel Model) {
// Set the model
m_Model = Model;
CONST_Width = m_Model.getElementsWidth();
CONST_Height = m_Model.getElementsHeight();
CONST_Width1fourth = CONST_Width/4;
CONST_Width3fourth = CONST_Width*3/4;
CONST_Width1dot5 = CONST_Width*3/2;
CONST_Heighthalf = CONST_Height/2;
CONST_Widthquad = CONST_Width*4;
CONST_Heightdouble = CONST_Height*2;
CONST_Steepness = (double)CONST_Heighthalf / CONST_Width1fourth;
m_ImageWidth = getSize().width+CONST_Widthquad;
m_ImageHeight = getSize().height+CONST_Heightdouble;
m_MaxColumn = m_ImageWidth / CONST_Width3fourth;
m_MaxRow = m_ImageHeight / CONST_Height;
// Register this canvas for various notifications
m_Model.addElementListener(this);
addComponentListener(this);
// Create the selection ring to highlight hex grid elements
m_SelectionRing = new Area(new Polygon(new int[]{-1, CONST_Width1fourth-1, CONST_Width3fourth+1, CONST_Width+1, CONST_Width3fourth+1, CONST_Width1fourth-1}, new int[]{CONST_Heighthalf, -1, -1, CONST_Heighthalf, CONST_Height+1, CONST_Height+1}, 6));
m_SelectionRing.subtract(new Area(new Polygon(new int[]{2, CONST_Width1fourth+2, CONST_Width3fourth-2, CONST_Width-2, CONST_Width3fourth-2, CONST_Width1fourth+2}, new int[]{CONST_Heighthalf, 2, 2, CONST_Heighthalf, CONST_Height-2, CONST_Height-2}, 6)));
m_SelectionRingImage = new BufferedImage(CONST_Width, CONST_Height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = m_SelectionRingImage.createGraphics();
g.setColor(Color.WHITE);
g.fill(m_SelectionRing);
@Override public synchronized void paint(Graphics g2) {
// Caculate the offset of indexes to show
int offsetX = 2 * (m_ScrollPosition.x / CONST_Width1dot5) - 2;
int offsetY = (int)(Math.ceil(m_ScrollPosition.y / CONST_Height) - 1);
m_CurrentOffset = new Point(offsetX, offsetY);
// Check if the image is in the cache
Image drawing = m_Cache.get(m_CurrentOffset);
if (drawing == null) {
// The image is not cached, so draw it
drawing = new BufferedImage(m_ImageWidth, m_ImageHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = ((BufferedImage)drawing).createGraphics();
// Draw background
g.setColor(Color.BLACK);
g.fillRect(0, 0, m_ImageWidth, m_ImageHeight);
// Draw the hex grid
for (int column = 0; column <= m_MaxColumn; column += 2) {
for (int row = 0; row <= m_MaxRow; row++) {
// Draw even column
IHexGridElement element = m_Model.getElementAt(offsetX + column, offsetY + row);
if (element != null) { g.drawImage(element.getImage(m_ShowGrid), (int)(column*(CONST_Width3fourth-0.5)), CONST_Height*row, null); }
// Draw odd column
element = m_Model.getElementAt(offsetX + column+1, offsetY + row);
if (element!= null) { g.drawImage(element.getImage(m_ShowGrid), (int)(column*(CONST_Width3fourth-0.5)+CONST_Width3fourth), CONST_Heighthalf*(row*2+1), null); }
// Put the image into the cache
m_Cache.put(m_CurrentOffset, drawing);
// Calculate the position of the image to show
offsetX = CONST_Width1dot5 + (m_ScrollPosition.x % CONST_Width1dot5);
offsetY = CONST_Height + (m_ScrollPosition.y % CONST_Height);
m_PixelOffset = new Point(offsetX, offsetY);
g2.drawImage(drawing, -offsetX, -offsetY, null);
// If the selected element should he highlighted, then do so
if (m_ShowSelected) {
// Check if the selected element is on screen
if (isElementOnScreen(m_CurrentSelected)) {
// Correct vertical offset for odd columns
if ((m_CurrentSelected.x % 2 == 1)) { offsetY -= CONST_Heighthalf; }
// Draw the selection circle
g2.drawImage(m_SelectionRingImage, (m_CurrentSelected.x - m_CurrentOffset.x) * CONST_Width3fourth - offsetX - ((m_CurrentSelected.x + 1) / 2), (m_CurrentSelected.y - m_CurrentOffset.y) * CONST_Height - offsetY, null);
@Override public synchronized void update(Graphics g) { paint(g); }
public synchronized void componentResized(ComponentEvent e) {
// Upon resizing of the component, adjust several pre-calculated values
m_ImageWidth = getSize().width+CONST_Widthquad;
m_ImageHeight = getSize().height+CONST_Heightdouble;
m_MaxColumn = m_ImageWidth / CONST_Width3fourth;
m_MaxRow = m_ImageHeight / CONST_Height;
// And flush the cache
m_Cache.clear();
public void componentMoved(ComponentEvent e) { /* do nothing */ }
public void componentShown(ComponentEvent e) { /* do nothing */ }
public void componentHidden(ComponentEvent e) { /* do nothing */ }
public synchronized void elementUpdated(IHexGridElement Element) {
// Clear cache where the element may be contained at
for (Point p : m_Cache.keySet()) { if (isElementInScope(Element.getIndex(), p, new Point(p.x + m_MaxColumn, p.y + m_MaxRow))) { m_Cache.remove(p); } }
// Update the currently shown image if the update element is shown, too
if (isElementOnScreen(Element.getIndex())) { repaint(); }
/** <p>Returns the model visualized by this grid view.</p>
* @return The model visualized by this grid view.
public IHexGridModel getModel() { return m_Model; }
/** <p>Returns the current selected hex grid element.</p>
* @return The current selected hex grid element.
public IHexGridElement getSelected() { return m_Model.getElementAt(m_CurrentSelected.x, m_CurrentSelected.y); }
/** <p>Sets the current selected hex grid element by its index.</p>
* <p>If the selected hex grid element should be highlighted and is currently
* shown on the screen, then this method will {@link #repaint() redraw} this
* component automatically.</p>
* @param Index The index of the hex grid element to become the selected one.
* @throws IllegalArgumentException If the index refers to a non-existing hex
* grid element.
public synchronized void setSelected(Point Index) throws IllegalArgumentException {
// Check that the index is valid
if ((Index.x < 0) || (Index.y < 0) || (Index.x > m_Model.getXElements()) || (Index.y > m_Model.getYElements())) { throw new IllegalArgumentException("There is no hex grid element with such index."); }
m_CurrentSelected = Index;
// If the element is on screen and should be highlighted, then repaint
if (m_ShowSelected && isElementOnScreen(m_CurrentSelected)) { repaint(); }
/** <p>Moves the visible elements to the left by the number of pixels.</p>
* <p>To move the visible elements to the left by one hex grid element, pass
* {@link #CONST_Width3fourth} as the parameter. The component will
* automatically {@link #repaint()}.</p>
* @param Pixels The number of pixels to move to the left.
* @return The number of pixels moved to the left. This is always between 0
* and {@code abs(Pixels)}.
public synchronized int moveLeft(int Pixels) {
int delta = m_ScrollPosition.x - Math.max(0, m_ScrollPosition.x - Math.max(0, Pixels));
if (delta != 0) {
m_ScrollPosition.x -= delta;
repaint();
return delta;
/** <p>Moves the visible elements up by the number of pixels.</p>
* <p>To move the visible elements up by one hex grid element, pass {@link
* #CONST_Height} as the parameter. The component will automatically {@link
* #repaint()}.</p>
* @param Pixels The number of pixels to move up.
* @return The number of pixels moved up. This is always between 0 and {@code
* abs(Pixels)}.
public synchronized int moveUp(int Pixels) {
int delta = m_ScrollPosition.y - Math.max(0, m_ScrollPosition.y - Math.max(0, Pixels));
if (delta != 0) {
m_ScrollPosition.y -= delta;
repaint();
return delta;
/** <p>Moves the visible elements to the right by the number of pixels.</p>
* <p>To move the visible elements to the right by one hex grid element, pass
* {@link #CONST_Width3fourth} as the parameter. The component will
* automatically {@link #repaint()}.</p>
* @param Pixels The number of pixels to move to the right.
* @return The number of pixels moved to the right. This is always between 0
* and {@code abs(Pixels)}.
public synchronized int moveRight(int Pixels) {
int delta = Math.min(m_Model.getXElements() * CONST_Width3fourth + CONST_Width1fourth - getSize().width, m_ScrollPosition.x + Math.max(0, Pixels)) - m_ScrollPosition.x;
if (delta != 0) {
m_ScrollPosition.x += delta;
repaint();
return delta;
/** <p>Moves the visible elements down by the number of pixels.</p>
* <p>To move the visible elements down by one hex grid element, pass {@link
* #CONST_Height} as the parameter. The component will automatically {@link
* #repaint()}.</p>
* @param Pixels The number of pixels to move down.
* @return The number of pixels moved down. This is always between 0 and
* {@code abs(Pixels)}.
public synchronized int moveDown(int Pixels) {
int delta = Math.min(m_Model.getYElements() * CONST_Height + CONST_Heighthalf - getSize().height, m_ScrollPosition.y + Math.max(0, Pixels)) - m_ScrollPosition.y;
if (delta != 0) {
m_ScrollPosition.y += delta;
repaint();
return delta;
/** <p>Checks if the hex grid element of the given index is currently
* displayed on the screen (even just one pixel).</p>
* <p>The intention of this method is to check if a {@link #repaint()} is
* necessary or not.</p>
* @param ElementIndex The index of the element to check.
* @return {@code true} if the hex grid element of the given index is
* displayed on the screen, {@code false} if not.
public synchronized boolean isElementOnScreen(Point ElementIndex) { return isElementInScope(ElementIndex, m_CurrentOffset, new Point(m_CurrentOffset.x + m_MaxColumn, m_CurrentOffset.y + m_MaxRow)); }
/** <p>Checks if the hex grid element of the given index is within the given
* indexes.</p>
* <p>The intention of this method is to check if a {@link #repaint()} is
* necessary or not.</p>
* @param ElementIndex The index of the element to check.
* @param ReferenceIndexLeftTop The left top index of the area to check.
* @param ReferenceIndexRightBottom The right bottom index of the area to check.
* @return {@code true} if the hex grid element of the given index is within
* the given area, {@code false} if not.
public synchronized boolean isElementInScope(Point ElementIndex, Point ReferenceIndexLeftTop, Point ReferenceIndexRightBottom) { if ((ElementIndex.x >= ReferenceIndexLeftTop.x) && (ElementIndex.x <= ReferenceIndexRightBottom.x) && (ElementIndex.y >= ReferenceIndexLeftTop.y) && (ElementIndex.y <= (ReferenceIndexRightBottom.y))) { return true; } else { return false; } }
/** <p>Return the {@link IHexGridElement hex grid element} shown at the given
* pixel on the screen.</p>
* <p><b>Remark: There seems to be a bug in retrieving the proper element,
* propably caused by rounding errors and unprecise pixel calculations.</p>
* @param P The pixel on the screen.
* @return The {@link IHexGridElement hex grid element} shown at the pixel.
public synchronized IHexGridElement getElementAtPixel(Point P) {
// @FIXME Here seems to be some bugs remaining
int dummy = 0; // Variable for warning to indicate that there is something to do :)
// Calculate the pixel on the image, not on the screen
int px = P.x + m_PixelOffset.x;
int py = P.y + m_PixelOffset.y;
// Determine the x-index of the column (is maybe decreased by one)
int x = px / CONST_Width3fourth + m_CurrentOffset.x;
// If the column is odd, then shift the y-pixel by half element height
if ((x % 2) == 1) { py -= CONST_Heighthalf; }
// Determine the y-index of the row (is maybe decreased by one)
int y = py / CONST_Height + m_CurrentOffset.y;
// Normative coordinates to a single element
px -= (x - m_CurrentOffset.x) * CONST_Width3fourth;
py -= (y - m_CurrentOffset.y) * CONST_Height;
// Check if the normative pixel is in the first quarter of a column
if (px < CONST_Width1fourth) {
// Adjustments to the index may be necessary
if (py < CONST_Heighthalf) {
// We are in the upper half of a hex-element
double ty = CONST_Heighthalf - CONST_Steepness * px;
if (py < ty) { x--; }
} else {
// We are in the lower half of a hex-element
double ty = CONST_Heighthalf + CONST_Steepness * px;
if (py > ty) {
x--;
y++;
return m_Model.getElementAt(x, y);
}Ah, just to give you some idea: I use this component to visualize a hex grid map with more than 1 million grid elements. And it works, really fast, and requires less than 10 MByte of memory. -
Java.awt.IllegalComponentStateException in JTable
Hi folks,
I am trying to write a JTable cell validation. Input data in a cell, if failure, prompt message and set focus & editing back to the cell. I've tried InputVerifier() but it doesn't work since I can easily use the mouse click to shift to other cells in the same table.
What I am trying to do now is to define my DefaultCellEditor. I record the row & index position when getting focus. In the lost focus event, do the validation and set the focus & editing back if failure. Seems it works fine. However, when I randomly click different cells in the table quickly. It prompts:
"java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location"
Here is my stack dump:
at java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:1487)
at java.awt.Component.getLocationOnScreen(Component.java:1461)
at javax.swing.Autoscroller.mouseDragged(Autoscroller.java:79)
at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:2759)
at java.awt.Component.processEvent(Component.java:4822)
at java.awt.Container.processEvent(Container.java:1525)
at java.awt.Component.dispatchEventImpl(Component.java:3526)
at java.awt.Container.dispatchEventImpl(Container.java:1582)
at java.awt.Component.dispatchEvent(Component.java:3367)
at javax.swing.plaf.basic.BasicTableUI$MouseInputHandler.repostEvent(BasicTableUI.java:475)
at javax.swing.plaf.basic.BasicTableUI$MouseInputHandler.mouseDragged(BasicTableUI.java:554)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:258)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:257)
at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:257)
at java.awt.Component.processMouseMotionEvent(Component.java:5069)
at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:2763)
at java.awt.Component.processEvent(Component.java:4822)
at java.awt.Container.processEvent(Container.java:1525)
at java.awt.Component.dispatchEventImpl(Component.java:3526)
at java.awt.Container.dispatchEventImpl(Container.java:1582)
at java.awt.Component.dispatchEvent(Component.java:3367)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3359)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3091)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3004)
at java.awt.Container.dispatchEventImpl(Container.java:1568)
at java.awt.Window.dispatchEventImpl(Window.java:1581)
at java.awt.Component.dispatchEvent(Component.java:3367)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:445)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:191)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)
Also, enclosed is my modified DefaultCellEditor class. Your input will be greatly appreicated. Thanks.
class NewDefaultCellEditor extends DefaultCellEditor {
public NewDefaultCellEditor(JTextField jTextField) {
super(jTextField);
this.setClickCountToStart(1);
jTextField.addFocusListener(new FocusAdapter() {
JTable tbl;
int row;
int column;
public void focusGained(FocusEvent e) {
tbl = (JTable)((JTextField)e.getSource()).getParent();
row = tbl.getEditingRow();
column = tbl.getEditingColumn();
public void focusLost(FocusEvent e) {
/*** Put validation here, execute the following if failed ***/
tbl.editCellAt(row, column);
((JTextField)e.getSource()).requestFocus();Your use in a JTable isn't too clear to me, but I feel you're overthinking the basic requirement:
I have an extended JComboBox which is meant to display its information only. Thus it
- does not allow any selection
- shows the first item of the list in the TextField only and not once more in the listI don't see the need for duplicating the model and using a popup menu listener.
import java.awt.Component;
import javax.swing.*;
public class DisplayOnlyComboBoxDemo {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new DisplayOnlyComboBoxDemo().makeUI();
public void makeUI() {
JFrame frame = new JFrame();
frame.add(new DisplayOnlyComboBox("One", new String[]{"Two", "Three", "Four", "Five"}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
class DisplayOnlyComboBox extends JComboBox {
private String firstItem;
public DisplayOnlyComboBox(String firstItem, String[] items) {
super(items);
this.firstItem = firstItem;
setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (index == -1) {
setText(DisplayOnlyComboBox.this.firstItem);
return this;
}db -
Hi.........
Why RGB colors created using a constructor of the class java.awt.Color as given below:
myColor = new Color(r, g, b);
whereas HSB colors are created using a static member function
myColor = Color.getHSBColor(h, s, b);
what is the reason behind it ???
thanks with regards........There can't be two constructors with the same parameters (float, float, float).
-
How to restrict the maximum size of a java.awt.ScrollPane
Dear all,
I would like to implement a scroll pane which is resizable, but not to a size exceeding the maximum size of the java.awt.Canvas that it contains.
I've sort of managed to do this by writing a subclass of java.awt.ScrollPane which implements java.awt.event.ComponentListener and has a componentResized method that checks whether the ScrollPane's viewport width (height) exceeds the content's preferred size, and if so, resizes the pane appropriately (see code below).
It seems to me, however, that there ought to be a simpler way to achieve this.
One slightly weird thing is that when the downsizing of the pane happens, the content can once be moved to the left by sliding the horizontal scrollbar, but not by clicking on the arrows. This causes one column of gray pixels to disappear and the rightmost column of the content to appear; subsequent actions on the scrollbar does not have any further effect. Likewise, the vertical scrollbar can also be moved up once.
Also, I would like a java.awt.Frame containing such a restrictedly resizable scrollpane, such that the Frame cannot be resized by the user such that its inside is larger than the maximum size of the scrollpane. The difficulty I encountered with that is that setSize on a Frame appears to set the size of the window including the decorations provided by the window manager (fvwm2, if that matters), and I haven't been able to find anything similar to getViewportSize, which would let me find out the size of the area inside the Frame which is available for the scrollpane which the frame contains.
Thanks in advance for hints and advice.
Here's the code of the componentResized method:
public void componentResized(java.awt.event.ComponentEvent e)
java.awt.Dimension contentSize = this.content.getPreferredSize();
this.content.setSize(contentSize);
java.awt.Dimension viewportSize = getViewportSize();
System.err.println("MaxSizeScrollPane: contentSize = " + contentSize);
System.err.println("MaxSizeScrollPane: viewportSize = " + viewportSize);
int dx = Math.max(0, (int) (viewportSize.getWidth() - contentSize.getWidth()));
int dy = Math.max(0, (int) (viewportSize.getHeight() - contentSize.getHeight()));
System.err.println("MaxSizeScrollPane: dx = " + dx + ", dy = " + dy);
if ((dx > 0) || (dy > 0))
java.awt.Dimension currentSize = getSize();
System.err.println("MaxSizeScrollPane: currentSize = " + currentSize);
setSize(new java.awt.Dimension(((int) currentSize.getWidth()) - dx, ((int) currentSize.getHeight()) - dy));
System.err.println();
}Best regards, Janimport java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class ScrollPaneTest
GraphicCanvas canvas;
CustomScrollPane scrollPane;
private Panel getScrollPanel()
canvas = new GraphicCanvas();
scrollPane = new CustomScrollPane();
scrollPane.add(canvas);
// GridBagLayout allows scrollPane to remain at
// its preferred size during resizing activity
Panel panel = new Panel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
panel.add(scrollPane, gbc);
return panel;
private WindowListener closer = new WindowAdapter()
public void windowClosing(WindowEvent e)
System.exit(0);
private Panel getUIPanel()
int w = canvas.width;
int h = canvas.height;
int visible = 100;
int minimum = 200;
int maximum = 500;
final Scrollbar
width = new Scrollbar(Scrollbar.HORIZONTAL, w,
visible, minimum, maximum),
height = new Scrollbar(Scrollbar.HORIZONTAL, h,
visible, minimum, maximum);
AdjustmentListener l = new AdjustmentListener()
public void adjustmentValueChanged(AdjustmentEvent e)
Scrollbar scrollbar = (Scrollbar)e.getSource();
int value = scrollbar.getValue();
if(scrollbar == width)
canvas.setWidth(value);
if(scrollbar == height)
canvas.setHeight(value);
canvas.invalidate();
scrollPane.validate();
width.addAdjustmentListener(l);
height.addAdjustmentListener(l);
Panel panel = new Panel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2,2,2,2);
gbc.weightx = 1.0;
addComponents(new Label("width"), width, panel, gbc);
addComponents(new Label("height"), height, panel, gbc);
gbc.anchor = GridBagConstraints.CENTER;
return panel;
private void addComponents(Component c1, Component c2, Container c,
GridBagConstraints gbc)
gbc.anchor = GridBagConstraints.EAST;
c.add(c1, gbc);
gbc.anchor = GridBagConstraints.WEST;
c.add(c2, gbc);
public static void main(String[] args)
ScrollPaneTest test = new ScrollPaneTest();
Frame f = new Frame();
f.addWindowListener(test.closer);
f.add(test.getScrollPanel());
f.add(test.getUIPanel(), "South");
f.pack();
f.setLocation(200,200);
f.setVisible(true);
f.addComponentListener(new FrameSizer(f));
class GraphicCanvas extends Canvas
int width, height;
public GraphicCanvas()
width = 300;
height = 300;
public void paint(Graphics g)
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int dia = Math.min(width, height)*7/8;
g2.setPaint(Color.blue);
g2.draw(new Rectangle2D.Double(width/16, height/16, width*7/8, height*7/8));
g2.setPaint(Color.green.darker());
g2.draw(new Ellipse2D.Double(width/2 - dia/2, height/2 - dia/2, dia-1, dia-1));
g2.setPaint(Color.red);
g2.draw(new Line2D.Double(width/16, height*15/16-1, width*15/16-1, height/16));
public Dimension getPreferredSize()
return new Dimension(width, height);
public Dimension getMaximumSize()
return getPreferredSize();
public void setWidth(int w)
width = w;
repaint();
public void setHeight(int h)
height = h;
repaint();
class CustomScrollPane extends ScrollPane
Dimension minimumSize;
public Dimension getPreferredSize()
Component child = getComponent(0);
if(child != null)
Dimension d = child.getPreferredSize();
if(minimumSize == null)
minimumSize = (Dimension)d.clone();
Insets insets = getInsets();
d.width += insets.left + insets.right;
d.height += insets.top + insets.bottom;
return d;
return null;
public Dimension getMinimumSize()
return minimumSize;
public Dimension getMaximumSize()
Component child = getComponent(0);
if(child != null)
return child.getMaximumSize();
return null;
class FrameSizer extends ComponentAdapter
Frame f;
public FrameSizer(Frame f)
this.f = f;
public void componentResized(ComponentEvent e)
Dimension needed = getSizeForViewport();
Dimension size = f.getSize();
if(size.width > needed.width || size.height > needed.height)
f.setSize(needed);
f.pack();
* returns the minimum required frame size that will allow
* the scrollPane to be displayed at its preferred size
private Dimension getSizeForViewport()
ScrollPane scrollPane = getScrollPane(f);
Insets insets = f.getInsets();
int w = scrollPane.getWidth() + insets.left + insets.right;
int h = getHeightOfChildren() + insets.top + insets.bottom;
return new Dimension(w, h);
private ScrollPane getScrollPane(Container cont)
Component[] c = cont.getComponents();
for(int j = 0; j < c.length; j++)
if(c[j] instanceof ScrollPane)
return (ScrollPane)c[j];
if(((Container)c[j]).getComponentCount() > 0)
return getScrollPane((Container)c[j]);
return null;
private int getHeightOfChildren()
Component[] c = f.getComponents();
int extraHeight = 0;
for(int j = 0; j < c.length; j++)
int height;
if(((Container)c[j]).getComponent(0) instanceof ScrollPane)
height = ((Container)c[j]).getComponent(0).getHeight();
else
height = c[j].getHeight();
extraHeight += height;
return extraHeight;
} -
Whats the use of having pragma autonomous transaction
Hii All,
The below is the procedure developed by our predecessors.We are making use of this for writing our debug messages.
I'm aware of pragma autonomous transaction ,this allows my code to run independently of the calling program.
But here we are just using utl_File and we are neither using any DML(Inserting error messages into a table) or DDL statements in the below code.
What is real use of having pragma autonomous transaction.???This code is working in the same way even without the pragma...I dont' find any difference .
Please let me know the use of having pragma autonomous transaction in the below procedure and where it actually comes into usage.
Create or replace Procedure logmesg
p_file_name in varchar2,
p_mesg_text in varchar2,
p_dir_path in varchar2 default fn_get_debug_path,
p_file_ext in varchar2 default 'log',
p_append_flag in varchar2 default 'Y'
) Is
pragma autonomous_transaction;
l_utl_file utl_file.file_type;
l_append_flag varchar2(1);
l_mesg_text varchar2(32000);
l_file_name varchar2(3000);
l_dir_path varchar2(32000);
l_delimeter_occurance number;
l_buffer_str varchar2(32000);
Begin
if trim(p_dir_path) is null then
l_dir_path := fn_get_debug_path ;
else
l_dir_path := p_dir_path;
end if;
l_mesg_text := p_mesg_text;
l_append_flag := nvl(p_append_flag,'Y');
l_file_name := p_file_name||'_'||to_char(sysdate,'ddmmyyyyhh')||'.'||p_file_ext;
l_append_flag := Case l_append_flag
When 'Y' then 'a'
When 'N' then 'w'
End;--l_append_flag
Begin
l_utl_file := utl_file.fopen(l_dir_path,l_file_name,l_append_flag);
Exception
When Others Then
l_utl_file := utl_file.fopen(l_dir_path,l_file_name,'w');
End;
if dbms_lob.getlength(l_mesg_text) > 32000 then
loop
exit when dbms_lob.getlength(l_mesg_text) < 32000;
l_delimeter_occurance := dbms_lob.instr(l_mesg_text,chr(32),1,1);
l_buffer_str := dbms_lob.substr(l_mesg_text,l_delimeter_occurance-1);
utl_file.put_line(l_utl_file,l_buffer_str);
l_mesg_text := dbms_lob.substr(l_mesg_text,l_delimeter_occurance+1);
utl_file.fflush(l_utl_file);
end loop;
end if;
utl_file.put_line(l_utl_file,l_mesg_text);
utl_file.fflush(l_utl_file);
utl_file.fclose(l_utl_file);
End logmesg;
/HerePlease let me know the use of having pragma autonomous transaction in the below procedure and where it actually comes into usage.Seems it is redundant in that procedure, and doesn't add any value, since the procedure isn't doing anything 'transactional'.
I would remove it. -
What are the key fields used to group double orders in t-code SDD1?
What are the key fields used to group double orders in t-code SDD1?
Cheers,
VTHi,
You can group the duplicate sales documents with the help of the following fields,
Sold-To-Party,Document type,date and sales area details.
Regards,
Gopal. -
I am having trouble with my JAVA Applet. It isn't functioning on SAFARI. It seems to have stopped working and I used it on SAFARI last year. Any suggestions?
Post in the Safari forum area.
-
What is wrong with Firefox ---It will not pull up anything the way it used to --having to use exployer instead ---Help
The catalog of our University will not pull up properly on Firefox but will on internet exployer Why?The #rdn# is a url variable that is pass to this form from
another page. I put it in a hidden filed and originallly used it as
from.rdn. That did not make a difference, so I just used rdn.
The cfoutput to display the rdn, partnumberid,
deliverynumber, totalrows, and row, all display properly. I even
use those in the query anlayzer and the update works.
I will remove the crparam and see if that makes any
difference. This is very frustrating since there are no error
messages and I am led to believe the code works. -
Open Folder by double click using java.awt
Hello Guys,
I have a problem. I m listing directory in List(java.awt). When i single click on directory it will open. But how i can double click on that directory then and then it will open otherwise not. By using JAVA.AWT.According to the documentation for java.awt.List "When an item is selected or
deselected by the user, AWT sends an instance of ItemEvent to the list. When
the user double-clicks on an item in a scrolling list, AWT sends an instance of
ActionEvent to the list following the item event. AWT also generates an action
event when the user presses the return key while an item in the list is selected."
If your directories are "opening" (whatever that means) in response to a single
click, that it because of how you have written your code. Change it so that action
events rather than item events cause the opening to happen. -
Using environment variable / double quotes in "Arguments" in "Server Start"
I have an admin server, NodeManager, and 1 managed server, all on the same machine (windows). I am trying to enter something similar to this to the arguments field in the Server Start tab:
-Dmy.property=%USERPROFILE%\someDir\someJar.jar
But when the managed server is started it throws this exception:
Error opening zip file or JAR manifest missing : %USERPROFILE%\someDir\someJar.jar
It appears that the environment variable is not being translated into it's value. It is just passed on to the managed server as plain-text. I tried surrounding the path with double quotes (") but the console validates the input and does not allow this: *"Arguments may not contain '"'"*
Even editing the config.xml file manually cannot work, as the admin server fails to startup after this:
<Critical> <WebLogicServer> <BEA-000362> <Server failed. Reason: [Management:141266]Parsing failure in config.xml: java.lang
.IllegalArgumentException: Arguments may not contain '"'.>
I also tried using %20 to no avail, it is just passed as %20.
I thought that perhaps this had something to do with the spaces in the value of %USERPROFILE% (which is "C:\documents and settings.."), but the same thing happens with other env. variables which point to other directories with no spaces.
_My question:_
Is there any supported way of :
using double quotes? what if i have to reference a folder with spaces in it's name?
reference an environment variable? What if i have to rely on it's value for distributed servers where i do not know in advance the variable's value?
Edited by: 937622 on Sep 28, 2012 1:02 AMThere is workaround : http://stackoverflow.com/questions/12629395/weblogic-using-environment-variable-double-quotes-in-arguments-in-server
Just posting here for reference. Let's see if we get a different answer from anyone else.
Maybe you are looking for
-
Photos on CD made by Dell Desktop - trying to open in Macbook Pro
I have a CD-R with photos that was made on a Dell desktop computer. When I put the CD in my MacBook Pro it doesnt read the CD. Is there a way to convert these photos so that my MBkPro can read the CD?
-
[SOLVED] 'ata3: EH complete' errors only when using GNOME
Hello, when I use GNOME as my DE, I start to get 'ata3: EH complete' errors on dmesg. ata3 is where my hard drive is connected to. Usually one would get those messages if the hard drive was going to failure, but the hard drive seems to be OK (smartct
-
Problem setting UK extended keyboard layout
I have an UK keyboard but I want to use UK Extended (WinKeys?) layout. According to the following I should use extd: $ cat /usr/share/X11/xkb/rules/xorg.lst | grep -i uk ua Ukrainian gb English (UK) guru in: Punjabi (Gurmukhi) jhelum in: Punjabi (Gur
-
Downloading and installing MediaSou
Hello. The CD-dri've of my computer doesn't work, so I've tried to download MediaSource from this site. No problem. Then installing. All goes fine, untill at the very end. The installer will say something like this: The installer didn't find a suppor
-
Nonce property in WCF custom adapter
Hello All, How to configure Nonce property in WCF Custom Adapter in Biztalk. I have created custom assembly as mentioned in other blogs(http://weblog.west-wind.com/posts/2012/Nov/24/WCF-WSSecurity-and-WSE-Nonce-Authentication), where we can create Us