Skip to main content

I don't get the point.

4 replies [Last post]
Darrin
Offline
Joined: 2006-02-17

Make that, I don't get the CORRECT point.

What I have is a group of images stored in a jar file that I load into ImageIcons that get placed into a scroll pane that gets put into a label that gets put into a tabbed pane. The ImageIcon can be zoomed in and out

Before I put the "resetPoint" (my home grown method) call in, when I click on the image (which is centered) to drop my begin and end points, the line that gets drawn is off one way or the other in both the X and Y directions. If I click in the very upper left hand corner of the scroll pane and draw a line from there, then it will ALWAYS (no matter if the image is zoomed, etc.) get drawn on the image in its upper left hand corner.

I've tried everything I can think of but the points I use for drawing a line on an image don't match up to what they should. It was suggested that I try using convertPoint but unless I'm using it incorrectly (and I tried every way that seemed to make sense) this doesn't do any good. In fact, it intruduces some error (at least the way I was using it..now commented out).

Note that the code (restPoint) does work in the X position if the image isn't zoomed in or out (the Y position is shifted up slightly). If the image is shrunk, then the Y position is still high, but the X position is is wrong in that it is both shifted to the left and the line is too short (the end point is too far left when drawing from left to right). If the image is enlarged, then the Y is too far down, and the line is too big with the left to far left, and the right too far right but NOT in proportion!

If anyone knows what I need to do to adjust the points please tell me. The logic I am using SEEMS right to me (scrollpane size / 2 - image size / 2 to get the start of where the image should be)

Here is the relevant code:

</p>
<p>private void drawLine()<br />
    {<br />
        m_jsPane = (JScrollPane) m_tabbedPane.getSelectedComponent();<br />
        m_port = m_jsPane.getViewport();</p>
<p>        GrabAndScrollLabel gnsLabel = (GrabAndScrollLabel) m_port.getView();</p>
<p>        m_currentImageIcon = (ImageIcon) gnsLabel.getIcon();</p>
<p>        m_currentImage = m_currentImageIcon.getImage();</p>
<p>        try<br />
        {<br />
            MediaTracker tracker = new MediaTracker(this);<br />
            tracker.addImage(m_currentImage, 0);<br />
            tracker.waitForID(0);<br />
        }<br />
        catch (InterruptedException ie)<br />
        {<br />
            System.out.println("Interupted in draw");<br />
        }</p>
<p>        int iw = m_currentImage.getWidth(this);<br />
        int ih = m_currentImage.getHeight(this);</p>
<p>        m_buffIm = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB);</p>
<p>        m_XOffset = m_jsPane.getX();<br />
        m_YOffset = m_jsPane.getY();</p>
<p>        big = m_buffIm.createGraphics();</p>
<p>        big.drawImage(m_currentImage, 0, 0, this);</p>
<p>        Point oldPoint = new Point(m_startX, m_startY);</p>
<p>        Point point1 = resetPoint(oldPoint);</p>
<p>        oldPoint.x = m_endX;<br />
        oldPoint.y = m_endY;</p>
<p>        Point point2 = resetPoint(oldPoint);</p>
<p>        OraLine oraLine = new OraLine(point1, point2);</p>
<p>        gnsLabel.get_oraImage().getImageModHolder().add_shape(oraLine);</p>
<p>        gnsLabel.applyModifications(big);</p>
<p>        final GrabAndScrollLabel gnsFinal = gnsLabel;</p>
<p>        ImageIcon icon = (ImageIcon) gnsLabel.getIcon();<br />
        ImageIcon newIcon = new ImageIcon(icon.getImage())<br />
        {<br />
            public void paintIcon(Component c, Graphics g, int x, int y)<br />
            {<br />
              super.paintIcon(c, g, x, y);<br />
              g.translate(x, y);  // don't forget this one!<br />
              g.setColor(Color.BLACK);</p>
<p>              gnsFinal.applyModifications((Graphics2D)g);</p>
<p>//              g.drawLine(0,0, 20, 20);<br />
            }<br />
        };</p>
<p>        gnsLabel.setIcon(newIcon);</p>
<p>        m_port.setView(gnsLabel);</p>
<p>        m_jsPane.setViewport(m_port);</p>
<p>        getRootPane().revalidate();<br />
        getRootPane().repaint();<br />
    }</p>
<p>private Point resetPoint(Point oldPoint)<br />
    {<br />
        JScrollPane jsp = (JScrollPane) m_tabbedPane.getSelectedComponent();<br />
        JViewport port = jsp.getViewport();<br />
        GrabAndScrollLabel gnsLabel = (GrabAndScrollLabel) m_port.getView();</p>
<p>        //Left this in, but it really does nothing..in = out every time<br />
        //Point newPoint = SwingUtilities.convertPoint(jsp, oldPoint, gnsLabel);</p>
<p>        int nJspWidth  = jsp.getWidth();<br />
        int nJspHeight = jsp.getHeight();</p>
<p>        //This returns the image's size after zooming<br />
        double nImgWidth  = gnsLabel.getDisplayedImageWidth();<br />
        double nImgHeight = gnsLabel.getDisplayedImageHeight();</p>
<p>        double xOffset = (nJspWidth / 2) - (nImgWidth / 2);<br />
        double yOffset = (nJspHeight / 2) - (nImgHeight / 2);</p>
<p>        //was using newPoint, but it introduced a small error<br />
        oldPoint.x -= xOffset;<br />
        oldPoint.y -= yOffset;</p>
<p>        return new Point(oldPoint);<br />
    }</p>
