/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2016 The ZAP Development Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.zaproxy.zap.view; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Rectangle; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.Scrollable; import javax.swing.SwingUtilities; /** * A {@code JPanel} containing two {@code JTree} shown one above the other, used to display the contexts and sites trees in the * same panel. * * @since 2.6.0 */ public class ContextsSitesPanel extends JPanel { private static final long serialVersionUID = -3325400144404304335L; /** * Constructs a {@code ContextsSitesPanel} with the given contexts and sites trees. * * @param contextsTree the contexts tree * @param sitesTree the sites tree * @throws IllegalArgumentException if any of the given parameters is {@code null}. */ public ContextsSitesPanel(JTree contextsTree, JTree sitesTree) { this(contextsTree, sitesTree, null); } /** * Constructs a {@code ContextsSitesPanel} with the given contexts and sites trees and with the given name for the * {@code JScrollPane}. * * @param contextsTree the contexts tree * @param sitesTree the sites tree * @param scrollPaneName the name of the {@code JScrollPane}, might be {@code null} * @throws IllegalArgumentException if any of the trees is {@code null}. */ public ContextsSitesPanel(JTree contextsTree, JTree sitesTree, String scrollPaneName) { super(new BorderLayout()); validateNonNull(contextsTree, "contextsTree"); validateNonNull(sitesTree, "sitesTree"); JScrollPane scrollPane = new JScrollPane(); if (scrollPaneName != null) { scrollPane.setName(scrollPaneName); } JPanel panel = new ScrollableTreesPanel(contextsTree, sitesTree); scrollPane.setViewportView(panel); add(scrollPane); } private static void validateNonNull(Object parameter, String parameterName) { if (parameter == null) { throw new IllegalArgumentException("The " + parameterName + " must not be null."); } } private static class ScrollableTreesPanel extends JPanel implements Scrollable { private static final long serialVersionUID = 2709986817434976954L; private final JTree contextsTree; private final JTree sitesTree; public ScrollableTreesPanel(JTree contextsTree, JTree sitesTree) { super(new BorderLayout()); this.contextsTree = contextsTree; add(contextsTree, BorderLayout.NORTH); this.sitesTree = sitesTree; add(sitesTree, BorderLayout.CENTER); } @Override public Dimension getPreferredScrollableViewportSize() { Dimension dNT = contextsTree.getPreferredScrollableViewportSize(); Dimension dCT = sitesTree.getPreferredScrollableViewportSize(); dCT.setSize(Math.max(dNT.getWidth(), dCT.getWidth()), dNT.getHeight() + dCT.getHeight()); return dCT; } @Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { if (visibleRect.getY() < sitesTree.getBounds().getY()) { return contextsTree.getScrollableUnitIncrement(visibleRect, orientation, direction); } return sitesTree.getScrollableUnitIncrement(visibleRect, orientation, direction); } @Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { // Same behaviour for both trees. return sitesTree.getScrollableBlockIncrement(visibleRect, orientation, direction); } @Override public boolean getScrollableTracksViewportWidth() { int width = Math.max(sitesTree.getPreferredSize().width, contextsTree.getPreferredSize().width); return SwingUtilities.getUnwrappedParent(this).getWidth() > width; } @Override public boolean getScrollableTracksViewportHeight() { return SwingUtilities.getUnwrappedParent(this) .getHeight() > (sitesTree.getPreferredSize().height + contextsTree.getPreferredSize().height); } } }