Package org.fest.swing.driver

Source Code of org.fest.swing.driver.JInternalFrameDriver

/*
* Created on Feb 1, 2008
*
* 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.
*
* Copyright @2008-2010 the original author or authors.
*/
package org.fest.swing.driver;

import static org.fest.swing.driver.ComponentStateValidator.validateIsShowing;
import static org.fest.swing.driver.JInternalFrameAction.*;
import static org.fest.swing.driver.JInternalFrameIconQuery.isIconified;
import static org.fest.swing.driver.JInternalFrameSetIconTask.setIcon;
import static org.fest.swing.driver.JInternalFrameSetMaximumTask.setMaximum;
import static org.fest.swing.driver.WindowLikeContainerLocations.*;
import static org.fest.swing.edt.GuiActionRunner.execute;
import static org.fest.swing.exception.ActionFailedException.actionFailure;
import static org.fest.swing.format.Formatting.format;
import static org.fest.util.Strings.concat;

import java.awt.*;
import java.beans.PropertyVetoException;

import javax.swing.JInternalFrame;
import javax.swing.JInternalFrame.JDesktopIcon;

import org.fest.swing.annotation.RunsInCurrentThread;
import org.fest.swing.annotation.RunsInEDT;
import org.fest.swing.core.Robot;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.edt.GuiTask;
import org.fest.swing.exception.ActionFailedException;
import org.fest.swing.exception.UnexpectedException;
import org.fest.swing.util.Pair;
import org.fest.swing.util.Triple;
import org.fest.util.VisibleForTesting;

/**
* Understands functional testing of <code>{@link JInternalFrame}</code>s:
* <ul>
* <li>user input simulation</li>
* <li>state verification</li>
* <li>property value query</li>
* </ul>
* This class is intended for internal use only. Please use the classes in the package
* <code>{@link org.fest.swing.fixture}</code> in your tests.
*
* @author Alex Ruiz
* @author Yvonne Wang
*/
public class JInternalFrameDriver extends JComponentDriver {

  /**
   * Creates a new </code>{@link JInternalFrameDriver}</code>.
   * @param robot the robot to use to simulate user input.
   */
  public JInternalFrameDriver(Robot robot) {
    super(robot);
  }

  /**
   * Brings the given <code>{@link JInternalFrame}</code> to the front.
   * @param internalFrame the target <code>JInternalFrame</code>.
   */
  @RunsInEDT
  public void moveToFront(JInternalFrame internalFrame) {
    toFront(internalFrame);
  }

  @RunsInEDT
  private static void toFront(final JInternalFrame internalFrame) {
    execute(new GuiTask() {
      protected void executeInEDT() {
        // it seems that moving to front always works, regardless if the internal frame is invisible and/or disabled.
        internalFrame.toFront();
      }
    });
  }

  /**
   * Brings the given <code>{@link JInternalFrame}</code> to the back.
   * @param internalFrame the target <code>JInternalFrame</code>.
   */
  @RunsInEDT
  public void moveToBack(JInternalFrame internalFrame) {
    toBack(internalFrame);
  }

  @RunsInEDT
  private static void toBack(final JInternalFrame internalFrame) {
    execute(new GuiTask() {
      protected void executeInEDT() {
        // it seems that moving to back always works, regardless if the internal frame is invisible and/or disabled.
        internalFrame.moveToBack();
      }
    });
  }

  /**
   * Maximizes the given <code>{@link JInternalFrame}</code>, deconifying it first if it is iconified.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not maximizable.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws ActionFailedException if the <code>JInternalFrame</code> vetoes the action.
   */
  @RunsInEDT
  public void maximize(JInternalFrame internalFrame) {
    Pair<Container, Point> maximizeLocation = validateAndFindMaximizeLocation(internalFrame);
    maximizeOrNormalize(internalFrame, MAXIMIZE, maximizeLocation);
  }

  @RunsInEDT
  private static Pair<Container, Point> validateAndFindMaximizeLocation(final JInternalFrame internalFrame) {
    return execute(new GuiQuery<Pair<Container, Point>>() {
      protected Pair<Container, Point> executeInEDT() {
        validateCanMaximize(internalFrame);
        return findMaximizeLocation(internalFrame);
      }
    });
  }

  @RunsInCurrentThread
  private static void validateCanMaximize(JInternalFrame internalFrame) {
    validateIsShowingOrIconified(internalFrame);
    if (!internalFrame.isMaximizable())
      throw new IllegalStateException(concat("The JInternalFrame <", format(internalFrame), "> is not maximizable"));
  }

