/**
   * Helper method to create the thumbnails background area, with a {@link JScrollPane}.
   *
   * @return the created and configured {@link JScrollPane} component.
   */
  private JScrollPane createThumbNailsBackgroundPanel() {
    thumbNailGridLayout = new GridLayout(0, maxNrOfConflicts);
    thumbNailsPanel = new JPanel(thumbNailGridLayout);

    JScrollBar hSB = new JScrollBar(JScrollBar.HORIZONTAL);
    JScrollBar vSB = new JScrollBar(JScrollBar.VERTICAL);

    hSB.setUnitIncrement(40);
    vSB.setUnitIncrement(40);

    scrollpane =
        new JScrollPane(
            thumbNailsPanel,
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    scrollpane.setHorizontalScrollBar(hSB);
    scrollpane.setVerticalScrollBar(vSB);

    return scrollpane;
  }
Пример #2
0
  private void setUpDisplayPanel() {
    JScrollPane mainScroll;
    JPanel mainPanel = new JPanel(new BorderLayout());
    displayPanel = new JPanel(new BorderLayout());
    hostsHolder = new JPanel();

    hostsHolder.setLayout(new BoxLayout(hostsHolder, BoxLayout.Y_AXIS));
    mainPanel.add(hostsHolder, BorderLayout.NORTH);
    displayPanel.add(mainScroll = new JScrollPane(mainPanel));

    JScrollBar bar = mainScroll.getVerticalScrollBar();
    mainScroll.setBorder(null);
    bar.setBlockIncrement(40);
    bar.setUnitIncrement(40);
  }
Пример #3
0
  private void initLayout() { // {{{
    layout = new javax.swing.GroupLayout(listPanel);

    super.setLayout(blayout);
    layout.setHonorsVisibility(true);
    // layout.setAutoCreateContainerGaps(true);
    layout.setAutoCreateGaps(true);

    ParallelGroup pg = layout.createParallelGroup(Alignment.LEADING);
    SequentialGroup sg = layout.createSequentialGroup();
    pg = pg.addGroup(sg);
    // add components to this one.
    vgroup = layout.createParallelGroup(Alignment.LEADING);
    sg.addGroup(vgroup);
    layout.setHorizontalGroup(pg);

    // Add out components to this one.
    hgroup = layout.createSequentialGroup();
    ParallelGroup pg1 = layout.createParallelGroup(Alignment.LEADING).addGroup(hgroup);
    layout.setVerticalGroup(pg1);
    // Add the listPanel to our layout
    listPanel.setLayout(layout);
    add(userListPane, BorderLayout.CENTER);
    setupToolBar();
    add(toolbar, BorderLayout.NORTH);
    btnNext.setEnabled(false);
    btnPrev.setEnabled(false);

    userListPane.setHorizontalScrollBarPolicy(
        javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    userListPane.setVerticalScrollBarPolicy(
        javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    userListPane.setAutoscrolls(true);
    userListPane.setName("userListPane"); // NOI18N
    userListPane.setViewportView(listPanel);
    javax.swing.JScrollBar bar = userListPane.getVerticalScrollBar();
    bar.setUnitIncrement(50);
    TwitzMainView.fixJScrollPaneBarsSize(userListPane);
  } // }}}
Пример #4
0
  public void paint(Graphics g) {
    super.paint(g);
    if (clusterCount == 0) return;
    boolean ismultigene = !isSingleGene;
    Graphics2D g2 = (Graphics2D) g;
    multigeneCount = 1;
    Cluster cluster = null;
    if (ismultigene) {
      try {
        if (!inAnalysis) {
          int begin = geneClusterCB.getSelectedItem().toString().indexOf(":");
          int end = geneClusterCB.getSelectedItem().toString().indexOf(",");
          sn = geneClusterCB.getSelectedItem().toString().substring(begin + 2, end);
          cluster = framework.getClusterRepository(0).getCluster(Integer.parseInt(sn));
          geneIndices = cluster.getIndices();
        }
      } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Gene Cluster Problem");
        return;
      }
      if (geneIndices == null || geneIndices.length < 1) return;

      if (aggregateGeneCluster) multigeneCount = 1;
      else multigeneCount = geneIndices.length;
    }
    int chartTop = chartTopHeight;

    lowerOutliers = new float[multigeneCount][][];
    upperOutliers = new float[multigeneCount][][];
    expressionSDs = new float[multigeneCount][];
    expressionAverages = new float[multigeneCount][];
    expressionMedian = new float[multigeneCount][];
    expressionQ1 = new float[multigeneCount][];
    expressionQ3 = new float[multigeneCount][];
    expressionIQR = new float[multigeneCount][];
    expressionLowerWhisker = new float[multigeneCount][];
    expressionUpperWhisker = new float[multigeneCount][];
    chartTitles = new String[multigeneCount];
    int maxString = 0;
    for (int i = 0; i < clusterNames.length; i++) {
      maxString = Math.max(maxString, g.getFontMetrics().stringWidth(clusterNames[i]));
    }
    chartGap = maxString + 50;

    // for only drawing the visible area- dramatic speed improvements
    Rectangle bounds = g.getClipBounds();
    int indexBegin = (int) Math.max(-3 + bounds.y / (chartHeight + chartGap), 0f);
    int indexEnd =
        (int) Math.min(multigeneCount, 3 + (bounds.y + bounds.height) / (chartHeight + chartGap));

    for (int multigeneIndex = indexBegin; multigeneIndex < indexEnd; multigeneIndex++) {
      if (ismultigene) {
        if (aggregateGeneCluster) {
          getChartData(geneIndices, multigeneIndex);
          if (inAnalysis) chartTitles[multigeneIndex] = geneClusterLabel;
          else chartTitles[multigeneIndex] = cluster.getClusterLabel();
        } else {
          getChartData(geneIndices[multigeneIndex], multigeneIndex);
          chartTitles[multigeneIndex] =
              framework.getData()
                  .getElementAnnotation(
                      geneIndices[multigeneIndex], framework.getData().getFieldNames()[0])[0];
        }
      } else {
        getChartData(geneCB.getSelectedIndex(), multigeneIndex);
        chartTitles[multigeneIndex] = geneCB.getSelectedItem().toString();
      }
      float maxHeight = 0;
      float minHeight = Float.POSITIVE_INFINITY;
      for (int i = 0; i < clusterCount; i++) {
        if (this.isBoxPlot) {
          for (int j = 0; j < this.upperOutliers[multigeneIndex][i].length; j++) {
            maxHeight = Math.max(upperOutliers[multigeneIndex][i][j], maxHeight);
          }
          maxHeight = Math.max(expressionUpperWhisker[multigeneIndex][i], maxHeight);
        } else {
          maxHeight =
              Math.max(
                  expressionAverages[multigeneIndex][i] + this.expressionSDs[multigeneIndex][i],
                  maxHeight);
        }
      }

      for (int i = 0; i < clusterCount; i++) {
        if (this.isBoxPlot) {
          for (int j = 0; j < this.lowerOutliers[multigeneIndex][i].length; j++) {
            minHeight = Math.min(lowerOutliers[multigeneIndex][i][j], minHeight);
          }
          minHeight = Math.min(expressionLowerWhisker[multigeneIndex][i], minHeight);
        } else minHeight = 0f; // Math.min(expressionAverages[i], minHeight);
      }
      maxHeight++;
      float topgridline;
      float bottomgridline;
      if (this.autoScale) {
        topgridline = (int) maxHeight + (int) maxHeight % 2;
        bottomgridline = (int) minHeight - (int) minHeight % 2 - 2;
        if (!isBoxPlot) bottomgridline = 0f;
        fixedTop = topgridline;
        fixedBottom = bottomgridline;
      } else {
        topgridline = fixedTop;
        bottomgridline = fixedBottom;
        if (!isBoxPlot) bottomgridline = 0f;
      }

      float gridrange = topgridline - bottomgridline;
      // draw everything
      // grid
      g2.setColor(Color.black);
      g2.drawLine(
          chartleft - 5,
          chartHeight + chartTop,
          chartleft + clusterCount * chartIncrement,
          chartHeight + chartTop); // horizontal line bottom
      g2.drawLine(chartleft, chartTop, chartleft, chartHeight + chartTop + 5); // vertical line left
      g2.setColor(Color.gray);
      g2.drawLine(chartleft - 7, chartTop, chartleft, chartTop); // horizontal line ticktop
      g2.drawLine(
          chartleft - 5,
          chartTop + chartHeight / 4,
          chartleft,
          chartTop + chartHeight / 4); // horizontal line tick75%
      g2.drawLine(
          chartleft - 7,
          chartTop + chartHeight / 2,
          chartleft,
          chartTop + chartHeight / 2); // horizontal line tickMid
      g2.drawLine(
          chartleft - 5,
          chartTop + 3 * chartHeight / 4,
          chartleft,
          chartTop + 3 * chartHeight / 4); // horizontal line tick25%
      if (showGridlines) {
        g2.setColor(Color.gray);
        g2.drawLine(
            chartleft,
            chartTop,
            chartleft + chartIncrement * clusterCount,
            chartTop); // horizontal line grid
        g2.drawLine(
            chartleft,
            chartTop + chartHeight / 4,
            chartleft + chartIncrement * clusterCount,
            chartTop + chartHeight / 4); // horizontal line grid
        g2.drawLine(
            chartleft,
            chartTop + chartHeight / 2,
            chartleft + chartIncrement * clusterCount,
            chartTop + chartHeight / 2); // horizontal line grid
        g2.drawLine(
            chartleft,
            chartTop + 3 * chartHeight / 4,
            chartleft + chartIncrement * clusterCount,
            chartTop + 3 * chartHeight / 4); // horizontal line grid
      }

      g2.setColor(Color.black);
      g2.drawString(
          Float.toString(bottomgridline + gridrange),
          chartleft - 40,
          chartTop + 3); // vertical axis label
      g2.drawString(
          Float.toString(bottomgridline + gridrange * 3f / 4f),
          chartleft - 40,
          (chartTop + 3) + chartHeight / 4); // vertical axis label
      g2.drawString(
          Float.toString(bottomgridline + gridrange / 2f),
          chartleft - 40,
          (chartTop + 3) + chartHeight / 2); // vertical axis label
      g2.drawString(
          Float.toString(bottomgridline + gridrange / 4f),
          chartleft - 40,
          (chartTop + 3) + (3 * chartHeight / 4)); // vertical axis label	
      g2.drawString(
          Float.toString(bottomgridline),
          chartleft - 40,
          (chartTop + 3) + (chartHeight)); // vertical axis label	

      Font font = g2.getFont();
      g2.setFont(new Font("Helvetica", Font.BOLD, 16));
      g2.drawString(
          chartTitles[multigeneIndex],
          chartleft + chartIncrement / 2,
          chartTop - 15); // Gene/group Name label
      g2.setFont(font);

      g2.rotate(-Math.PI / 2);
      g2.drawString(
          "Expression", -((chartTop + 3) + 2 * chartHeight / 3), (chartleft - 60)); // y-axis Label
      g2.rotate(Math.PI / 2);

      for (int i = 0; i < this.clusterCount; i++) {
        int xorigin = (int) ((.25f + (float) i) * chartIncrement) + chartleft;
        int yorigin = chartHeight + chartTop;
        int barWidth = chartIncrement / 2;

        int barHeight =
            (int) ((expressionAverages[multigeneIndex][i]) * ((float) chartHeight) / gridrange);
        int errorBarHeight =
            (int) (expressionSDs[multigeneIndex][i] * ((float) chartHeight) / gridrange);

        int boxBottom =
            (int)
                ((-bottomgridline + expressionQ1[multigeneIndex][i])
                    * ((float) chartHeight)
                    / gridrange);
        int boxTop =
            (int)
                ((-bottomgridline + expressionQ3[multigeneIndex][i])
                    * ((float) chartHeight)
                    / gridrange);
        int boxMedian =
            (int)
                ((-bottomgridline + expressionMedian[multigeneIndex][i])
                    * ((float) chartHeight)
                    / gridrange);
        int boxLowerWhisker =
            (int)
                ((-bottomgridline + expressionLowerWhisker[multigeneIndex][i])
                    * ((float) chartHeight)
                    / gridrange);
        int boxUpperWhisker =
            (int)
                ((-bottomgridline + expressionUpperWhisker[multigeneIndex][i])
                    * ((float) chartHeight)
                    / gridrange);

        g2.setColor(Color.gray);
        g2.drawLine(
            xorigin + 3 * barWidth / 2,
            yorigin,
            xorigin + 3 * barWidth / 2,
            yorigin + 5); // vertical tickmark
        g2.setColor(Color.black);
        g2.rotate(-Math.PI / 2);
        g2.drawString(
            clusterNames[i],
            -(yorigin + 5) - g.getFontMetrics().stringWidth(clusterNames[i]),
            (xorigin + barWidth / 2)); // cluster names
        g2.rotate(Math.PI / 2);

        if (!isBoxPlot) { // bar graph
          g2.setColor(clusterColors[i]);
          g2.fillRect(xorigin, yorigin - barHeight, barWidth, barHeight); // box
          g2.setColor(Color.black);
          g2.drawRect(xorigin, yorigin - barHeight, barWidth, barHeight); // box outline
          g2.drawLine(
              xorigin + barWidth / 2,
              yorigin - barHeight - errorBarHeight,
              xorigin + barWidth / 2,
              yorigin - barHeight); // vertical errorbar
          g2.drawLine(
              xorigin + barWidth / 4,
              yorigin - barHeight - errorBarHeight,
              xorigin + 3 * barWidth / 4,
              yorigin - barHeight - errorBarHeight); // horizontal error bar

        } else if (isBoxPlot) { // box plot
          g2.setColor(clusterColors[i]);
          g2.fillRect(xorigin, yorigin - boxTop, barWidth, boxTop - boxBottom); // box
          g2.setColor(Color.black);
          g2.drawRect(xorigin, yorigin - boxTop, barWidth, boxTop - boxBottom); // box	outline
          g2.drawLine(
              xorigin, yorigin - boxMedian, xorigin + barWidth, yorigin - boxMedian); // median line
          g2.drawLine(
              xorigin + barWidth / 2,
              yorigin - boxTop,
              xorigin + barWidth / 2,
              yorigin - boxUpperWhisker); // vertical whisker upper
          g2.drawLine(
              xorigin + barWidth / 2,
              yorigin - boxBottom,
              xorigin + barWidth / 2,
              yorigin - boxLowerWhisker); // vertical whisker lower
          g2.drawLine(
              xorigin + barWidth / 4,
              yorigin - boxUpperWhisker,
              xorigin + 3 * barWidth / 4,
              yorigin - boxUpperWhisker); // horizontal whisker upper
          g2.drawLine(
              xorigin + barWidth / 4,
              yorigin - boxLowerWhisker,
              xorigin + 3 * barWidth / 4,
              yorigin - boxLowerWhisker); // horizontal whisker lower

          // draw outliers
          int circleWidth = 6;
          for (int j = 0; j < upperOutliers[multigeneIndex][i].length; j++) {
            g2.drawOval(
                xorigin + barWidth / 2 - circleWidth / 2,
                yorigin
                    - (int)
                        ((float) ((-bottomgridline + upperOutliers[multigeneIndex][i][j]))
                            * ((float) chartHeight)
                            / gridrange)
                    - circleWidth / 2,
                circleWidth,
                circleWidth);
          }
          for (int j = 0; j < lowerOutliers[multigeneIndex][i].length; j++) {
            g2.drawOval(
                xorigin + barWidth / 2 - circleWidth / 2,
                yorigin
                    - (int)
                        ((float) ((-bottomgridline + lowerOutliers[multigeneIndex][i][j]))
                            * ((float) chartHeight)
                            / gridrange)
                    - circleWidth / 2,
                circleWidth,
                circleWidth);
          }

        } else {
          System.out.println("unknown chart type");
        }
      }

      chartTop =
          chartTopHeight
              + (multigeneIndex + 1) * (chartHeight + chartGap); // moves top down for next graph
    }
    jScrollBar.setUnitIncrement(chartHeight + chartGap);
    int viewerHeight = chartTopHeight + (multigeneCount) * (chartHeight + chartGap);
    this.setSize(new Dimension(this.getWidth(), viewerHeight));
    this.setPreferredSize(new Dimension(this.getWidth(), viewerHeight));
  }
Пример #5
0
 public void setScrollBar(JScrollBar jsb) {
   this.jScrollBar = jsb;
   jScrollBar.setUnitIncrement(chartHeight + chartGap);
 }
Пример #6
0
  public ModelChartImpl() {
    super();
    this.model = new GCModel(true);
    this.chart = new Chart();
    this.chart.setPreferredSize(new Dimension(0, 0));
    setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);

    // set scrolling speed
    horizontalScrollBar = getHorizontalScrollBar();
    horizontalScrollBar.setUnitIncrement(50);
    horizontalScrollBar.setBlockIncrement(500);

    // order of the renderers determines what is painted first and last
    // we start with what's painted last
    GridBagConstraints gridBagConstraints = new GridBagConstraints();
    gridBagConstraints.fill = GridBagConstraints.BOTH;
    gridBagConstraints.weightx = 2;
    gridBagConstraints.weighty = 2;
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 1;

    initialMarkLevelRenderer = new InitialMarkLevelRenderer(this);
    chart.add(initialMarkLevelRenderer, gridBagConstraints);
    usedHeapRenderer = new UsedHeapRenderer(this);
    chart.add(usedHeapRenderer, gridBagConstraints);
    gcTimesRenderer = new GCTimesRenderer(this);
    chart.add(gcTimesRenderer, gridBagConstraints);
    fullGCLineRenderer = new FullGCLineRenderer(this);
    chart.add(fullGCLineRenderer, gridBagConstraints);
    gcRectanglesRenderer = new GCRectanglesRenderer(this);
    chart.add(gcRectanglesRenderer, gridBagConstraints);
    incLineRenderer = new IncLineRenderer(this);
    chart.add(incLineRenderer, gridBagConstraints);
    concurrentGcLineRenderer = new ConcurrentGcBegionEndRenderer(this);
    chart.add(concurrentGcLineRenderer, gridBagConstraints);
    totalTenuredRenderer = new TotalTenuredRenderer(this);
    chart.add(totalTenuredRenderer, gridBagConstraints);
    totalYoungRenderer = new TotalYoungRenderer(this);
    chart.add(totalYoungRenderer, gridBagConstraints);
    totalHeapRenderer = new TotalHeapRenderer(this);
    chart.add(totalHeapRenderer, gridBagConstraints);

    setViewportView(chart);
    // This would make scrolling slower, but eliminates flickering...
    // getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);

    JPanel rowHeaderPanel = new JPanel();
    GridBagLayout layout = new GridBagLayout();
    rowHeaderPanel.setLayout(layout);
    GridBagConstraints constraints = new GridBagConstraints();
    constraints.fill = GridBagConstraints.VERTICAL;
    constraints.weightx = 2;
    constraints.weighty = 1;
    constraints.gridheight = 2;
    constraints.gridx = 0;
    constraints.gridy = 1;
    this.memoryRuler = new Ruler(true, 0, model.getFootprint(), "K");
    this.pauseRuler = new Ruler(true, 0, model.getPause().getMax(), "s");
    layout.setConstraints(memoryRuler, constraints);
    rowHeaderPanel.add(memoryRuler);
    constraints.gridx = 1;
    layout.setConstraints(pauseRuler, constraints);
    rowHeaderPanel.add(pauseRuler);
    setRowHeaderView(rowHeaderPanel);
    setCorner(JScrollPane.UPPER_LEFT_CORNER, new JPanel());
    setCorner(JScrollPane.LOWER_LEFT_CORNER, new JPanel());

    DateFormat dateFormatter = new TimeFormat();
    this.timestampRuler = new Ruler(false, 0, model.getRunningTime(), "", dateFormatter);
    setColumnHeaderView(timestampRuler);

    getViewport()
        .addComponentListener(
            new ComponentListener() {
              public void componentResized(ComponentEvent e) {
                chart.setSize(chart.getPreferredSize());
                memoryRuler.setSize(
                    (int) memoryRuler.getPreferredSize().getWidth(), e.getComponent().getHeight());
                pauseRuler.setSize(
                    (int) pauseRuler.getPreferredSize().getWidth(), e.getComponent().getHeight());
                timestampRuler.setSize(
                    (int) chart.getPreferredSize().getWidth(),
                    (int) timestampRuler.getPreferredSize().getHeight());
              }

              public void componentMoved(ComponentEvent e) {}

              public void componentShown(ComponentEvent e) {}

              public void componentHidden(ComponentEvent e) {}
            });
    // timestamp menu
    final JPopupMenu popupMenu = new JPopupMenu();
    timeOffsetPanel = new TimeOffsetPanel(popupMenu);
    popupMenu.add(timeOffsetPanel);
    final JPopupMenu timestampRulerPopup = popupMenu;
    Action setOffsetAction =
        new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            if (timeOffsetPanel.isOffsetSet())
              timestampRuler.setOffset(timeOffsetPanel.getDate().getTime() / 1000);
            else timestampRuler.setOffset(0);
            timestampRuler.revalidate();
            timestampRuler.repaint();
          }
        };
    timeOffsetPanel.setOkAction(setOffsetAction);
    this.timestampRuler.addMouseListener(
        new MouseAdapter() {
          public void mousePressed(MouseEvent e) {
            maybePopup(e);
          }

          public void mouseReleased(MouseEvent e) {
            maybePopup(e);
          }

          public void maybePopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
              if (timestampRuler.getOffset() != 0) {
                timeOffsetPanel.setDate(new Date((long) timestampRuler.getOffset() * 1000));
                timeOffsetPanel.setOffsetSet(true);
              } else {
                long suggestedStartDate = model.getLastModified();
                if (model.hasDateStamp()) {
                  suggestedStartDate = (long) (model.getFirstDateStamp().getTime());
                } else if (model.hasCorrectTimestamp()) {
                  suggestedStartDate -= (long) (model.getRunningTime() * 1000.0d);
                }
                timeOffsetPanel.setDate(new Date(suggestedStartDate));
                timeOffsetPanel.setOffsetSet(false);
              }
              timestampRulerPopup.show(e.getComponent(), e.getX(), e.getY());
              timeOffsetPanel.requestFocus();
            }
          }
        });
  }
