/* * Copyright (c) 2014 tabletoptool.com team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * rptools.com team - initial implementation * tabletoptool.com team - further development */ package com.t3.macro.api.functions.input; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.JPanel; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.Scrollable; /** * Wrapper panel provides alignment and scrolling to a ColumnPanel. * ColumnPanel uses GridBagLayout, which ignores size requests. Thus, the * ColumnPanel is always the size of its container, and is always centered. * We wrap the ColumnPanel in a ScrollingPanel to set the alignment and * desired maximum size. The ScrollingPanel is wrapped in a JScrollPane to * provide scrolling support. */ @SuppressWarnings("serial") public final class ColumnPanelHost extends JScrollPane { ScrollingPanel panel; ColumnPanel columnPanel; ColumnPanelHost(ColumnPanel cp) { // get the width of the vertical scrollbar JScrollBar vscroll = getVerticalScrollBar(); int scrollBarWidth = 20; // default value if we can't find the scrollbar if (vscroll != null) { Dimension d = vscroll.getMaximumSize(); scrollBarWidth = (d == null) ? 20 : d.width; } // Cap the height of the contents at 3/4 of the screen height int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height; panel = new ScrollingPanel(cp, scrollBarWidth, screenHeight * 5 / 8); setViewportView(panel); columnPanel = cp; panel.setLayout(new FlowLayout(FlowLayout.LEFT)); panel.add(columnPanel); // Restores focus to the appropriate input field in the nested ColumnPanel. ComponentAdapter onPanelShow = new ComponentAdapter() { @Override public void componentShown(ComponentEvent ce) { columnPanel.restoreFocus(); } }; setBorder(null); addComponentListener(onPanelShow); } final class ScrollingPanel extends JPanel implements Scrollable { ColumnPanel cp; int scrollBarWidth; int maxHeight; ScrollingPanel(ColumnPanel cp, int scrollBarWidth, int maxHeight) { this.cp = cp; this.scrollBarWidth = scrollBarWidth; this.maxHeight = maxHeight; } // The Scrollable interface methods @Override public Dimension getPreferredScrollableViewportSize() { Dimension d = cp.getPreferredSize(); if (d.height > maxHeight || (d.height > cp.getParent().getHeight() && cp.getParent().getHeight() > 0)) { d.height = maxHeight + cp.maxHeightModifier; d.width += scrollBarWidth; // make room for the vertical scrollbar } return d; } @Override public int getScrollableBlockIncrement(Rectangle visRect, int orientation, int direction) { int retval = visRect.height - 10; if (retval < 0) retval = 10; return retval; } @Override public int getScrollableUnitIncrement(Rectangle visRect, int orientation, int direction) { return scrollBarWidth; } @Override public boolean getScrollableTracksViewportHeight() { return false; } @Override public boolean getScrollableTracksViewportWidth() { return false; } } }