/**
  * Iterates all child components and calculates the space enough to keep all of them assuming that
  * the width is fixed.
  */
 private Dimension calculateSize(int maxRowWidth) {
   FlowLayout layout = (FlowLayout) getLayout();
   int height = 0;
   int currentRowWidth = 0;
   int currentRowHeight = 0;
   for (int i = 0, count = getComponentCount(); i < count; ++i) {
     Component comp = getComponent(i);
     Dimension bounds = comp.getPreferredSize();
     if (!comp.isVisible()) {
       continue;
     }
     currentRowHeight = Math.max(currentRowHeight, bounds.height);
     if (currentRowWidth + layout.getHgap() + bounds.width <= maxRowWidth) {
       if (bounds.width != 0) {
         currentRowWidth += bounds.width + layout.getHgap();
       }
       continue;
     }
     height += currentRowHeight + layout.getVgap();
     currentRowWidth = bounds.width;
     currentRowHeight = bounds.height;
   }
   return new Dimension(maxRowWidth, height + currentRowHeight + 2 * layout.getVgap());
 }
  /**
   * Displays a modal dialog with one button for each entry in the {@link GraphicGenerator} clipart
   * library. Clicking on a button sets that entry into the {@link ATTR_CLIPART_NAME} parameter.
   */
  private void displayClipartDialog() {
    Window window = SwingUtilities.getWindowAncestor(myPanel);
    final JDialog dialog = new JDialog(window, Dialog.ModalityType.DOCUMENT_MODAL);
    FlowLayout layout = new FlowLayout();
    dialog.getRootPane().setLayout(layout);
    int count = 0;
    for (Iterator<String> iter = GraphicGenerator.getClipartNames(); iter.hasNext(); ) {
      final String name = iter.next();
      try {
        JButton btn = new JButton();

        btn.setIcon(new ImageIcon(GraphicGenerator.getClipartIcon(name)));
        Dimension d = new Dimension(CLIPART_ICON_SIZE, CLIPART_ICON_SIZE);
        btn.setMaximumSize(d);
        btn.setPreferredSize(d);
        btn.addActionListener(
            new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                myTemplateState.put(ATTR_CLIPART_NAME, name);
                dialog.setVisible(false);
                update();
              }
            });
        dialog.getRootPane().add(btn);
        count++;
      } catch (IOException e) {
        LOG.error(e);
      }
    }
    int size =
        (int) (Math.sqrt(count) + 1) * (CLIPART_ICON_SIZE + layout.getHgap())
            + CLIPART_DIALOG_BORDER * 2;
    dialog.setSize(size, size + DIALOG_HEADER);
    dialog.setLocationRelativeTo(window);
    dialog.setVisible(true);
  }