Пример #7
0
  HtmlPanel(final Map<String, Action> actions, HtmlPage page) throws IOException {
    super(new BorderLayout());

    this.actions = actions;
    textPane = new JTextPane();
    find = new JTextField();
    matches = new JLabel();
    this.page = null;

    final Dimension d = matches.getPreferredSize();
    matches.setPreferredSize(new Dimension(100, d.height));

    textPane.setEditable(false);
    textPane.setFocusable(false);
    textPane.addHyperlinkListener(
        new HyperlinkListener() {

          public final void hyperlinkUpdate(HyperlinkEvent ev) {
            if (ev.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
              final JEditorPane pane = (JEditorPane) ev.getSource();
              if (ev instanceof HTMLFrameHyperlinkEvent) {
                final HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) ev;
                final HTMLDocument doc = (HTMLDocument) pane.getDocument();
                doc.processHTMLFrameHyperlinkEvent(evt);
              } else if (Desktop.isDesktopSupported())
                try {
                  Desktop.getDesktop().browse(ev.getURL().toURI());
                } catch (final Exception e) {
                  e.printStackTrace();
                }
            }
          }
        });

    final HTMLEditorKit kit =
        new HTMLEditorKit() {
          private static final long serialVersionUID = 1L;

          @Override
          public final Document createDefaultDocument() {
            final HTMLDocument doc = (HTMLDocument) super.createDefaultDocument();
            // Load synchronously.
            doc.setAsynchronousLoadPriority(-1);
            return doc;
          }
        };

    final StyleSheet styleSheet = kit.getStyleSheet();
    final InputStream is = getClass().getResourceAsStream("/doogal.css");
    try {
      styleSheet.loadRules(newBufferedReader(is), null);
    } finally {
      is.close();
    }

    textPane.setEditorKit(kit);

    final Document doc = kit.createDefaultDocument();
    textPane.setDocument(doc);
    textPane.addMouseListener(
        new MouseAdapter() {

          private final void showPopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
              final JPopupMenu menu = newPopupMenu(TableType.DOCUMENT, actions);
              if (null != menu) menu.show(e.getComponent(), e.getX(), e.getY());
            }
          }

          @Override
          public final void mousePressed(MouseEvent e) {
            showPopup(e);
          }

          @Override
          public final void mouseReleased(MouseEvent e) {
            showPopup(e);
          }
        });
    find.setColumns(16);
    find.setFont(new Font("Dialog", Font.PLAIN, TINY_FONT));
    find.setMargin(new Insets(2, 2, 2, 2));
    find.addActionListener(
        new ActionListener() {
          public final void actionPerformed(ActionEvent ev) {
            find(find.getText());
          }
        });

    final JLabel label = new JLabel("Quick Find: ");
    label.setLabelFor(find);

    final JButton clear = new JButton("Clear");
    clear.setMargin(new Insets(1, 5, 0, 5));
    clear.setFont(new Font("Dialog", Font.PLAIN, TINY_FONT));
    clear.addActionListener(
        new ActionListener() {
          public final void actionPerformed(ActionEvent e) {
            find.setText("");
            find("");
          }
        });

    final JPanel findPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    findPanel.add(label);
    findPanel.add(find);
    findPanel.add(clear);
    findPanel.add(matches);

    scrollPane =
        new JScrollPane(
            textPane,
            ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.setFocusable(false);
    final JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
    scrollBar.setBlockIncrement(scrollBar.getBlockIncrement() * 20);
    scrollBar.setUnitIncrement(scrollBar.getUnitIncrement() * 20);

    add(scrollPane, BorderLayout.CENTER);
    add(findPanel, BorderLayout.SOUTH);

    setPage(page);
  }
  public CopiesPanel(final Project project) {
    myProject = project;
    myConnection = myProject.getMessageBus().connect(myProject);
    myVcs = SvnVcs.getInstance(myProject);
    myCurrentInfoList = null;

    final Runnable focus =
        new Runnable() {
          @Override
          public void run() {
            IdeFocusManager.getInstance(myProject).requestFocus(myRefreshLabel, true);
          }
        };
    final Runnable refreshView =
        new Runnable() {
          @Override
          public void run() {
            final List<WCInfo> infoList = myVcs.getWcInfosWithErrors();
            final boolean hasErrors = !myVcs.getSvnFileUrlMapping().getErrorRoots().isEmpty();
            final List<WorkingCopyFormat> supportedFormats = getSupportedFormats();
            Runnable runnable =
                new Runnable() {
                  @Override
                  public void run() {
                    if (myCurrentInfoList != null) {
                      final List<OverrideEqualsWrapper<WCInfo>> newList =
                          ObjectsConvertor.convert(
                              infoList,
                              new Convertor<WCInfo, OverrideEqualsWrapper<WCInfo>>() {
                                @Override
                                public OverrideEqualsWrapper<WCInfo> convert(WCInfo o) {
                                  return new OverrideEqualsWrapper<WCInfo>(
                                      InfoEqualityPolicy.getInstance(), o);
                                }
                              },
                              ObjectsConvertor.NOT_NULL);

                      if (Comparing.haveEqualElements(newList, myCurrentInfoList)) {
                        myRefreshLabel.setEnabled(true);
                        return;
                      }
                      myCurrentInfoList = newList;
                    }
                    Collections.sort(infoList, WCComparator.getInstance());
                    updateList(infoList, supportedFormats);
                    myRefreshLabel.setEnabled(true);
                    showErrorNotification(hasErrors);
                    SwingUtilities.invokeLater(focus);
                  }
                };
            ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL);
          }
        };
    final Consumer<Boolean> refreshOnPooled =
        new Consumer<Boolean>() {
          @Override
          public void consume(Boolean somethingNew) {
            if (Boolean.TRUE.equals(somethingNew)) {
              if (ApplicationManager.getApplication().isUnitTestMode()) {
                refreshView.run();
              } else {
                ApplicationManager.getApplication().executeOnPooledThread(refreshView);
              }
            } else {
              ApplicationManager.getApplication()
                  .invokeLater(
                      new Runnable() {
                        @Override
                        public void run() {
                          myRefreshLabel.setEnabled(true);
                        }
                      },
                      ModalityState.NON_MODAL);
            }
          }
        };
    myConnection.subscribe(SvnVcs.ROOTS_RELOADED, refreshOnPooled);

    final JPanel holderPanel = new JPanel(new BorderLayout());
    FontMetrics fm = holderPanel.getFontMetrics(holderPanel.getFont());
    myTextHeight = (int) (fm.getHeight() * 1.3);
    myPanel = new JPanel(new GridBagLayout());
    final JPanel panel = new JPanel(new BorderLayout());
    panel.add(myPanel, BorderLayout.NORTH);
    holderPanel.add(panel, BorderLayout.WEST);
    myRefreshLabel =
        new MyLinkLabel(
            myTextHeight,
            "Refresh",
            new LinkListener() {
              @Override
              public void linkSelected(LinkLabel aSource, Object aLinkData) {
                if (myRefreshLabel.isEnabled()) {
                  myVcs.invokeRefreshSvnRoots();
                  myRefreshLabel.setEnabled(false);
                }
              }
            });
    final JScrollPane pane = ScrollPaneFactory.createScrollPane(holderPanel);
    myHolder = pane;
    final JScrollBar vBar = pane.getVerticalScrollBar();
    vBar.setBlockIncrement(vBar.getBlockIncrement() * 5);
    vBar.setUnitIncrement(vBar.getUnitIncrement() * 5);
    myHolder.setBorder(null);
    setFocusableForLinks(myRefreshLabel);
    refreshOnPooled.consume(true);
    initView();
  }