private void refreshGUI() {
    spvp.getScrollPanel().removeAll();

    for (SwimmingObject result : Icy.getMainInterface().getSwimmingPool().getObjects()) {
      JPanel panel = new SwimmingPoolObjectPanel(result);
      ComponentUtil.setFixedHeight(panel, 40);
      spvp.getScrollPanel().add(panel);
    }

    spvp.getScrollPanel().add(Box.createVerticalGlue());

    String text = "No object in swimming pool.";

    int numberOfSwimmingObject = Icy.getMainInterface().getSwimmingPool().getObjects().size();
    if (numberOfSwimmingObject > 0) {
      text = "" + numberOfSwimmingObject + " objects in swimming pool.";
    }

    spvp.getNumberOfSwimmingObjectLabel().setText(text);

    spvp.getScrollPane().invalidate();
    spvp.getScrollPane().repaint();
  }
  /** @param plugin */
  public PluginDetailPanel(PluginDescriptor plugin) {
    super(plugin.getName() + " " + plugin.getVersion(), false, true);

    this.plugin = plugin;

    // changesLogButton = new ChangesLogActionButton();
    executeButton = new ExecuteActionButton();
    closeButton = new CloseActionButton();

    setPreferredSize(new Dimension(640, 480));

    // build top panel
    pluginDescriptionText = new JTextPane();
    pluginDescriptionText.setContentType("text/html");
    pluginDescriptionText.setEditable(false);
    pluginDescriptionText.setOpaque(false);
    pluginDescriptionText.addHyperlinkListener(this);
    ComponentUtil.setFixedHeight(pluginDescriptionText, 256);

    final JScrollPane scDescription = new JScrollPane(pluginDescriptionText);
    scDescription.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));

    pluginImage =
        new ImageComponent(
            plugin.isImageLoaded() ? plugin.getImage() : PluginDescriptor.DEFAULT_IMAGE);

    imagePanel = new JPanel(new BorderLayout());
    imagePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
    imagePanel.add(pluginImage, BorderLayout.CENTER);

    final JPanel topPanel = new JPanel(new BorderLayout());

    topPanel.add(imagePanel, BorderLayout.WEST);
    topPanel.add(scDescription, BorderLayout.CENTER);

    // center panel
    pluginAuthorLabel = new JLabel();
    pluginWebsiteLabel = new JLabel();
    pluginEmailLabel = new JLabel();

    final JPanel infosPanel = new JPanel();
    infosPanel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 8));
    infosPanel.setLayout(new BoxLayout(infosPanel, BoxLayout.PAGE_AXIS));

    infosPanel.add(GuiUtil.createTabBoldLabel("Author", 1));
    infosPanel.add(GuiUtil.createTabLabel(pluginAuthorLabel, 32));
    infosPanel.add(Box.createVerticalStrut(4));
    infosPanel.add(GuiUtil.createTabBoldLabel("Web site", 1));
    infosPanel.add(GuiUtil.createTabLabel(pluginWebsiteLabel, 32));
    infosPanel.add(Box.createVerticalStrut(4));
    infosPanel.add(GuiUtil.createTabBoldLabel("Email", 1));
    infosPanel.add(GuiUtil.createTabLabel(pluginEmailLabel, 32));
    infosPanel.add(Box.createVerticalStrut(4));
    infosPanel.add(Box.createVerticalGlue());

    pluginChangeLogText = new JTextPane();
    pluginChangeLogText.setContentType("text/html");
    pluginChangeLogText.setEditable(false);
    pluginChangeLogText.setOpaque(false);
    pluginChangeLogText.addHyperlinkListener(this);

    final JScrollPane scChangeLog = new JScrollPane(pluginChangeLogText);
    scChangeLog.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));

    final JPanel changeLogPanel = new JPanel(new BorderLayout());
    changeLogPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 4, 4));

    changeLogPanel.add(GuiUtil.createTabBoldLabel("ChangeLog", 1), BorderLayout.NORTH);
    changeLogPanel.add(
        GuiUtil.createLineBoxPanel(Box.createHorizontalStrut(32), scChangeLog),
        BorderLayout.CENTER);

    final JPanel centerPanel = new JPanel(new BorderLayout());

    centerPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH);
    centerPanel.add(infosPanel, BorderLayout.WEST);
    centerPanel.add(changeLogPanel, BorderLayout.CENTER);

    // bottom panel
    final JPanel buttonsPanel = new JPanel();
    buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.LINE_AXIS));
    buttonsPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));

    buttonsPanel.add(executeButton);
    buttonsPanel.add(Box.createHorizontalGlue());
    buttonsPanel.add(Box.createHorizontalStrut(4));
    buttonsPanel.add(closeButton);

    final JPanel bottomPanel = new JPanel(new BorderLayout());

    bottomPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH);
    bottomPanel.add(buttonsPanel, BorderLayout.CENTER);

    setLayout(new BorderLayout());

    add(topPanel, BorderLayout.NORTH);
    add(centerPanel, BorderLayout.CENTER);
    add(bottomPanel, BorderLayout.SOUTH);

    updateGui();

    addToDesktopPane();
    // random position for more fun
    setLocation(10 * Random.nextInt(20) + 40, 10 * Random.nextInt(10) + 40);
    setVisible(true);
    requestFocus();

    // some parts of the descriptor are not loaded --> async update
    if (!plugin.isAllLoaded()) {
      ThreadUtil.bgRun(
          new Runnable() {
            @Override
            public void run() {
              PluginDetailPanel.this.plugin.loadAll();

              // rebuild interface
              ThreadUtil.invokeLater(
                  new Runnable() {
                    @Override
                    public void run() {
                      updateGui();
                    }
                  });
            }
          });
    }
  }