Question

I've got a new requirement to change my display.

Currently I have a row of 3 radio buttons sitting above a Panel with a card layout. The buttons CONTROL which card of the Card Layout Panel is displayed. But this, it seems, wastes valuable screen real estate.

The row of buttons can easily be transformed to a column of buttons using a GridLayout(4,1) on the panel that owns them and their title label. This panel could then theoretically be placed in the upper left corner of the each of the cards displayed in the card layout panel, and the top row of each card could be moved up to the right of the button panel, allowing more space for what has to come below.

But what shall be the containment model for this? In this variant, the button panel must appear on each card. Who owns it? Logically it needs to be owned by the parent panel on which all this sits, but it won't display on the cards, which will cover it over - unless I could

  1. add the button panel to each card at the moment of its display, which would probably be messy and maybe cause flicker.
  2. make the top left corner of each card be transparent, allowing it to show the upper left button panel owned by its parent. But how would I do that?

Other solutions?

Maybe

  1. Have two card layout panels controlled by the radio buttons. The upper right one that contains all but the the button panel and the lower component that sits below both.
Was it helpful?

Solution

It sounds like you could use a JLayeredPane as the parent component of both, the panel containing the radio buttons and the card panel.

JLayeredPane allows its child components to overlap, each child belonging to a layer.

To specify the layer, you can pass an Integer constant into the JLayeredPane's add(Component, Object) method as the constraint argument. The integer constants are defined in the JLayeredPane class itself. You can use JLayeredPane.DEFAULT_LAYER for the card panel and JLayeredPane.PALETTE_LAYER for the radio button panel.

Having set the layer, you'll still have to position the two panels correctly in x,y space. I would recommend just overriding the JLayeredPane's doLayout() method with something like this (haven't tested):

public void doLayout()
{
    cardPanel.setBounds( new Rectangle( getSize() ));
    radioButtonPanel.setBounds( new Rectangle( radtioButtonPanel.getPreferredSize() ));
}

OTHER TIPS

You may be able to use OverlayLayout to display the control panel in the top-left of your card panel.

image

I would forget the transparency idea. Just put the options as a list to the left of (or right of, or over/under) the card panel. I would definitely NOT put the panel of controls on the CardPanel itself. It should be outside.

The list of selections could be radios, buttons, or in this example, a JList of items that can grow w/o messing up the layout. For example:

/*
 * CardLayoutDemo.java
 */
import java.awt.*;

import javax.swing.*;
import javax.swing.event.*;

@SuppressWarnings("unchecked")
public class CardLayoutDemo implements Runnable
{
  final static String CARD1 = "Gray Panel";
  final static String CARD2 = "Blue Panel";
  final static String CARD3 = "Green Panel";

  JPanel cards;
  CardLayout cl;

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new CardLayoutDemo());
  }

  public void run()
  {
    final JList jList = new JList(new String[]{CARD1, CARD2, CARD3});
    jList.setPrototypeCellValue("XXXXXXXXXXXX");
    jList.setVisibleRowCount(5);
    jList.setSelectedIndex(0);
    jList.addListSelectionListener(new ListSelectionListener()
    {
      @Override
      public void valueChanged(ListSelectionEvent e)
      {
        String name = jList.getSelectedValue().toString();
        cl.show(cards, name);
      }
    });

    JScrollPane scroll = new JScrollPane(jList);
    scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    Dimension dim = new Dimension(300, 300);

    JPanel card1 = new JPanel();
    card1.setBackground(Color.GRAY);
    card1.setPreferredSize(dim);

    JPanel card2 = new JPanel();
    card2.setBackground(Color.BLUE);
    card2.setPreferredSize(dim);

    JPanel card3 = new JPanel();
    card3.setBackground(Color.GREEN);
    card3.setPreferredSize(dim);

    cl = new CardLayout();
    cards = new JPanel(cl);
    cards.add(card1, CARD1);
    cards.add(card2, CARD2);
    cards.add(card3, CARD3);

    JFrame f = new JFrame("CardLayout Demo");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(scroll, BorderLayout.WEST);
    f.add(cards, BorderLayout.CENTER);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

If you wanted a label for the selections, just make a "selection panel" that contains the JLabel and the JScrollPane (or use your grid of buttons panel), and put it in Borderlayout.WEST (instead of the adding the JScrollPane directly).

Also, look into JTabbedPane as an alternative.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top