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

org.tomitribe.crest.table.Resize Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.tomitribe.crest.table;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Resize {

    private Resize() {
    }

    public static Data resize(final Data data, final int width) {
        if (data.getWidth().getMax() < width) return data;

        /*
         * We take the minimum size of the table and slowly and evenly expand it back out
         * until we reach the maximum.  If the desired table size is 200 and the minimum
         * size this table can be squished to is 92 we will have a remainder of 108.  The
         * 108 will be given back to each column till there is no more to allocate.
         *
         * Each column will stop taking space once it reaches its maximum or there is no
         * more space left to allocate.
         *
         * We do this to find the optimal sizes for each column, it does not actually
         * resize the cells.  That happens later.
         */
        final AtomicInteger remaining = new AtomicInteger(width - data.getWidth().getMin());

        final List columns = data.getColumns().stream()
                .map(column -> new Column(column, remaining))
                .collect(Collectors.toList());

        while (expand(columns)) {
            /* checkstyle */
        }

        /*
         * Now actually resize the cells to fit in their new column size
         * and add them to the new array of cell[][]
         */
        final Data.Cell[][] resized = new Data.Cell[data.getRows().size()][data.getColumns().size()];

        columns.stream()
                .flatMap(Column::resize)
                .forEach(cell -> resized[cell.getRow()][cell.getColumn()] = cell);

        /*
         * Create a new Data instance with the new cells
         */
        return new Data(resized, data);
    }

    private static boolean expand(final List columns) {
        return columns.stream()
                .map(Column::expand)
                .reduce((columnAExpanded, columnBExpanded) -> columnAExpanded || columnBExpanded)
                .orElse(false);
    }

    public static class Column {
        private final Data.Column column;
        private final AtomicInteger remaining;
        private int size;

        public Column(final Data.Column column, final AtomicInteger remaining) {
            this.column = column;
            this.size = column.getWidth().getMin();
            this.remaining = remaining;
        }

        public boolean expand() {
            if (size == column.getWidth().getMax()) return false;
            if (remaining.getAndDecrement() <= 0) return false;
            size++;
            return true;
        }

        public Stream resize() {
            return column.stream().map(cell -> cell.resizeTo(size));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy