Package net.sf.jasperreports.engine.export

Source Code of net.sf.jasperreports.engine.export.JRGridLayout$BoxKey

/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2009 Jaspersoft Corporation. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
*/

/*
* Contributors:
* Greg Hilton
*/

package net.sf.jasperreports.engine.export;

import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.JRBoxContainer;
import net.sf.jasperreports.engine.JRLineBox;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintFrame;
import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.base.JRBasePrintFrame;
import net.sf.jasperreports.engine.type.ModeEnum;
import net.sf.jasperreports.engine.util.JRBoxUtil;

/**
* Utility class used by grid exporters to create a grid for page layout.
*
* @author Lucian Chirita (lucianc@users.sourceforge.net)
* @version $Id: JRGridLayout.java 4291 2011-04-15 10:11:15Z teodord $
*/
public class JRGridLayout
{
  private final ExporterNature nature;

  private int width;
  private int height;
  private int offsetX;
  private int offsetY;
  private final String address;

  private CutsInfo xCuts;
  private CutsInfo yCuts;
  private JRExporterGridCell[][] grid;

  private Map boxesCache;

  private int virtualFrameIndex;

  private boolean hasTopMargin = true;
  private boolean hasBottomMargin = true;
  private boolean hasLeftMargin = true;
  private boolean hasRightMargin = true;

  private boolean isNested;

  /**
   * Constructor.
   *
   * @param elements the elements that should arranged in a grid
   * @param width the width available for the grid
   * @param height the height available for the grid
   * @param offsetX horizontal element position offset
   * @param offsetY vertical element position offset
   */
  public JRGridLayout(
    ExporterNature nature,
    List elements,
    int width,
    int height,
    int offsetX,
    int offsetY
    )
  {
    this(
      nature,
      elements,
      width,
      height,
      offsetX,
      offsetY,
      null //xCuts
      );
  }

  /**
   * Constructor.
   *
   * @param elements the elements that should arranged in a grid
   * @param width the width available for the grid
   * @param height the height available for the grid
   * @param offsetX horizontal element position offset
   * @param offsetY vertical element position offset
   * @param xCuts An optional list of pre-calculated X cuts.
   */
  public JRGridLayout(
    ExporterNature nature,
    List elements,
    int width,
    int height,
    int offsetX,
    int offsetY,
    CutsInfo xCuts
    )
  {
    this.nature = nature;
    this.height = height;
    this.width = width;
    this.offsetX = offsetX;
    this.offsetY = offsetY;
    this.address = null;
    this.xCuts = xCuts;

    boxesCache = new HashMap();

    virtualFrameIndex = elements.size();

    layoutGrid(createWrappers(null, elements, address));

    if (nature.isSplitSharedRowSpan())
    {
      splitSharedRowSpanIntoNestedGrids();
    }
  }

  /**
   * Constructor.
   *
   * @param wrappers the element wrappers that should arranged in a grid
   * @param width the width available for the grid
   * @param height the height available for the grid
   * @param offsetX horizontal element position offset
   * @param offsetY vertical element position offset
   * @param address element address
   */
  protected JRGridLayout(
    ExporterNature nature,
    ElementWrapper[] wrappers,
    int width,
    int height,
    int offsetX,
    int offsetY,
    String address
    )
  {
    this.nature = nature;
    this.height = height;
    this.width = width;
    this.offsetX = offsetX;
    this.offsetY = offsetY;
    this.address = address;

    //this constructor is called only in nested grids:
    this.isNested = true;

    boxesCache = new HashMap();

    layoutGrid(wrappers);

    if (nature.isSplitSharedRowSpan())
    {
      splitSharedRowSpanIntoNestedGrids();
    }
  }


  /**
   *
   */
  private void createNestedGrid(
    int row1,
    int col1,
    int row2,
    int col2
    )
  {
    JRBasePrintFrame frame = new JRBasePrintFrame(null);
    List wrappers = new ArrayList();

    frame.setWidth(xCuts.getCut(col2) - xCuts.getCut(col1));
    frame.setHeight(yCuts.getCut(row2) - yCuts.getCut(row1));

    String virtualAddress = (address == null ? "" : address + "_") + getNextVirtualFrameIndex();

    JRExporterGridCell gridCell =
      new ElementGridCell(
        new ElementWrapper(null, frame, virtualAddress),
        frame.getWidth(),
        frame.getHeight(),
        col2 - col1,
        row2 - row1
        );

    OccupiedGridCell occupiedGridCell = new OccupiedGridCell(gridCell);
    for(int row = row1; row < row2; row++)
    {
      for(int col = col1; col < col2; col++)
      {
        JRExporterGridCell gCell = grid[row][col];
        grid[row][col] = occupiedGridCell;
        ElementWrapper wrapper = gCell.getWrapper();
        if (gCell.getType() == JRExporterGridCell.TYPE_ELEMENT_CELL)
        {
          wrappers.add(wrapper);
          frame.addElement(wrapper.getElement());//FIXMEODT do we need this?
        }
      }
    }

    gridCell.setLayout(
      new JRGridLayout(
        nature,
        (ElementWrapper[]) wrappers.toArray(new ElementWrapper[wrappers.size()]),
        frame.getWidth(),
        frame.getHeight(),
        offsetX -xCuts.getCut(col1),
        offsetY -yCuts.getCut(row1),
        virtualAddress
        )
      );

    grid[row1][col1] = gridCell;
  }


  /**
   * Constructs the element grid.
   */
  protected void layoutGrid(ElementWrapper[] wrappers)
  {

    boolean createXCuts = (xCuts == null);

    xCuts = createXCuts ? new CutsInfo() : xCuts;
    yCuts = nature.isIgnoreLastRow() ? new CutsInfo(0) : new CutsInfo(height);

    if(!isNested && nature.isIgnorePageMargins()) //FIXMEXLS left and right margins are not ignored when all pages on a single sheet
    {
      setMargins(wrappers);

      if(createXCuts)
      {
        List xCutsList = xCuts.getCuts();

        if(hasLeftMargin)
        {
          xCutsList.remove(Integer.valueOf(0));
        }
      }

      List yCutsList = yCuts.getCuts();

      if(hasTopMargin)
      {
        yCutsList.remove(Integer.valueOf(0));
      }
      if(hasBottomMargin)
      {
        yCutsList.remove(Integer.valueOf(height));
      }
    }

    createCuts(wrappers, offsetX, offsetY, createXCuts);

    // add a cut at the width if it's a nested grid, or if the right margin
    // is not to be removed and no element goes beyond the width
    if (createXCuts && (isNested
        || (!(nature.isIgnorePageMargins() && hasRightMargin)
        && !(xCuts.hasCuts() && xCuts.getLastCut() >= width))))
    {
      xCuts.addCut(width);
    }
   
    xCuts.use();
    yCuts.use();

    int colCount = Math.max(xCuts.size() - 1, 0);
    int rowCount = Math.max(yCuts.size() - 1, 0);

    grid = new JRExporterGridCell[rowCount][colCount];

    for(int row = 0; row < rowCount; row++)
    {
      for(int col = 0; col < colCount; col++)
      {
        grid[row][col] =
          new EmptyGridCell(
            xCuts.getCut(col + 1) - xCuts.getCut(col),
            yCuts.getCut(row + 1) - yCuts.getCut(row),
            1,
            1
            );
      }
    }

    setGridElements(wrappers,
        offsetX, offsetY,
        0, 0, rowCount, colCount);

    width = xCuts.getTotalLength();
    height = yCuts.getTotalLength();
  }

  protected void createCuts(ElementWrapper[] wrappers, int elementOffsetX, int elementOffsetY, boolean createXCuts)
  {
    for(int elementIndex = 0; elementIndex < wrappers.length; elementIndex++)
    {
      ElementWrapper wrapper = wrappers[elementIndex];
      JRPrintElement element = wrapper.getElement();

      if (nature.isToExport(element))
      {
        if (createXCuts)
        {
          xCuts.addXCuts(element, elementOffsetX);
        }

        yCuts.addYCuts(element, elementOffsetY);
       
        JRPrintFrame frame = element instanceof JRPrintFrame ? (JRPrintFrame)element : null;
        if (frame != null && nature.isDeep(frame))
        {
          createCuts(
            wrapper.getWrappers(),
            element.getX() + elementOffsetX + frame.getLineBox().getLeftPadding().intValue(),
            element.getY() + elementOffsetY + frame.getLineBox().getTopPadding().intValue(),
            createXCuts
            );
        }
      }
    }
  }

  protected void setMargins(ElementWrapper[] wrappers)
  {
    for(int elementIndex = 0; elementIndex < wrappers.length; elementIndex++)
    {
      ElementWrapper wrapper = wrappers[elementIndex];
      JRPrintElement element = wrapper.getElement();

      if (nature.isToExport(element))
      {
        if(hasLeftMargin && element.getX() <= 0)
        {
          hasLeftMargin = false;
        }

        if(hasRightMargin && element.getX() >= width - element.getWidth())
        {
          hasRightMargin = false;
        }

        if(hasTopMargin && element.getY() <= 0)
        {
          hasTopMargin = false;
        }

        if(hasBottomMargin && element.getY() >= height - element.getHeight())
        {
          hasBottomMargin = false;
        }

      }
    }
  }


  protected void setGridElements(ElementWrapper[] wrappers,
      int elementOffsetX, int elementOffsetY,
      int startRow, int startCol, int endRow, int endCol)
  {
    for(int elementIndex = wrappers.length - 1; elementIndex >= 0; elementIndex--)
    {
      ElementWrapper wrapper = wrappers[elementIndex];
      JRPrintElement element = wrapper.getElement();

      if (nature.isToExport(element))
      {
        int x = element.getX() + elementOffsetX;
        int y = element.getY() + elementOffsetY;

        int col1 = xCuts.indexOfCut(x);
        int row1 = yCuts.indexOfCut(y);
        int col2 = xCuts.indexOfCut(x + element.getWidth());
        int row2 = yCuts.indexOfCut(y + element.getHeight());

        if (!isOverlap(row1, col1, row2, col2))
        {
          JRPrintFrame frame = element instanceof JRPrintFrame ? (JRPrintFrame)element : null;
          if (frame != null && nature.isDeep(frame))
          {
            setGridElements(
              wrapper.getWrappers(),
              x + frame.getLineBox().getLeftPadding().intValue(),
              y + frame.getLineBox().getTopPadding().intValue(),
              row1, col1, row2, col2
              );
           
            setFrameCellsStyle(frame, row1, col1, row2, col2);
          }
          else
          {
            setGridElement(wrapper, row1, col1, row2, col2);
          }
        }
      }
    }

    if (nature.isHorizontallyMergeEmptyCells())
    {
      horizontallyMergeEmptyCells(startRow, startCol, endRow, endCol);
    }
  }

  protected void horizontallyMergeEmptyCells(int startRow, int startCol, int endRow, int endCol)
  {
    for (int row = startRow; row < endRow; ++row)
    {
      int startSpan = -1;
      int spanWidth = 0;
      int col = startCol;
      for (; col < endCol; ++col)
      {
        JRExporterGridCell cell = grid[row][col];
        if (cell.isEmpty())
        {
          if (startSpan == -1)
          {
            startSpan = col;
          }
          spanWidth += cell.getWidth();
        }
        else
        {
          if (startSpan != -1 && col - startSpan > 1)
          {
            JRExporterGridCell spanCell = grid[row][startSpan];
            spanCell.setColSpan(col - startSpan);
            spanCell.setWidth(spanWidth);
            //TODO set OCCUPIED_CELL?
          }
          startSpan = -1;
          spanWidth = 0;
        }
      }
      if (startSpan != -1 && col - startSpan > 1)
      {
        JRExporterGridCell spanCell = grid[row][startSpan];
        spanCell.setColSpan(col - startSpan);
        spanCell.setWidth(spanWidth);
      }
    }
  }

  protected boolean isOverlap(int row1, int col1, int row2, int col2)
  {
    boolean isOverlap = false;
    if (nature.isSpanCells())
    {
      is_overlap_out:
      for (int row = row1; row < row2; row++)
      {
        for (int col = col1; col < col2; col++)
        {
          if (!grid[row][col].isEmpty())
          {
            isOverlap = true;
            break is_overlap_out;
          }
        }
      }
    }
    else
    {
      isOverlap = grid[row1][col1].getWrapper() != null;
    }
    return isOverlap;
  }