<p>

Thanks.

Message was edited by: Darrin

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Darrin
Offline
Joined: 2006-02-17

I'm not sure what I did, but it works fine now until I zoom. The lines I set before the zoom are taken care of just fine, but the lines I draw after the zoom still have problems.

Here is some more code which may shed some light on it:

[code]
public BufferedImage applyModifications(Graphics2D g2D)
{
ImageIcon icon = oraImage.getImageIcon();
BufferedImage bi = new BufferedImage(icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB);

ImageModHolder mods = oraImage.getImageModHolder();

//###### Notice the scale here ######
g2D.scale(mods.getZoomFactor(), mods.getZoomFactor());

Iterator shapeIter = mods.getShapeList().iterator();

while(shapeIter.hasNext())
{
OraShape shape = (OraShape)shapeIter.next();
shape.draw(g2D);
}

return bi;
}

[/code]

Here is some more information:

Case #1: Where the image is expanded, if you try to draw a line in the upper portion of the image, then the line that is drawn is too high (smaller Y values) and too long.

If you try to draw on the lower portion of the image, then the line is too low (larger Y values) and too long.

Case 2: Where the image is shrunk, if you try to draw a line in the upper portion of the image, then the line that is drawn is too low and too short (the opposite of what happened in case 1).

If you try to draw on the lower portion of the image, then the line is too high and too short (the opposite of what happened in case 1).

In either case, the amount of shift (high or low) seems to be progressive...the further from the center of the image you are, the more of a shift occurs.

Strange!

Message was edited by: Darrin

Darrin
Offline
Joined: 2006-02-17

Well I was able to get the scale of the line correct, but the tranlation is still off. As the scale/zoom goes up from 100%, the line is drawn to the left and high at an increasing rate. As the scale goes down from, 100% the line is drawn to the right and low at an increasing rate.

Here is what my latest code looks like. Any thoughts on what I'm doing wrong would be appreciated. Thanks.

[code]
private Point resetPoint(Point oldPoint)
{
JScrollPane jsp = (JScrollPane) m_tabbedPane.getSelectedComponent();
JViewport port = jsp.getViewport();
GrabAndScrollLabel gnsLabel = (GrabAndScrollLabel) m_port.getView();

double nImgWidth = gnsLabel.getOraImage().getOriginalImageWidth();
double nImgHeight = gnsLabel.getOraImage().getOriginalImageHeight();

Point newPoint = SwingUtilities.convertPoint(jsp, oldPoint, gnsLabel);

int nPortWidth = port.getWidth();
int nPortHeight = port.getHeight();

double xOffset = (nPortWidth / 2) - (nImgWidth / 2);
double yOffset = (nPortHeight / 2) - (nImgHeight / 2);

//Adjust for Zoom
double zoom = gnsLabel.getOraImage().getImageModHolder().getZoomFactor();

if(port.getHeight() < gnsLabel.getHeight())
{
//Shunken viewport in vertical direction
if(zoom == 1.0)
{
newPoint.y = oldPoint.y;
}
else
{
//Have to handle the scale
//Now handle the translate
}
}
else
{
if(zoom == 1.0)
{
newPoint.y -= yOffset;
}
else
{
//Have to handle the scale
newPoint.y /= zoom;

//Now handle the translate fixed amount first
newPoint.y -= yOffset;

//Now the variable amount
//??????????????????

}
}

if(port.getWidth() < gnsLabel.getWidth())
{
//Shunken viewport in horizontal direction
if(zoom == 1.0)
{
newPoint.x = oldPoint.x;
}
else
{
//Have to handle the scale
newPoint.x /= zoom;

//Now handle the translate
}
}
else
{
if(zoom == 1.0)
{
newPoint.x -= xOffset;
}
else
{
//Have to handle the scale
newPoint.x /= zoom;

//Now handle the translate..take off the fixed amount first
newPoint.x -= xOffset;

//Now the variable amount
//??????????????????

}
}

return new Point(newPoint);
}

[/code]

zander
Offline
Joined: 2003-06-13

This problem has little to do with Java, so i am not sure you will get your aswer here.
Check AffineTransform. While this is a class in Java, it just implements commong graphics ideas. Many graphicsProgramming books will talk about it.
ps. Also don't forget to read the API docs describing the Graphics and Graphics2D classes!!

Basically; this is stuff you have to read up on, otherwise you can outsource the problem, but via the forums will not be a very good way to get your app working.

Oh, and don't forget to translate before you scale.

Happy reading !

Darrin
Offline
Joined: 2006-02-17

Thanks.

I'll check into the docs on the subjects you mention.