All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.swt.custom.ScrolledComposite Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.custom;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * A ScrolledComposite provides scrollbars and will scroll its content when the user
 * uses the scrollbars.
 *
 *
 * 

There are two ways to use the ScrolledComposite: * *

*
    *
  1. Set the size of the control that is being scrolled and the ScrolledComposite * will show scrollbars when the contained control can not be fully seen.
  2. * *
  3. The second way imitates the way a browser would work. Set the minimum size of * the control and the ScrolledComposite will show scroll bars if the visible area is * less than the minimum size of the control and it will expand the size of the control * if the visible area is greater than the minimum size. This requires invoking * both setMinWidth(), setMinHeight() and setExpandHorizontal(), setExpandVertical().
  4. *
* *

 * public static void main (String [] args) {
 *      Display display = new Display ();
 *      Color red = display.getSystemColor(SWT.COLOR_RED);
 *      Color blue = display.getSystemColor(SWT.COLOR_BLUE);
 *      Shell shell = new Shell (display);
 *      shell.setLayout(new FillLayout());
 *
 *      // set the size of the scrolled content - method 1
 *      final ScrolledComposite sc1 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
 *      final Composite c1 = new Composite(sc1, SWT.NONE);
 *      sc1.setContent(c1);
 *      c1.setBackground(red);
 *      GridLayout layout = new GridLayout();
 *      layout.numColumns = 4;
 *      c1.setLayout(layout);
 *      Button b1 = new Button (c1, SWT.PUSH);
 *      b1.setText("first button");
 *      c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *
 *      // set the minimum width and height of the scrolled content - method 2
 *      final ScrolledComposite sc2 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
 *      sc2.setExpandHorizontal(true);
 *      sc2.setExpandVertical(true);
 *      final Composite c2 = new Composite(sc2, SWT.NONE);
 *      sc2.setContent(c2);
 *      c2.setBackground(blue);
 *      layout = new GridLayout();
 *      layout.numColumns = 4;
 *      c2.setLayout(layout);
 *      Button b2 = new Button (c2, SWT.PUSH);
 *      b2.setText("first button");
 *      sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *
 *      Button add = new Button (shell, SWT.PUSH);
 *      add.setText("add children");
 *      final int[] index = new int[]{0};
 *      add.addListener(SWT.Selection, new Listener() {
 *          public void handleEvent(Event e) {
 *              index[0]++;
 *              Button button = new Button(c1, SWT.PUSH);
 *              button.setText("button "+index[0]);
 *              // reset size of content so children can be seen - method 1
 *              c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *              c1.layout();
 *
 *              button = new Button(c2, SWT.PUSH);
 *              button.setText("button "+index[0]);
 *              // reset the minimum width and height so children can be seen - method 2
 *              sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 *              c2.layout();
 *          }
 *      });
 *
 *      shell.open ();
 *      while (!shell.isDisposed ()) {
 *          if (!display.readAndDispatch ()) display.sleep ();
 *      }
 *      display.dispose ();
 * }
 * 