  protected void setGridElement(ElementWrapper wrapper, int row1, int col1, int row2, int col2)
  {
    yCuts.addUsage(row1, CutsInfo.USAGE_NOT_EMPTY);
    xCuts.addUsage(col1, CutsInfo.USAGE_NOT_EMPTY);

    JRPrintElement element = wrapper.getElement();
    JRPrintFrame frame = element instanceof JRPrintFrame ? (JRPrintFrame) element : null;

    int rowSpan = nature.isSpanCells() ? row2 - row1 : 1;
    int colSpan = nature.isSpanCells() ? col2 - col1 : 1;

    JRExporterGridCell gridCell =
      new ElementGridCell(
        wrapper,
        element.getWidth(),
        element.getHeight(),
        colSpan,
        rowSpan
        );

    if (nature.isSpanCells())
    {
      OccupiedGridCell occupiedGridCell = new OccupiedGridCell(gridCell);
      for (int row = row1; row < row2; row++)
      {
        for (int col = col1; col < col2; col++)
        {
          grid[row][col] = occupiedGridCell;
        }
        yCuts.addUsage(row, CutsInfo.USAGE_SPANNED);
      }

      for (int col = col1; col < col2; col++)
      {
        xCuts.addUsage(col, CutsInfo.USAGE_SPANNED);
      }
    }

    if (col2 - col1 != 0 && row2 - row1 != 0)
    {
      if (frame != null)//FIXMEODT if deep, does this make sense?
      {
        gridCell.setLayout(
          new JRGridLayout(
            nature,
            wrapper.getWrappers(),
            frame.getWidth(),
            frame.getHeight(),
            0, //offsetX
            0, //offsetY
            wrapper.getAddress()
            )
          );
      }

      gridCell.setBox((element instanceof JRBoxContainer)?((JRBoxContainer)element).getLineBox():null);

      if (nature.isBreakBeforeRow(element))
      {
        yCuts.addUsage(row1,  CutsInfo.USAGE_BREAK);
      }
      if (nature.isBreakAfterRow(element))
      {
        yCuts.addUsage(row1 + rowSpan,  CutsInfo.USAGE_BREAK);
      }

      grid[row1][col1] = gridCell;
    }
  }


  protected void setFrameCellsStyle(JRPrintFrame frame, int row1, int col1, int row2, int col2)
  {
    Color backcolor = frame.getModeValue() == ModeEnum.OPAQUE ? frame.getBackcolor() : null;

    for (int row = row1; row < row2; row++)
    {
      for (int col = col1; col < col2; col++)
      {
        JRExporterGridCell cell = grid[row][col];

        if (cell.getBackcolor() == null)
        {
          if (frame.getModeValue() == ModeEnum.OPAQUE)
          {
            cell.setBackcolor(backcolor);
          }
        }

        if (cell.getForecolor() == null)
        {
          cell.setForecolor(frame.getForecolor());
        }

        boolean keepLeft = col == col1;
        boolean keepRight = col == col2 - cell.getColSpan();
        boolean keepTop = row == row1;
        boolean keepBottom = row == row2 - cell.getRowSpan();

        if (keepLeft || keepRight || keepTop || keepBottom)
        {
          JRLineBox cellBox = cell.getBox();
          Object key = new BoxKey(frame.getLineBox(), cellBox, keepLeft, keepRight, keepTop, keepBottom);
          JRLineBox modBox = (JRLineBox) boxesCache.get(key);
          if (modBox == null)
          {
            modBox = JRBoxUtil.clone(frame.getLineBox(), keepLeft, keepRight, keepTop, keepBottom, cellBox);
            boxesCache.put(key, modBox);
          }

          cell.setBox(modBox);
        }
      }
    }
  }

  private void splitSharedRowSpanIntoNestedGrids()
  {
    for(int row = 0; row < grid.length;)
    {
      int rowSpan = getSharedRowSpan(row);
      //negative row span means it is not shared row span
      if (rowSpan > 0)
      {
        splitSharedColSpanIntoNestedGrids(row, row + rowSpan);
      }
      row += Math.abs(rowSpan);
    }
  }

  private void splitSharedColSpanIntoNestedGrids(int row1, int row2)
  {
    for(int col = 0; col < grid[row1].length;)
    {
      int colSpan = getSharedColSpan(row1, row2, col);
      //negative col span means it is not shared col span
      if (colSpan > 0)
      {
        if (
          !(row1 == 0
          && row2 == grid.length
          && col == 0
          && colSpan == grid[0].length)
          )
        {
          this.createNestedGrid(
            row1,
            col,
            row2,
            col + colSpan
            );
        }
      }
      col += Math.abs(colSpan);
    }
  }