  /**
   * Normalizes the given <code>{@link JInternalFrame}</code>, deconifying it first if it is iconified.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws ActionFailedException if the <code>JInternalFrame</code> vetoes the action.
   */
  @RunsInEDT
  public void normalize(JInternalFrame internalFrame) {
    Pair<Container, Point> normalizeLocation = validateAndFindNormalizeLocation(internalFrame);
    maximizeOrNormalize(internalFrame, NORMALIZE, normalizeLocation);
  }

  @RunsInEDT
  private static Pair<Container, Point> validateAndFindNormalizeLocation(final JInternalFrame internalFrame) {
    return execute(new GuiQuery<Pair<Container, Point>>() {
      protected Pair<Container, Point> executeInEDT() {
        validateIsShowingOrIconified(internalFrame);
        return findMaximizeLocation(internalFrame);
      }
    });
  }

  @RunsInCurrentThread
  private static void validateIsShowingOrIconified(JInternalFrame internalFrame) {
    if (!internalFrame.isIcon()) validateIsShowing(internalFrame);
  }

  @RunsInCurrentThread
  private static Pair<Container, Point> findMaximizeLocation(JInternalFrame internalFrame) {
    Container clickTarget = internalFrame.isIcon() ? internalFrame.getDesktopIcon() : internalFrame;
    Point location = maximizeLocationOf(clickTarget);
    return new Pair<Container, Point>(clickTarget, location);
  }

  @RunsInEDT
  private void maximizeOrNormalize(JInternalFrame internalFrame, JInternalFrameAction action,
      Pair<Container, Point> toMoveMouseTo) {
    moveMouseIgnoringAnyError(toMoveMouseTo.i, toMoveMouseTo.ii);
    setMaximumProperty(internalFrame, action);
  }

  @RunsInEDT
  private void setMaximumProperty(JInternalFrame internalFrame, JInternalFrameAction action) {
    try {
      setMaximum(internalFrame, action);
      robot.waitForIdle();
    } catch (UnexpectedException unexpected) {
      failIfVetoed(internalFrame, action, unexpected);
    }
  }

  /**
   * Iconifies the given <code>{@link JInternalFrame}</code>.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not iconifiable.
   * @throws ActionFailedException if the <code>JInternalFrame</code> vetoes the action.
   */
  @RunsInEDT
  public void iconify(JInternalFrame internalFrame) {
    Pair<Boolean, Point> iconifyInfo = validateAndfindIconifyInfo(internalFrame);
    if (iconifyInfo.i) return; // internal frame is already iconified
    moveMouseIgnoringAnyError(internalFrame, iconifyInfo.ii);
    setIconProperty(internalFrame, ICONIFY);
  }

  @RunsInEDT
  private static Pair<Boolean, Point> validateAndfindIconifyInfo(final JInternalFrame internalFrame) {
    return execute(new GuiQuery<Pair<Boolean, Point>>() {
      protected Pair<Boolean, Point> executeInEDT() throws Throwable {
        validateIsShowingOrIconified(internalFrame);
        if (!internalFrame.isIconifiable())
          throw new IllegalStateException(concat("The JInternalFrame <", format(internalFrame), "> is not iconifiable"));
        return iconifyInfo(internalFrame);
      }
    });
  }

  @RunsInCurrentThread
  private static Pair<Boolean, Point> iconifyInfo(JInternalFrame internalFrame) {
    boolean iconified = isIconified(internalFrame);
    if (iconified) return new Pair<Boolean, Point>(true, null);
    return new Pair<Boolean, Point>(iconified, findIconifyLocation(internalFrame));
  }

  /**
   * De-iconifies the given <code>{@link JInternalFrame}</code>.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws ActionFailedException if the <code>JInternalFrame</code> vetoes the action.
   */
  @RunsInEDT
  public void deiconify(JInternalFrame internalFrame) {
    Triple<Boolean, Container, Point> deiconifyInfo = validateAndfindDeiconifyInfo(internalFrame);
    if (deiconifyInfo.i) return; // internal frame is already de-iconified
    moveMouseIgnoringAnyError(deiconifyInfo.ii, deiconifyInfo.iii);
    setIconProperty(internalFrame, DEICONIFY);
  }

  @RunsInEDT
  private static Triple<Boolean, Container, Point> validateAndfindDeiconifyInfo(final JInternalFrame internalFrame) {
    return execute(new GuiQuery<Triple<Boolean, Container, Point>>() {
      protected Triple<Boolean, Container, Point> executeInEDT() throws Throwable {
        validateIsShowingOrIconified(internalFrame);
        return deiconifyInfo(internalFrame);
      }
    });
  }

  @RunsInCurrentThread
  private static Triple<Boolean, Container, Point> deiconifyInfo(JInternalFrame internalFrame) {
    boolean deiconified = !isIconified(internalFrame);
    if (deiconified) return new Triple<Boolean, Container, Point>(true, null, null);
    JDesktopIcon desktopIcon = internalFrame.getDesktopIcon();
    return new Triple<Boolean, Container, Point>(deiconified, desktopIcon, iconifyLocationOf(desktopIcon));
  }

  @RunsInCurrentThread
  private static Point findIconifyLocation(JInternalFrame internalFrame) {
    return iconifyLocationOf(internalFrame.getDesktopIcon());
  }

  @RunsInEDT
  private void setIconProperty(JInternalFrame internalFrame, JInternalFrameAction action) {
    try {
      setIcon(internalFrame, action);
      robot.waitForIdle();
    } catch (UnexpectedException unexpected) {
      failIfVetoed(internalFrame, action, unexpected);
    }
  }

  @VisibleForTesting
  void failIfVetoed(JInternalFrame internalFrame, JInternalFrameAction action, UnexpectedException unexpected) {
    PropertyVetoException vetoError = vetoFrom(unexpected);
    if (vetoError == null) return;
    throw actionFailure(concat(action.name, " of ", format(internalFrame), " was vetoed: <", vetoError.getMessage(), ">"));
  }

  private PropertyVetoException vetoFrom(UnexpectedException unexpected) {
    Throwable cause = unexpected.getCause();
    if (!(cause instanceof PropertyVetoException)) return null;
    return (PropertyVetoException)cause;
  }

  /**
   * Resizes the <code>{@link JInternalFrame}</code> horizontally.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @param width the width that the <code>JInternalFrame</code> should have after being resized.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not resizable by the user.
   */
  @RunsInEDT
  public void resizeWidthTo(JInternalFrame internalFrame, int width) {
    resizeWidth(internalFrame, width);
  }

  /**
   * Resizes the <code>{@link JInternalFrame}</code> vertically.
   * @param w the target <code>JInternalFrame</code>.
   * @param height the height that the <code>JInternalFrame</code> should have after being resized.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not resizable by the user.
   */
  @RunsInEDT
  public void resizeHeightTo(JInternalFrame w, int height) {
    resizeHeight(w, height);
  }

  /**
   * Resizes the <code>{@link JInternalFrame}</code> to the given size.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @param size the size to resize the <code>JInternalFrame</code> to.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not resizable by the user.
   */
  @RunsInEDT
  public void resizeTo(JInternalFrame internalFrame, Dimension size) {
    resize(internalFrame, size.width, size.height);
  }

  /**
   * Moves the <code>{@link JInternalFrame}</code> to the given location.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @param where the location to move the <code>JInternalFrame</code> to.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   */
  @RunsInEDT
  public void moveTo(JInternalFrame internalFrame, Point where) {
    move(internalFrame, where.x, where.y);
  }

  /**
   * Closes the given <code>{@link JInternalFrame}</code>.
   * @param internalFrame the target <code>JInternalFrame</code>.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not showing on the screen.
   * @throws IllegalStateException if the <code>JInternalFrame</code> is not closable.
   */
  @RunsInEDT
  public void close(JInternalFrame internalFrame) {
    Pair<Boolean, Point> closeInfo = validateAndFindCloseInfo(internalFrame);
    if (closeInfo.i) return; // internal frame is already closed
    moveMouseIgnoringAnyError(internalFrame, closeInfo.ii);
    JInternalFrameCloseTask.close(internalFrame);
    robot.waitForIdle();
  }

  @RunsInEDT
  private static Pair<Boolean, Point> validateAndFindCloseInfo(final JInternalFrame internalFrame) {
    return execute(new GuiQuery<Pair<Boolean, Point>>() {
      protected Pair<Boolean, Point> executeInEDT() {
        validateCanClose(internalFrame);
        return closeInfo(internalFrame);
      }
    });
  }

  @RunsInCurrentThread
  private static void validateCanClose(JInternalFrame internalFrame) {
    validateIsShowing(internalFrame);
    if (!internalFrame.isClosable())
      throw new IllegalStateException(concat("The JInternalFrame <", format(internalFrame), "> is not closable"));
  }

  @RunsInCurrentThread
  private static Pair<Boolean, Point> closeInfo(JInternalFrame internalFrame) {
    if (internalFrame.isClosed()) return new Pair<Boolean, Point>(true, null);
    return new Pair<Boolean, Point>(false, closeLocationOf(internalFrame));
  }

}
TOP

Related Classes of org.fest.swing.driver.JInternalFrameDriver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.