0

I am in the midst of attempting to program a GUI-based game application using Java Swing components. The basic framework is as follows: A JFrame which contains a JScrollPane and a JPanel. The JScrollPane further contains a JPanel containing a two-layer JLayeredPane which itself contains two JPanels. (For the curious, the two JPanels correspond to a units pane for the upper-most, non-opaque panel and a terrain pane for the lower-most, opaque panel.)

Automated window scrolling is a feature of the program as it stands. To clarify, the code as written automatically designates an appropriate unit as the window target and then proceeds to scroll the visible window in such a manner so as to display that unit in as close to a central position on screen as is possible given the window display constraints. This procedure is the source of my dilemma. In any given method execution, excepting those calls to the method made prior to re-sizing the window, the method works exactly as it should. It is solely in the initial start up of the application that the method functions improperly.

I believe my code is rather too long to post in its entirety in the context of this post, so I will initially provide solely the code which handles window scrolling and then post additional code as is necessary to a public DropBox account.

private void scrollWindowToUnit(int targetUnit) {
    System.out.println(((GenericUnit) unitsPane.getComponent(targetUnit))
            .getUnitName());
    int upLeftX = unitsPane.getLocation().x;
    int upLeftY = unitsPane.getLocation().y;
    Point scrollDest = new Point(unitsPane.getComponent(targetUnit)
            .getLocation().x - (screenSize.width / 2), unitsPane
            .getComponent(targetUnit).getLocation().y
            - ((screenSize.height - infoPane.getHeight()) / 2) + 24);

    if (scrollDest.x < upLeftX) {
        scrollDest.x = upLeftX + 24;
    }

    if (scrollDest.y < upLeftY) {
        scrollDest.y = upLeftY + 24;
    }

    jScrollPane.getViewport().setViewPosition(scrollDest);

    repaint();
    revalidate();
}

I have already completed a fairly robust testing of this method and my results are as follows, When the application is initially launched, the values held within the upLeftX and upLeftY are both set to -24. This is consistent throughout the execution of the program. (It is fairly odd that each is set to a negative value but it seems manageable enough.) However, the values within scrollDest vary between the initial start up of the program and subsequent runs. Essentially, what occurs is that the code obtains values for scrollDest.x and scrollDest.y which are negative integers less than -24.

After a brief example run including print statements, the following results were printed.

scrollDest.x and y: -800 -336

scrollDest.x and y: 0 0

scrollDest.x and y: 1051 2145

scrollDest.x and y: 1051 2145

scrollDest.x and y: 610 -312

scrollDest.x and y: 610 0

The line System.out.println("scrollDest.x and y: " + scrollDest.x + " " + scrollDest.y); was placed both before and after the two if statements of the above method. The values reflect the first call of the method by the program on a unit, called ONE for convenience, followed by the second call by the program upon a different unit elsewhere on the board, TWO, followed lastly by a third call of the method once again upon ONE.

This inconsistency is either the root or the reflection of my problem and I have yet to devise a reliable way to fix the issue.

I would gladly answer any questions regarding clarifications or elaborations. Thank you all in advance for your assistance!

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 1
    For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Feb 20 '13 at 06:09
  • 1
    A lot of your problems stem from the conversion of the locations from one coordinate space to another. Instead of using the view port to change the position directly, take advantage of `JComponent#scrollRectToVisible` instead. – MadProgrammer Feb 20 '13 at 06:14

1 Answers1

2

not sure if you want to centering some JComponents in the JViewport, is possible by calculating two Rectangles (rect returns desired JComponent, rect2 is rectangle from JViewport)

JScrollPane.scrollRectToVisible(new Rectangle(rect.x, rect.y, 
    (int) rect2.getWidth(), (int) rect2.getHeight()));

but easiest will be

JScrollPane.scrollRectToVisible(myDesiredComponents.getBounds());

notice all events to JScrollPane must be done on Event Dispatch Thread

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • In reply to mKorbel, I believe my issue is of a different sort. I want specifically to ensure that a method that works regularly after it is first called, works reliably at all times rather than just the second, third, fourth, and so on times that it is called. Thank you for your reply all the same though! – Nigel_Baldwen Feb 20 '13 at 07:13
  • 2
    @user2089461: You may be correct, but `scrollRectToVisible()` is reliable. You might examine this [example](http://stackoverflow.com/a/7820703/230513) as a starting point for your [sscce](http://sscce.org/). – trashgod Feb 20 '13 at 12:01