  private int getSharedRowSpan(int row1)
  {
    int rowSpan = 1;
    int sharedSpanCount = 0;

    for(int row = 0; row < rowSpan; row++)
    {
      for(int col = 0; col < grid[0].length; col++)
      {
        JRExporterGridCell gridCell = grid[row1 + row][col];
        if (row + gridCell.getRowSpan() > rowSpan)
        {
          sharedSpanCount++;
          rowSpan = row + gridCell.getRowSpan();
        }
      }
    }

    // we have "shared row span" only if at least two merged cells share at least one row;
    // negative row span is used to skip row span that is not shared
    return sharedSpanCount > 1 ? rowSpan : -rowSpan;
  }

  private int getSharedColSpan(int row1, int row2, int col1)
  {
    int colSpan = 1;
    boolean isSharedSpan = false;

    for(int col = 0; col < colSpan; col++)
    {
      for(int row = row1; row < row2; row++)
      {
        JRExporterGridCell gridCell = grid[row][col1 + col];
        if (col + gridCell.getColSpan() > colSpan)
        {
          isSharedSpan = true;
          colSpan = col + gridCell.getColSpan();
        }
        else if (gridCell.getRowSpan() > 1)
        {
          isSharedSpan = true;
        }
      }
    }

    // we have "shared col span" only if at least two merged cells share at least one col;
    // negative col span is used to skip col span that is not shared
    return isSharedSpan ? colSpan : -colSpan;
  }

  /**
   * Returns the constructed element grid.
   *
   * @return the constructed element grid
   */
  public JRExporterGridCell[][] getGrid()
  {
    return grid;
  }


  /**
   * Returns the list of cut points on the X axis for the grid.
   *
   * @return the list of cut points on the X axis for the grid
   */
  public CutsInfo getXCuts()
  {
    return xCuts;
  }


  /**
   * Returns the list of cut points on the Y axis for the grid.
   *
   * @return the list of cut points on the Y axis for the grid
   */
  public CutsInfo getYCuts()
  {
    return yCuts;
  }


  /**
   * Returns the width available for the grid.
   *
   * @return the width available for the grid
   */
  public int getWidth()
  {
    return width;
  }


  public int getColumnWidth(int col)
  {
    return xCuts.getCut(col + 1) - xCuts.getCut(col);
  }


  public int getRowHeight(int row)
  {
    return yCuts.getCut(row + 1) - yCuts.getCut(row);
  }


  public int getMaxRowHeight(int rowIndex)
  {
    JRExporterGridCell[] row = grid[rowIndex];
    int maxRowHeight = row[0].getHeight();
    for (int col = 0; col < row.length; col++)
    {
      JRExporterGridCell cell = row[col];

      if (cell.getType() != JRExporterGridCell.TYPE_OCCUPIED_CELL)
      {
        if (maxRowHeight < cell.getHeight())
        {
          maxRowHeight = cell.getHeight();
        }
      }
    }
    return maxRowHeight;
  }


  public static int getRowHeight(JRExporterGridCell[] row)//FIXMEODT are we still using this?
  {
    if (row[0].getRowSpan() == 1 && row[0].getType() != JRExporterGridCell.TYPE_OCCUPIED_CELL) //quick exit
    {
      return row[0].getHeight();
    }

    int rowHeight = 0;
    int minSpanIdx = 0;

    int colCount = row.length;

    int col;
    for (col = 0; col < colCount; col++)
    {
      JRExporterGridCell cell = row[col];

      if (cell.getType() != JRExporterGridCell.TYPE_OCCUPIED_CELL)
      {
        if (cell.getRowSpan() == 1)
        {
          rowHeight = cell.getHeight();
          break;
        }

        if (cell.getRowSpan() < row[minSpanIdx].getRowSpan())
        {
          minSpanIdx = col;
        }
      }
    }

    if (col >= colCount) //no cell with rowSpan = 1 was found, getting the height of the cell with min rowSpan
    {
      rowHeight = row[minSpanIdx].getHeight();
    }

    return rowHeight;
  }