* *
*
Styles:
H_SCROLL, V_SCROLL *
* * @see ScrolledComposite snippets * @see Sample code and further information */ public class ScrolledComposite extends Composite { Control content; Listener contentListener; Listener filter; int minHeight = 0; int minWidth = 0; boolean expandHorizontal = false; boolean expandVertical = false; boolean alwaysShowScroll = false; boolean showFocusedControl = false; boolean showNextFocusedControl = true; /** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. *

* The style value is either one of the style constants defined in * class SWT which is applicable to instances of this * class, or must be built by bitwise OR'ing together * (that is, using the int "|" operator) two or more * of those SWT style constants. The class description * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. *

* * @param parent a widget which will be the parent of the new instance (cannot be null) * @param style the style of widget to construct * * @exception IllegalArgumentException
    *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • *
* @exception SWTException
    *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • *
* * @see SWT#H_SCROLL * @see SWT#V_SCROLL * @see #getStyle() */ public ScrolledComposite(Composite parent, int style) { super(parent, checkStyle(style)); super.setLayout(new ScrolledCompositeLayout()); ScrollBar hBar = getHorizontalBar (); if (hBar != null) { hBar.setVisible(false); hBar.addListener (SWT.Selection, e -> hScroll()); } ScrollBar vBar = getVerticalBar (); if (vBar != null) { vBar.setVisible(false); vBar.addListener (SWT.Selection, e -> vScroll()); } contentListener = e -> { if (e.type != SWT.Resize) return; layout(false); }; filter = event -> { if (event.type == SWT.FocusIn) { if (!showNextFocusedControl) { showNextFocusedControl = true; } else if (event.widget instanceof Control control) { if (contains(control)) showControl(control); } } else { Widget w = event.widget; if (w instanceof Control) { showNextFocusedControl = w.getDisplay().getActiveShell() == ((Control) w).getShell(); } } }; addDisposeListener(e -> { getDisplay().removeFilter(SWT.FocusIn, filter); getDisplay().removeFilter(SWT.FocusOut, filter); }); } static int checkStyle (int style) { int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; return style & mask; } boolean contains(Control control) { if (control == null || control.isDisposed()) return false; Composite parent = control.getParent(); while (parent != null && !(parent instanceof Shell)) { if (this == parent) return true; parent = parent.getParent(); } return false; } /** * Returns the Always Show Scrollbars flag. True if the scrollbars are * always shown even if they are not required. False if the scrollbars are only * visible when some part of the composite needs to be scrolled to be seen. * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the * horizontal and vertical directions. * * @return the Always Show Scrollbars flag value */ public boolean getAlwaysShowScrollBars() { /* * This call is intentionally commented out, to allow this getter method to be * called from a thread which is different from one that created the widget. */ //checkWidget(); return alwaysShowScroll; } /** * Returns true if the content control * will be expanded to fill available horizontal space. * * @return the receiver's horizontal expansion state * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.2 */ public boolean getExpandHorizontal() { checkWidget(); return expandHorizontal; } /** * Returns true if the content control * will be expanded to fill available vertical space. * * @return the receiver's vertical expansion state * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.2 */ public boolean getExpandVertical() { checkWidget(); return expandVertical; } /** * Returns the minimum width of the content control. * * @return the minimum width * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.2 */ public int getMinWidth() { checkWidget(); return minWidth; } /** * Returns the minimum height of the content control. * * @return the minimum height * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.2 */ public int getMinHeight() { checkWidget(); return minHeight; } /** * Get the content that is being scrolled. * * @return the control displayed in the content area */ public Control getContent() { /* * This call is intentionally commented out, to allow this getter method to be * called from a thread which is different from one that created the widget. */ //checkWidget(); return content; } /** * Returns true if the receiver automatically scrolls to a focused child control * to make it visible. Otherwise, returns false. * * @return a boolean indicating whether focused child controls are automatically scrolled into the viewport * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.4 */ public boolean getShowFocusedControl() { checkWidget(); return showFocusedControl; } void hScroll() { if (content == null) return; Point location = content.getLocation (); ScrollBar hBar = getHorizontalBar (); int hSelection = hBar.getSelection (); content.setLocation (-hSelection, location.y); } boolean needHScroll(Rectangle contentRect, boolean vVisible) { ScrollBar hBar = getHorizontalBar(); if (hBar == null) return false; Rectangle hostRect = getBounds(); int border = getBorderWidth(); hostRect.width -= 2*border; ScrollBar vBar = getVerticalBar(); if (vVisible && vBar != null) hostRect.width -= vBar.getSize().x; if (!expandHorizontal && contentRect.width > hostRect.width) return true; if (expandHorizontal && minWidth > hostRect.width) return true; return false; } boolean needVScroll(Rectangle contentRect, boolean hVisible) { ScrollBar vBar = getVerticalBar(); if (vBar == null) return false; Rectangle hostRect = getBounds(); int border = getBorderWidth(); hostRect.height -= 2*border; ScrollBar hBar = getHorizontalBar(); if (hVisible && hBar != null) hostRect.height -= hBar.getSize().y; if (!expandVertical && contentRect.height > hostRect.height) return true; if (expandVertical && minHeight > hostRect.height) return true; return false; } /** * Return the point in the content that currently appears in the top left * corner of the scrolled composite. * * @return the point in the content that currently appears in the top left * corner of the scrolled composite. If no content has been set, this returns * (0, 0). * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 2.0 */ public Point getOrigin() { checkWidget(); if (content == null) return new Point(0, 0); Point location = content.getLocation(); return new Point(-location.x, -location.y); } /** * Scrolls the content so that the specified point in the content is in the top * left corner. If no content has been set, nothing will occur. * * Negative values will be ignored. Values greater than the maximum scroll * distance will result in scrolling to the end of the scrollbar. * * @param origin the point on the content to appear in the top left corner * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
  • ERROR_INVALID_ARGUMENT - value of origin is outside of content *
* @since 2.0 */ public void setOrigin(Point origin) { setOrigin(origin.x, origin.y); } /** * Scrolls the content so that the specified point in the content is in the top * left corner. If no content has been set, nothing will occur. * * Negative values will be ignored. Values greater than the maximum scroll * distance will result in scrolling to the end of the scrollbar. * * @param x the x coordinate of the content to appear in the top left corner * * @param y the y coordinate of the content to appear in the top left corner * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 2.0 */ public void setOrigin(int x, int y) { checkWidget(); if (content == null) return; ScrollBar hBar = getHorizontalBar (); if (hBar != null) { hBar.setSelection(x); x = -hBar.getSelection (); } else { x = 0; } ScrollBar vBar = getVerticalBar (); if (vBar != null) { vBar.setSelection(y); y = -vBar.getSelection (); } else { y = 0; } content.setLocation(x, y); } /** * Set the Always Show Scrollbars flag. True if the scrollbars are * always shown even if they are not required. False if the scrollbars are only * visible when some part of the composite needs to be scrolled to be seen. * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the * horizontal and vertical directions. * * @param show true to show the scrollbars even when not required, false to show scrollbars only when required * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setAlwaysShowScrollBars(boolean show) { checkWidget(); if (show == alwaysShowScroll) return; alwaysShowScroll = show; ScrollBar hBar = getHorizontalBar (); if (hBar != null && alwaysShowScroll) hBar.setVisible(true); ScrollBar vBar = getVerticalBar (); if (vBar != null && alwaysShowScroll) vBar.setVisible(true); layout(false); } /** * Set the content that will be scrolled. * * @param content the control to be displayed in the content area * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setContent(Control content) { checkWidget(); if (this.content != null && !this.content.isDisposed()) { this.content.removeListener(SWT.Resize, contentListener); this.content.setBounds(new Rectangle(-200, -200, 0, 0)); } this.content = content; ScrollBar vBar = getVerticalBar (); ScrollBar hBar = getHorizontalBar (); if (this.content != null) { if (vBar != null) { vBar.setMaximum (0); vBar.setThumb (0); vBar.setSelection(0); } if (hBar != null) { hBar.setMaximum (0); hBar.setThumb (0); hBar.setSelection(0); } content.setLocation(0, 0); layout(false); this.content.addListener(SWT.Resize, contentListener); } else { if (hBar != null) hBar.setVisible(alwaysShowScroll); if (vBar != null) vBar.setVisible(alwaysShowScroll); } } /** * Configure the ScrolledComposite to resize the content object to be as wide as the * ScrolledComposite when the width of the ScrolledComposite is greater than the * minimum width specified in setMinWidth. If the ScrolledComposite is less than the * minimum width, the content will not be resized and instead the horizontal scroll bar will be * used to view the entire width. * If expand is false, this behaviour is turned off. By default, this behaviour is turned off. * * @param expand true to expand the content control to fill available horizontal space * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setExpandHorizontal(boolean expand) { checkWidget(); if (expand == expandHorizontal) return; expandHorizontal = expand; layout(false); } /** * Configure the ScrolledComposite to resize the content object to be as tall as the * ScrolledComposite when the height of the ScrolledComposite is greater than the * minimum height specified in setMinHeight. If the ScrolledComposite is less than the * minimum height, the content will not be resized and instead the vertical scroll bar will be * used to view the entire height. * If expand is false, this behaviour is turned off. By default, this behaviour is turned off. * * @param expand true to expand the content control to fill available vertical space * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setExpandVertical(boolean expand) { checkWidget(); if (expand == expandVertical) return; expandVertical = expand; layout(false); } /** * Sets the layout which is associated with the receiver to be * the argument which may be null. *

* Note: No Layout can be set on this Control because it already * manages the size and position of its children. *

* * @param layout the receiver's new layout or null * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ @Override public void setLayout (Layout layout) { checkWidget(); return; } /** * Specify the minimum height at which the ScrolledComposite will begin scrolling the * content with the vertical scroll bar. This value is only relevant if * setExpandVertical(true) has been set. * * @param height the minimum height or 0 for default height * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setMinHeight(int height) { setMinSize(minWidth, height); } /** * Specify the minimum width and height at which the ScrolledComposite will begin scrolling the * content with the horizontal scroll bar. This value is only relevant if * setExpandHorizontal(true) and setExpandVertical(true) have been set. * * @param size the minimum size or null for the default size * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setMinSize(Point size) { if (size == null) { setMinSize(0, 0); } else { setMinSize(size.x, size.y); } } /** * Specify the minimum width and height at which the ScrolledComposite will begin scrolling the * content with the horizontal scroll bar. This value is only relevant if * setExpandHorizontal(true) and setExpandVertical(true) have been set. * * @param width the minimum width or 0 for default width * @param height the minimum height or 0 for default height * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setMinSize(int width, int height) { checkWidget(); if (width == minWidth && height == minHeight) return; minWidth = Math.max(0, width); minHeight = Math.max(0, height); layout(false); } /** * Specify the minimum width at which the ScrolledComposite will begin scrolling the * content with the horizontal scroll bar. This value is only relevant if * setExpandHorizontal(true) has been set. * * @param width the minimum width or 0 for default width * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setMinWidth(int width) { setMinSize(width, minHeight); } /** * Configure the receiver to automatically scroll to a focused child control * to make it visible. * * If show is false, show a focused control is off. * By default, show a focused control is off. * * @param show true to show a focused control. * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.4 */ public void setShowFocusedControl(boolean show) { checkWidget(); if (showFocusedControl == show) return; Display display = getDisplay(); display.removeFilter(SWT.FocusIn, filter); display.removeFilter(SWT.FocusOut, filter); showFocusedControl = show; if (!showFocusedControl) return; display.addFilter(SWT.FocusIn, filter); display.addFilter(SWT.FocusOut, filter); Control control = display.getFocusControl(); if (contains(control)) showControl(control); } /** * Scrolls the content of the receiver so that the control is visible. * * @param control the control to be shown * * @exception IllegalArgumentException
    *
  • ERROR_NULL_ARGUMENT - if the control is null
  • *
  • ERROR_INVALID_ARGUMENT - if the control has been disposed
  • *
* @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 3.4 */ public void showControl(Control control) { checkWidget (); if (control == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (control.isDisposed ()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); if (!contains(control)) SWT.error(SWT.ERROR_INVALID_ARGUMENT); Rectangle itemRect = getDisplay().map(control.getParent(), this, control.getBounds()); Rectangle area = getClientArea(); Point origin = getOrigin(); if (itemRect.x < 0) { origin.x = Math.max(0, origin.x + itemRect.x); } else { if (area.width < itemRect.x + itemRect.width) origin.x = Math.max(0, origin.x + itemRect.x + Math.min(itemRect.width, area.width) - area.width); } if (itemRect.y < 0) { origin.y = Math.max(0, origin.y + itemRect.y); } else { if (area.height < itemRect.y + itemRect.height) origin.y = Math.max(0, origin.y + itemRect.y + Math.min(itemRect.height, area.height) - area.height); } setOrigin(origin); } void vScroll() { if (content == null) return; Point location = content.getLocation (); ScrollBar vBar = getVerticalBar (); int vSelection = vBar.getSelection (); content.setLocation (location.x, -vSelection); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy