11

I want a JPanel that can be Collapsed or Expanded when user clicks on a text/icon on its border. I need this type of panel due to space crunch in my application.

I read about CollapsiblePanel class but not sure how to use it.. I think SwingX is needed to be downloaded but did not find that anywhere.

Moreover, it would be better if I get the solution to this in basic Java Swing.

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Nayan Soni
  • 1,001
  • 3
  • 12
  • 22
  • 3
    *"I need this type of panel due to space crunch in my application."* There are other ways to place many controls in one GUI. `JTabbedPane`, `JSplitPane`, `CardLayout`, `JDesktopPane`/`JInternalFrame` .. Alternately it might make more sense to pop the extra controls in a (possibly modal) `JDialog`, or a `JOptionPane`. – Andrew Thompson Nov 18 '11 at 05:04
  • 2
    @AndrewThompson - we are on Swing, so sure there's multitude of possibilites, but: JXCollapsible/JXTaskPane is sooo cute :-) – kleopatra Nov 18 '11 at 10:22
  • @kleopatra I was waiting for you to pop by and address the OP's *actual* question. Just thought I'd make them aware that there are a plethora of possibilities. :) – Andrew Thompson Nov 18 '11 at 10:34
  • Thanks Andrew for your input. I got what I was looking for from SwingX. However, the mystery for performing similar stuff using only Swing is still not answered. Will come back to this if required.. Thanks guys !! – Nayan Soni Nov 20 '11 at 16:54

3 Answers3

11

not sure where you looked, but it's not that difficult to find - even given the infrastructure mess we are in ;-)

Go to the project home of SwingX, then follow the link in the first paragraph to the (barebone) download section, down to releases\1.6.2. Nothing special to the collapsibles themselves, just containers to put components into.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • Concur. Currently rewriting most of our GUI with SwingX components. Saves about half the code for adaptation of standard Swing components. – Mike Adler Nov 18 '11 at 11:46
  • Thanks kleopatra.. I got SwingX library... imported and am using now. Loved JXTaskPane and JXCollapsible :) Did not yet explored in depth of both the panes tough.. What I was looking for is something similar to both "JXTaskPane" and "JXCollapsible". However, liked **JXTaskpane** more than **JXCollapsiblePane** as collapsible pane requires an **external trigger** to expand and collapse. Correct me if I am wrong. – Nayan Soni Nov 20 '11 at 16:48
1

I think you can use a JSplitPane to tackle your problem. Utilizing the property to set the position of divider judiciously, you can achieve what you want.

COD3BOY
  • 11,964
  • 1
  • 38
  • 56
0

So here comes a little class purely in Swing :) This implementation assumes the title to be top left...

import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class JCollapsiblePanel extends JPanel {
  private TitledBorder border;
  private Dimension visibleSize;
  private boolean collapsible;

  public JCollapsiblePanel(String title, Color titleCol) {
    super();

    collapsible = true;

    border = new TitledBorder(title);
    border.setTitleColor(titleCol);
    border.setBorder(new LineBorder(Color.white));
    setBorder(border);

    // as Titleborder has no access to the Label we fake the size data ;)
    final JLabel l = new JLabel(title);
    Dimension size = l.getPreferredSize();

    addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        if (!collapsible) {
          return;
        }

        Insets i = getBorder().getBorderInsets(JCollapsiblePanel.this);
        if (e.getX() < i.left + size.width && e.getY() < i.bottom + size.height) {
          if (visibleSize == null || getHeight() > size.height) {
            visibleSize = getSize();
          }
          if (getSize().height < visibleSize.height) {
            setMaximumSize(new Dimension(visibleSize.width, 20000));
            setMinimumSize(visibleSize);
          } else {
            setMaximumSize(new Dimension(visibleSize.width, size.height));
          }
          revalidate();
          e.consume();
        }
      }
    });
  }

  public void setCollapsible(boolean collapsible) {
    this.collapsible = collapsible;
  }

  public void setTitle(String title) {
    border.setTitle(title);
  }
}
  • I was trying to test, but you don't submit an example. Please put code, how your solution works. –  Jul 04 '19 at 03:21