  /**
   * This static method calculates all the X cuts for a list of pages.
   *
   * @param pages
   *            The list of pages.
   * @param startPageIndex
   *            The first page to consider.
   * @param endPageIndex
   *            The last page to consider.
   * @param width
   *            The page width
   * @param offsetX
   *            horizontal element position offset
   */
  public static CutsInfo calculateXCuts(ExporterNature nature, List pages, int startPageIndex, int endPageIndex, int width, int offsetX)
  {
    CutsInfo xCuts = new CutsInfo();

    for (int pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
    {
      JRPrintPage page = (JRPrintPage) pages.get(pageIndex);
      addXCuts(nature, page.getElements(), offsetX, xCuts);
    }
   
    // add a cut at the page width if no element goes beyond the width
    int lastCut = xCuts.getLastCut();
    if (lastCut < width)
    {
      xCuts.addCut(width);
    }

    return xCuts;
  }

  /**
   * This static method calculates the X cuts for a list of print elements and
   * stores them in the list indicated by the xCuts parameter.
   *
   * @param elementsList
   *            The list of elements to be used to determine the X cuts.
   * @param elementOffsetX
   *            horizontal element position offset
   * @param xCuts
   *            The list to which the X cuts are to be added.
   */
  protected static void addXCuts(ExporterNature nature, List elementsList, int elementOffsetX, CutsInfo xCuts)
  {
    for (Iterator it = elementsList.iterator(); it.hasNext();)
    {
      JRPrintElement element = ((JRPrintElement) it.next());

      if (nature.isToExport(element))
      {
        xCuts.addXCuts(element, elementOffsetX);
       
        if (element instanceof JRPrintFrame)
        {
          JRPrintFrame frame = (JRPrintFrame) element;
          addXCuts(
            nature,
            frame.getElements(),
            element.getX() + elementOffsetX + frame.getLineBox().getLeftPadding().intValue(),
            xCuts
            );
        }
      }
    }
  }

  /**
   *
   */
  protected int getNextVirtualFrameIndex()
  {
    return virtualFrameIndex++;
  }


  /**
   *
   */
  private static ElementWrapper[] createWrappers(ElementWrapper parentWrapper, List elementsList, String parentAddress)
  {
    ElementWrapper[] wrappers = new ElementWrapper[elementsList.size()];

    for (int elementIndex = 0; elementIndex < elementsList.size(); elementIndex++)
    {
      JRPrintElement element = ((JRPrintElement) elementsList.get(elementIndex));

      String address = (parentAddress == null ? "" : parentAddress + "_") + elementIndex;

      ElementWrapper wrapper =
        new ElementWrapper(
          parentWrapper,
          element,
          address
          );
     
      if (element instanceof JRPrintFrame)
      {
        wrapper.setWrappers(createWrappers(wrapper, ((JRPrintFrame)element).getElements(), address));
      }

      wrappers[elementIndex] = wrapper;
    }

    return wrappers;
  }

  /**
   *
   */
  protected static class BoxKey
  {
    final JRLineBox box;
    final JRLineBox cellBox;
    final boolean left;
    final boolean right;
    final boolean top;
    final boolean bottom;
    final int hashCode;

    BoxKey(JRLineBox box, JRLineBox cellBox, boolean left, boolean right, boolean top, boolean bottom)
    {
      this.box = box;
      this.cellBox = cellBox;
      this.left = left;
      this.right = right;
      this.top = top;
      this.bottom = bottom;

      int hash = box.hashCode();
      if (cellBox != null)
      {
        hash = 31*hash + cellBox.hashCode();
      }
      hash = 31*hash + (left ? 1231 : 1237);
      hash = 31*hash + (right ? 1231 : 1237);
      hash = 31*hash + (top ? 1231 : 1237);
      hash = 31*hash + (bottom ? 1231 : 1237);
      hashCode = hash;
    }

    public boolean equals(Object obj)
    {
      if (obj == this)
      {
        return true;
      }

      BoxKey b = (BoxKey) obj;

      return b.box.equals(box) &&
        (b.cellBox == null ? cellBox == null : (cellBox != null && b.cellBox.equals(cellBox))) &&
        b.left == left && b.right == right && b.top == top && b.bottom == bottom;
    }

    public int hashCode()
    {
      return hashCode;
    }
  }


}
TOP

Related Classes of net.sf.jasperreports.engine.export.JRGridLayout$BoxKey

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.