Java Tips Weblog

  • Blog Stats

    • 2,571,874 hits
  • Categories

  • Archives

Card Layout Focus

Posted by Rob Camick on October 31, 2008

The CardLayout can be a flexible layout manager to use. Although I think it has two related drawbacks:

  • focus is not placed on the Card as it is displayed
  • there is no API to determine which Card is currently being displayed

If you could somehow solve the second problem then you could implement the first.

So, I decided to extend the CardLayout to provide some additional functionality. To address the above issues I created the RXCardLayout class with support added for the following methods:

  • setRequestFocusOnCard (default true) – when true, the Card will request focus every time it is displayed
  • isRequestFocusOnCard – returns the state of the above method
  • getCurrentCard – returns the current Card being displayed.

When using the next(…) method of the CardLayout, the displayed Cards will wrap from the last to the first and there is no way to know when you are displaying the last Card. Similiarly, when using the previous(…) method you don’t know when you are displaying the first Card and you will wrap to the last Card. You may wish to control this wrapping process and stop when you reach the last or first card respectively. The following methods will help with this:

  • isNextCardAvailable – returns false when currently displaying the last card, true otherwise
  • isPreviousCardAvailable – returns false when currently displaying the first card, true otherwise

The key to providing support for all the above methods is the HierarchyListener. As a card is added to the layout manager, a HierarchyListener is added to the card. We will now be notified whenever a new card is displayed.

Stay tuned for my next blog entry for further extensions that will make the CardLayout even more programmer friendly.

Get The Code

RXCardLayout.java

Related Reading

How to Use Card Layout
Java API: java.awt.event.HierarchyListener

6 Responses to “Card Layout Focus”

  1. boots said

    Cool I just found your code it was just what I wanted for a project I’m working on. I’m assuming it’s completely opensource as there are no licenses or copyrights mentioned. Thanks again!! I will include a link to this page and acknowledge you in the source.

  2. Hey, thanks for this class. I’m having an issue with it that I can’t figure out how to solve, though. It appears that the first time I call next() on it the displayed card is changed appropriately, but when I then call getCurrentCard() the previously displayed card is returned. From then on, the card returned from getCurrentCard() is one step behind the displayed card. To make it more clear, say I have a layout with 3 cards. When the form is first displayed, card 1 is the current card and is returned from getCurrentCard(). If I then call next(), card 2 is displayed but card 1 is still returned from getCurrentCard(). Calling next() again displays card 3 but card 2 is returned from getCurrentCard(). I’m just wondering if you’ve ever come across this issue.

    • Rob Camick said

      The AncestorListener code is executing after the getCurrentCard() statement is executed, therefore the current card has not yet been updated. This is strange as normally listener code executes sequentially on the EDT. I changed the class to use a HierarchyListener instead and this code does execute in the expected order on the EDT. You will need to download the new version.

      Thanks for the feedback.

  3. terryconsult said

    Hi Rob,

    I am not able to implement the class. In my Frame, hae a JPanel(mainPanel). I set its layout as RXCardLayout (cards). Added different panels to cards using addLayoutComponent. While dispalying the required panel, I call cards.show(mainPanel, panelStr); But unfortunately I don’t see anything – the screen is blank. Why so ? Where am I going wrong ? Can you help me with this. I want to work out with focusing on dispalying cards from cardLayout.

    Thanks

    • Rob Camick said

      I have no idea what you are doing wrong. This class is used the same as the CardLayout class. Read the tutorial on using a Card layout. Download the example and replace the CardLayout with RXCardLayout and it will work. If you still have problems then you ask your question in a forum where you can post your SSCCE showing the problem.

Leave a comment