├── .gitignore ├── LICENSE.txt ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── inamik │ └── text │ └── tables │ ├── Cell.java │ ├── GridTable.java │ ├── SimpleTable.java │ ├── cell │ ├── BottomAlign.java │ ├── BottomPad.java │ ├── BottomTruncate.java │ ├── TopAlign.java │ ├── TopPad.java │ ├── TopTruncate.java │ ├── VerticalCenter.java │ └── base │ │ ├── Function.java │ │ ├── FunctionWithChar.java │ │ ├── FunctionWithCharAndHeight.java │ │ ├── FunctionWithCharAndWidth.java │ │ ├── FunctionWithCharAndWidthAndHeight.java │ │ ├── FunctionWithHeight.java │ │ ├── FunctionWithWidth.java │ │ └── FunctionWithWidthAndHeight.java │ ├── grid │ ├── Border.java │ └── Util.java │ └── line │ ├── HorizontalCenter.java │ ├── LeftAlign.java │ ├── LeftPad.java │ ├── LeftTruncate.java │ ├── RightAlign.java │ ├── RightPad.java │ ├── RightTruncate.java │ └── base │ ├── Function.java │ ├── FunctionWithChar.java │ ├── FunctionWithCharAndWidth.java │ └── FunctionWithWidth.java └── test └── java └── com └── inamik └── text └── tables ├── GridTableTest.java └── SimpleTableTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Created with help from www.gitignore.io 3 | # 4 | 5 | 6 | ####################################################################### 7 | # Intellij 8 | # Created by https://www.gitignore.io/api/intellij 9 | # 10 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 11 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 12 | 13 | # User-specific stuff: 14 | .idea/workspace.xml 15 | .idea/tasks.xml 16 | .idea/dictionaries 17 | .idea/vcs.xml 18 | .idea/jsLibraryMappings.xml 19 | 20 | # Sensitive or high-churn files: 21 | .idea/dataSources.ids 22 | .idea/dataSources.xml 23 | .idea/dataSources.local.xml 24 | .idea/sqlDataSources.xml 25 | .idea/dynamic.xml 26 | .idea/uiDesigner.xml 27 | 28 | # Gradle: 29 | .idea/gradle.xml 30 | .idea/libraries 31 | 32 | # Mongo Explorer plugin: 33 | .idea/mongoSettings.xml 34 | 35 | ## File-based project format: 36 | *.iws 37 | 38 | ## Plugin-specific files: 39 | 40 | # IntelliJ 41 | /out/ 42 | 43 | # mpeltonen/sbt-idea plugin 44 | .idea_modules/ 45 | 46 | # JIRA plugin 47 | atlassian-ide-plugin.xml 48 | 49 | # Crashlytics plugin (for Android Studio and IntelliJ) 50 | com_crashlytics_export_strings.xml 51 | crashlytics.properties 52 | crashlytics-build.properties 53 | fabric.properties 54 | 55 | ### Intellij Patch ### 56 | *.iml 57 | *.ipr 58 | 59 | 60 | ####################################################################### 61 | # Maven 62 | # Created by https://www.gitignore.io/api/maven 63 | # 64 | target/ 65 | pom.xml.tag 66 | pom.xml.releaseBackup 67 | pom.xml.versionsBackup 68 | pom.xml.next 69 | release.properties 70 | dependency-reduced-pom.xml 71 | buildNumber.properties 72 | .mvn/timing.properties 73 | 74 | 75 | ####################################################################### 76 | # OSX 77 | # Created by https://www.gitignore.io/api/osx 78 | # 79 | .DS_Store 80 | .AppleDouble 81 | .LSOverride 82 | 83 | # Icon must end with two \r 84 | Icon 85 | 86 | 87 | # Thumbnails 88 | ._* 89 | 90 | # Files that might appear in the root of a volume 91 | .DocumentRevisions-V100 92 | .fseventsd 93 | .Spotlight-V100 94 | .TemporaryItems 95 | .Trashes 96 | .VolumeIcon.icns 97 | 98 | # Directories potentially created on remote AFP share 99 | .AppleDB 100 | .AppleDesktop 101 | Network Trash Folder 102 | Temporary Items 103 | .apdisk 104 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 David Farrell (DavidPFarrell@yahoo.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # java\_text\_tables 2 | 3 | **Text Table Library in Java** 4 | 5 | ## About 6 | 7 | The `Java Text Tables` library is the next generation of my original [Java Text Table Formatter](https://github.com/iNamik/Java-Text-Table-Formatter) project. 8 | 9 | This new project hopes to offer more extensibility and composability, while still providing the ease-of-use of the original project. 10 | 11 | ## Examples 12 | 13 | ### SimpleTable Example 14 | 15 | `SimpleTable` is Optimized for quick table construction without having to know the final table dimensions beforehand. It Allows you to build a table one row/cell at a time. 16 | 17 | // NOTE: Apply vertical alignment FIRST ! 18 | // 19 | SimpleTable s = SimpleTable.of() 20 | .nextRow() 21 | .nextCell() 22 | .addLine("Left") 23 | .addLine("Top") 24 | .applyToCell(TOP_ALIGN .withHeight(height)) 25 | .applyToCell(LEFT_ALIGN.withWidth (width ).withChar('^')) 26 | .nextCell() 27 | .addLine("Center") 28 | .addLine("Top") 29 | .applyToCell(TOP_ALIGN .withHeight(height)) 30 | .applyToCell(HORIZONTAL_CENTER.withWidth (width )) 31 | .nextCell() 32 | .addLine("Right") 33 | .addLine("Top") 34 | .applyToCell(TOP_ALIGN .withHeight(height)) 35 | .applyToCell(RIGHT_ALIGN.withWidth (width )) 36 | .nextRow() 37 | .nextCell() 38 | .addLine("Left") 39 | .addLine("Center") 40 | .applyToCell(VERTICAL_CENTER.withHeight(height)) 41 | .applyToCell(LEFT_ALIGN .withWidth (width )) 42 | .nextCell() 43 | .addLine("Center") 44 | .addLine("Center") 45 | .applyToCell(VERTICAL_CENTER .withHeight(height)) 46 | .applyToCell(HORIZONTAL_CENTER.withWidth (width ).withChar('.')) 47 | .nextCell() 48 | .addLine("Right") 49 | .addLine("Center") 50 | .applyToCell(VERTICAL_CENTER.withHeight(height)) 51 | .applyToCell(RIGHT_ALIGN .withWidth (width )) 52 | .nextRow() 53 | .nextCell() 54 | .addLine("Left") 55 | .addLine("Bottom") 56 | .applyToCell(BOTTOM_ALIGN.withHeight(height)) 57 | .applyToCell(LEFT_ALIGN .withWidth (width )) 58 | .nextCell() 59 | .addLine("Center") 60 | .addLine("Bottom") 61 | .applyToCell(BOTTOM_ALIGN .withHeight(height)) 62 | .applyToCell(HORIZONTAL_CENTER.withWidth (width )) 63 | .nextCell() 64 | .addLine("Right") 65 | .addLine("Bottom") 66 | .applyToCell(BOTTOM_ALIGN.withHeight(height)) 67 | .applyToCell(RIGHT_ALIGN .withWidth (width ).withChar('_')) 68 | ; 69 | 70 | // 71 | // NOTE: SimpleTable makes creating the table easy, but you will need to convert it 72 | // into a GridTable in order to perform further operations 73 | // (like adding a border or printing) 74 | // 75 | 76 | // Convert to grid 77 | // 78 | GridTable g = s.toGrid(); 79 | 80 | // Add simple border 81 | // 82 | g = Border.of(Border.Chars.of('+', '-', '|')).apply(g); 83 | 84 | 85 | // Print the table to System.out 86 | // 87 | Util.print(g); 88 | 89 | The above code should result in the following output: 90 | 91 | +----------+----------+----------+ 92 | |Left^^^^^^| Center | Right| 93 | |Top^^^^^^^| Top | Top| 94 | |^^^^^^^^^^| | | 95 | |^^^^^^^^^^| | | 96 | |^^^^^^^^^^| | | 97 | |^^^^^^^^^^| | | 98 | +----------+----------+----------+ 99 | | |..........| | 100 | | |..........| | 101 | |Left |..Center..| Right| 102 | |Center |..Center..| Center| 103 | | |..........| | 104 | | |..........| | 105 | +----------+----------+----------+ 106 | | | |__________| 107 | | | |__________| 108 | | | |__________| 109 | | | |__________| 110 | |Left | Center |_____Right| 111 | |Bottom | Bottom |____Bottom| 112 | +----------+----------+----------+ 113 | 114 | ### GridTable Example 115 | 116 | `GridTable` Offers a more powerful table builder (compared to SimpleTable), but requires knowledge of the final table dimensions at construction, along with specifying coordinates `(row, col)` when manipulating cells. 117 | 118 | GridTable g = GridTable.of(3, 3) 119 | .put(0, 0, Cell.of("Left" , "Top" )) 120 | .put(0, 1, Cell.of("Center", "Top" )) 121 | .put(0, 2, Cell.of("Right" , "Top" )) 122 | 123 | .put(1, 0, Cell.of("Left" , "Center")) 124 | .put(1, 1, Cell.of("Center", "Center")) 125 | .put(1, 2, Cell.of("Right" , "Center")) 126 | 127 | .put(2, 0, Cell.of("Left" , "Bottom")) 128 | .put(2, 1, Cell.of("Center", "Bottom")) 129 | .put(2, 2, Cell.of("Right" , "Bottom")) 130 | 131 | .applyToRow(0, TOP_ALIGN .withHeight(height)) 132 | .applyToRow(1, VERTICAL_CENTER.withHeight(height)) 133 | .applyToRow(2, BOTTOM_ALIGN .withHeight(height)) 134 | 135 | .apply(0, 0, LEFT_ALIGN.withWidth(width).withChar('^')) 136 | .apply(1, 0, LEFT_ALIGN) 137 | .apply(2, 0, LEFT_ALIGN) 138 | 139 | .apply(0, 1, HORIZONTAL_CENTER.withWidth(width)) 140 | .apply(1, 1, HORIZONTAL_CENTER.withChar('.')) 141 | .apply(2, 1, HORIZONTAL_CENTER) 142 | 143 | .apply(0, 2, RIGHT_ALIGN.withWidth(width)) 144 | .apply(1, 2, RIGHT_ALIGN) 145 | .apply(2, 2, RIGHT_ALIGN.withChar('_')) 146 | ; 147 | 148 | // Add fancy border 149 | // 150 | g = Border.DOUBLE_LINE.apply(g); 151 | 152 | // Print the table to System.out 153 | // 154 | Util.print(g); 155 | 156 | The above code should result in the following output: 157 | 158 | ╔══════════╦══════════╦══════════╗ 159 | ║Left^^^^^^║ Center ║ Right║ 160 | ║Top^^^^^^^║ Top ║ Top║ 161 | ║^^^^^^^^^^║ ║ ║ 162 | ║^^^^^^^^^^║ ║ ║ 163 | ║^^^^^^^^^^║ ║ ║ 164 | ║^^^^^^^^^^║ ║ ║ 165 | ╠══════════╬══════════╬══════════╣ 166 | ║ ║..........║ ║ 167 | ║ ║..........║ ║ 168 | ║Left ║..Center..║ Right║ 169 | ║Center ║..Center..║ Center║ 170 | ║ ║..........║ ║ 171 | ║ ║..........║ ║ 172 | ╠══════════╬══════════╬══════════╣ 173 | ║ ║ ║__________║ 174 | ║ ║ ║__________║ 175 | ║ ║ ║__________║ 176 | ║ ║ ║__________║ 177 | ║Left ║ Center ║_____Right║ 178 | ║Bottom ║ Bottom ║____Bottom║ 179 | ╚══════════╩══════════╩══════════╝ 180 | *NOTE* Spaces between Border Character are due to HTML styling and would not appear in a terminal 181 | 182 | ## Importing Into Your Project 183 | 184 | ### Snapshot 185 | 186 | 187 | 188 | oss-sonatype 189 | oss-sonatype 190 | https://oss.sonatype.org/content/repositories/snapshots/ 191 | 192 | true 193 | 194 | 195 | 196 | 197 | 198 | 199 | com.github.inamik.text.tables 200 | inamik-text-tables 201 | 1.0-SNAPSHOT 202 | 203 | 204 | 205 | ## Contributing 206 | 207 | 1. Fork it! 208 | 2. Create your feature branch: `git checkout -b my-new-feature` 209 | 3. Commit your changes: `git commit -am 'Add some feature'` 210 | 4. Push to the branch: `git push origin my-new-feature` 211 | 5. Submit a pull request :D 212 | 213 | ## Credits 214 | 215 | * David Farrell (DavidPFarrell@yahoo.com) 216 | 217 | ## License 218 | 219 | Licensed under The MIT License (MIT), see LICENSE.txt 220 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | 8 | iNamik Text Tables for Java 9 | https://github.com/iNamik/java_text_tables 10 | A set of Java classes to help print text in tabulated form 11 | 12 | com.github.inamik.text.tables 13 | inamik-text-tables 14 | 0.8 15 | 16 | 17 | 18 | The MIT License (MIT) 19 | https://opensource.org/licenses/MIT 20 | 21 | 22 | 23 | 24 | 25 | davidpfarrell+maven@gmail.com 26 | David Farrell 27 | https://github.com/iNamik 28 | iNamik 29 | 30 | 31 | 32 | 33 | https://github.com/iNamik/java_text_tables 34 | scm:git:git@github.com:iNamik/java_text_tables.git 35 | scm:git:git@github.com:iNamik/java_text_tables.git 36 | 37 | 38 | 39 | 40 | ossrh 41 | https://oss.sonatype.org/content/repositories/snapshots 42 | 43 | 44 | ossrh 45 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 46 | 47 | 48 | 49 | jar 50 | 51 | 52 | 53 | 54 | junit 55 | junit 56 | 4.13.1 57 | test 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | ${basedir} 67 | 68 | README.md 69 | LICENSE.txt 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.apache.maven.plugins 78 | maven-source-plugin 79 | 2.2.1 80 | 81 | 82 | attach-sources 83 | 84 | jar-no-fork 85 | 86 | 87 | 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-javadoc-plugin 93 | 2.9.1 94 | 95 | 96 | attach-javadocs 97 | 98 | jar 99 | 100 | 101 | 102 | 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-compiler-plugin 107 | 3.1 108 | 109 | 1.6 110 | 1.6 111 | 112 | 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-jar-plugin 117 | 2.4 118 | 119 | 120 | 121 | org.apache.maven.plugins 122 | maven-gpg-plugin 123 | 1.6 124 | 125 | 126 | sign-artifacts 127 | verify 128 | 129 | sign 130 | 131 | 132 | 133 | 134 | 135 | 136 | org.apache.maven.plugins 137 | maven-release-plugin 138 | 2.5.3 139 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/Cell.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables; 9 | 10 | import com.inamik.text.tables.cell.BottomAlign; 11 | import com.inamik.text.tables.cell.BottomPad; 12 | import com.inamik.text.tables.cell.BottomTruncate; 13 | import com.inamik.text.tables.cell.base.FunctionWithChar; 14 | import com.inamik.text.tables.cell.base.FunctionWithCharAndHeight; 15 | import com.inamik.text.tables.cell.base.FunctionWithCharAndWidth; 16 | import com.inamik.text.tables.cell.base.FunctionWithCharAndWidthAndHeight; 17 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 18 | import com.inamik.text.tables.cell.base.FunctionWithWidth; 19 | import com.inamik.text.tables.cell.base.FunctionWithWidthAndHeight; 20 | import com.inamik.text.tables.cell.TopAlign; 21 | import com.inamik.text.tables.cell.TopPad; 22 | import com.inamik.text.tables.cell.TopTruncate; 23 | import com.inamik.text.tables.cell.VerticalCenter; 24 | import com.inamik.text.tables.line.HorizontalCenter; 25 | import com.inamik.text.tables.line.LeftAlign; 26 | import com.inamik.text.tables.line.LeftPad; 27 | import com.inamik.text.tables.line.LeftTruncate; 28 | import com.inamik.text.tables.line.RightAlign; 29 | import com.inamik.text.tables.line.RightPad; 30 | import com.inamik.text.tables.line.RightTruncate; 31 | 32 | import java.util.ArrayList; 33 | import java.util.Arrays; 34 | import java.util.Collection; 35 | import java.util.Collections; 36 | import java.util.List; 37 | 38 | public final class Cell 39 | { 40 | public static final Collection EMPTY = Collections.emptyList(); 41 | 42 | public static Collection of() { return EMPTY; } 43 | 44 | public static Collection of(String...cell) { 45 | return Arrays.asList(cell); 46 | } 47 | 48 | public static Collection append(Collection cell, String...lines) { 49 | List r = new ArrayList(cell.size() + lines.length); 50 | r.addAll(cell); 51 | for (String line: lines) { 52 | r.add(line); 53 | } 54 | return r; 55 | } 56 | 57 | public static Collection append(Collection cell, Collection lines) { 58 | List r = new ArrayList(cell.size() + lines.size()); 59 | r.addAll(cell); 60 | r.addAll(lines); 61 | return r; 62 | } 63 | 64 | /* 65 | * Function 66 | */ 67 | public static abstract class Function 68 | { 69 | public abstract Collection apply(Collection cell); 70 | public abstract Collection apply(Integer width, Integer height, Collection cell); 71 | public abstract Collection apply(Character character, Integer width, Integer height, Collection cell); 72 | 73 | public abstract Function withChar (char character); 74 | public abstract Function withWidth (int width ); 75 | public abstract Function withHeight(int height); 76 | 77 | public static final Function IDENTITY = new Function() { 78 | @Override 79 | public Function withChar(char _1) { return this; } 80 | @Override 81 | public Function withWidth(int _1) { return this; } 82 | @Override 83 | public Function withHeight(int _1) { return this; } 84 | @Override 85 | public Collection apply(Collection cell) { return cell; } 86 | @Override 87 | public Collection apply(Integer _1, Integer _2, Collection cell) { return cell; } 88 | @Override 89 | public Collection apply(Character _1, Integer _2, Integer _3, Collection cell) { return cell; } 90 | }; 91 | 92 | /* 93 | * From cell.Function 94 | */ 95 | public static Function from(final com.inamik.text.tables.cell.base.Function f) { 96 | return of( 97 | new FunctionWithCharAndWidthAndHeight() { 98 | @Override 99 | public Collection apply(Character _1, Integer _2, Integer _3, Collection cell) { 100 | return f.apply(cell); 101 | } 102 | }, 103 | null, null, null 104 | ); 105 | } 106 | 107 | /* 108 | * From cell.FunctionWithChar 109 | */ 110 | public static Function from(final FunctionWithChar f) { 111 | return of( 112 | new FunctionWithCharAndWidthAndHeight() { 113 | @Override 114 | public Collection apply(Character character, Integer _2, Integer _3, Collection cell) { 115 | return f.apply(character, cell); 116 | } 117 | }, 118 | null, null, null 119 | ); 120 | } 121 | 122 | /* 123 | * From cell.FunctionWithWidth 124 | */ 125 | public static Function from(final FunctionWithWidth f) { 126 | return of( 127 | new FunctionWithCharAndWidthAndHeight() { 128 | @Override 129 | public Collection apply(Character _1, Integer width, Integer _3, Collection cell) { 130 | return f.apply(width, cell); 131 | } 132 | }, 133 | null, null, null 134 | ); 135 | } 136 | 137 | /* 138 | * From cell.FunctionWithHeight 139 | */ 140 | public static Function from(final FunctionWithHeight f) { 141 | return of( 142 | new FunctionWithCharAndWidthAndHeight() { 143 | @Override 144 | public Collection apply(Character _1, Integer _2, Integer height, Collection cell) { 145 | return f.apply(height, cell); 146 | } 147 | }, 148 | null, null, null 149 | ); 150 | } 151 | 152 | /* 153 | * From cell.FunctionWithCharAndWidth 154 | */ 155 | public static Function from(final FunctionWithCharAndWidth f) { 156 | return of( 157 | new FunctionWithCharAndWidthAndHeight() { 158 | @Override 159 | public Collection apply(Character character, Integer width, Integer _3, Collection cell) { 160 | return f.apply(character, width, cell); 161 | } 162 | }, 163 | null, null, null 164 | ); 165 | } 166 | 167 | /* 168 | * From cell.FunctionWithCharAndHeight 169 | */ 170 | public static Function from(final FunctionWithCharAndHeight f) { 171 | return of( 172 | new FunctionWithCharAndWidthAndHeight() { 173 | @Override 174 | public Collection apply(Character character, Integer _2, Integer height, Collection cell) { 175 | return f.apply(character, height, cell); 176 | } 177 | }, 178 | null, null, null 179 | ); 180 | } 181 | 182 | /* 183 | * From cell.FunctionWithWidthAndHeight 184 | */ 185 | public static Function from(final FunctionWithWidthAndHeight f) { 186 | return of( 187 | new FunctionWithCharAndWidthAndHeight() { 188 | @Override 189 | public Collection apply(Character _1, Integer width, Integer height, Collection cell) { 190 | return f.apply(width, height, cell); 191 | } 192 | }, 193 | null, null, null 194 | ); 195 | } 196 | 197 | /* 198 | * From cell.FunctionWithCharAndWidthAndHeight 199 | */ 200 | public static Function from(FunctionWithCharAndWidthAndHeight f) { 201 | return of(f, null, null, null); 202 | } 203 | 204 | private static Function of(final FunctionWithCharAndWidthAndHeight f, final Character character, final Integer width, final Integer height) { 205 | return new Function() { 206 | @Override 207 | public Function withChar(char character) { return of(f, character, width, height); } 208 | @Override 209 | public Function withWidth(int width) { return of(f, character, width, height); } 210 | @Override 211 | public Function withHeight(int height) { return of(f, character, width, height); } 212 | @Override 213 | public Collection apply(Collection cell) { 214 | return apply(' ' , null, null, cell); 215 | } 216 | @Override 217 | public Collection apply(Integer w, Integer h, Collection cell) { 218 | return apply(' ' , w, h, cell); 219 | } 220 | @Override 221 | public Collection apply(Character c, Integer w, Integer h, Collection cell) { 222 | c = (null == character) ? c : character; 223 | w = (null == width ) ? w : width; 224 | h = (null == height ) ? h : height; 225 | return f.apply(c, w, h, cell); 226 | } 227 | }; 228 | } 229 | 230 | } 231 | 232 | public static abstract class FullPadding extends Function 233 | { 234 | public abstract FullPadding fullPad (int pad ); 235 | public abstract FullPadding leftPad (int leftPad ); 236 | public abstract FullPadding rightPad (int rightPad ); 237 | public abstract FullPadding topPad (int topPad ); 238 | public abstract FullPadding bottomPad(int bottomPad); 239 | 240 | public static final FullPadding INSTANCE = of(0,0,0,0, null, null, null); 241 | 242 | public static FullPadding of(final int leftPad, final int rightPad, final int topPad, final int bottomPad, final Character character, final Integer width, final Integer height) { 243 | return new FullPadding() { 244 | @Override 245 | public FullPadding fullPad (int pad ) { return of ( pad, pad, pad, pad, character, width, height); } 246 | @Override 247 | public FullPadding leftPad (int leftPad ) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 248 | @Override 249 | public FullPadding rightPad (int rightPad ) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 250 | @Override 251 | public FullPadding topPad (int topPad ) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 252 | @Override 253 | public FullPadding bottomPad (int bottomPad ) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 254 | @Override 255 | public FullPadding withChar (char character) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 256 | @Override 257 | public FullPadding withWidth (int width ) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 258 | @Override 259 | public FullPadding withHeight(int height ) { return of(leftPad, rightPad, topPad, bottomPad, character, width, height); } 260 | @Override 261 | public Collection apply(Collection cell) { 262 | return apply(' ', null, null, cell); 263 | } 264 | @Override 265 | public Collection apply(Integer w, Integer h, Collection cell) { 266 | return apply(' ', w, h, cell); 267 | } 268 | @Override 269 | public Collection apply(Character c, Integer w, Integer h, Collection cell) { 270 | c = (null == character) ? ' ' : character; 271 | w = (null == width ) ? w : width; 272 | h = (null == height ) ? h : height; 273 | 274 | cell = FunctionWithWidth .from(LeftTruncate .INSTANCE).apply(Math.max(0, w - leftPad ), cell); 275 | cell = FunctionWithWidth .from(RightTruncate.INSTANCE).apply(Math.max(0, w - leftPad - rightPad), cell); 276 | 277 | cell = FunctionWithCharAndWidth.from(LeftPad .INSTANCE).apply(c, Math.max(leftPad , w - rightPad), cell); 278 | cell = FunctionWithCharAndWidth.from(RightPad .INSTANCE).apply(c, Math.max(rightPad, w) , cell); 279 | 280 | cell = TopTruncate .INSTANCE.apply(Math.max(0, h - topPad ), cell); 281 | cell = BottomTruncate.INSTANCE.apply(Math.max(0, h - topPad - bottomPad), cell); 282 | 283 | cell = TopPad .INSTANCE.apply(Math.max(topPad , h - bottomPad), cell); 284 | cell = BottomPad .INSTANCE.apply(Math.max(bottomPad, h) , cell); 285 | 286 | return cell; 287 | } 288 | }; 289 | } 290 | 291 | } 292 | 293 | /* 294 | * Functions 295 | * isolated in separate class so you can statically import them 296 | */ 297 | public static final class Functions 298 | { 299 | public static final FullPadding FULL_PADDING = FullPadding.INSTANCE; 300 | 301 | public static final Function VERTICAL_CENTER = Function.from(VerticalCenter.INSTANCE); 302 | public static final Function BOTTOM_ALIGN = Function.from(BottomAlign .INSTANCE); 303 | public static final Function BOTTOM_PAD = Function.from(BottomPad .INSTANCE); 304 | public static final Function TOP_ALIGN = Function.from(TopAlign .INSTANCE); 305 | public static final Function TOP_PAD = Function.from(TopPad .INSTANCE); 306 | public static final Function BOTTOM_TRUNCATE = Function.from(BottomTruncate.INSTANCE); 307 | public static final Function TOP_TRUNCATE = Function.from(TopTruncate .INSTANCE); 308 | 309 | public static final Function HORIZONTAL_CENTER = Function.from(FunctionWithCharAndWidth.from(HorizontalCenter.INSTANCE)); 310 | public static final Function LEFT_ALIGN = Function.from(FunctionWithCharAndWidth.from(LeftAlign .INSTANCE)); 311 | public static final Function RIGHT_ALIGN = Function.from(FunctionWithCharAndWidth.from(RightAlign .INSTANCE)); 312 | public static final Function LEFT_PAD = Function.from(FunctionWithCharAndWidth.from(LeftPad .INSTANCE)); 313 | public static final Function RIGHT_PAD = Function.from(FunctionWithCharAndWidth.from(RightPad .INSTANCE)); 314 | public static final Function LEFT_TRUNCATE = Function.from(FunctionWithWidth .from(LeftTruncate .INSTANCE)); 315 | public static final Function RIGHT_TRUNCATE = Function.from(FunctionWithWidth .from(RightTruncate .INSTANCE)); 316 | } 317 | 318 | } 319 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/GridTable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.Collections; 13 | import java.util.Iterator; 14 | import java.util.List; 15 | 16 | /* 17 | * GridTable - Offers a more powerful table builder (compared to SimpleTable), 18 | * but requires knowledge of the final table dimensions at construction, 19 | * along with specifying coordinates when manipulating cells. 20 | */ 21 | public final class GridTable 22 | { 23 | private final int numRows; 24 | private final int numCols; 25 | 26 | private final Collection[][] table; 27 | 28 | private final int[] colWidths; 29 | private final int[] rowHeights; 30 | 31 | private int tableWidth = 0; 32 | private int tableHeight = 0; 33 | 34 | public static GridTable of(int numRows, int numCols) { return new GridTable(numRows, numCols); } 35 | 36 | /* 37 | * Constructor 38 | */ 39 | @SuppressWarnings("unchecked") 40 | public GridTable(int numRows, int numCols) { 41 | if (numRows <= 0 || numCols <= 0) { 42 | throw new IllegalArgumentException(); 43 | } 44 | this.numRows = numRows; 45 | this.numCols = numCols; 46 | 47 | this.table = (Collection[][]) new Collection[numRows][numCols]; 48 | // Fill table with empty cells, 49 | // 50 | for (int r = 0; r < numRows; r++) { 51 | for (int c = 0; c < numCols; c++) { 52 | this.table [r][c] = Cell.EMPTY; 53 | } 54 | } 55 | 56 | this.colWidths = new int[numCols]; 57 | this.rowHeights = new int[numRows]; 58 | } 59 | 60 | /* 61 | * put 62 | */ 63 | public GridTable put(int row, int col, Collection cell) { 64 | if (row < 0 || row >= numRows) { 65 | throw new IndexOutOfBoundsException("row"); 66 | } 67 | if (col < 0 || col >= numCols) { 68 | throw new IndexOutOfBoundsException("col"); 69 | } 70 | _put(row, col, cell); 71 | updateRowRanges(row); 72 | updateColRanges(col); 73 | return this; 74 | } 75 | 76 | /* 77 | * apply 78 | */ 79 | public GridTable apply(int row, int col, Cell.Function f) { 80 | if (row < 0 || row >= numRows) { 81 | throw new IndexOutOfBoundsException("row"); 82 | } 83 | if (col < 0 || col >= numCols) { 84 | throw new IndexOutOfBoundsException("col"); 85 | } 86 | _apply(row, col, f); 87 | updateRowRanges(row); 88 | updateColRanges(col); 89 | return this; 90 | } 91 | 92 | /* 93 | * apply (to all) 94 | */ 95 | public GridTable apply(Cell.Function f) { 96 | for (int row = 0; row < numRows; row++) { 97 | for (int col = 0; col < numCols; col++) { 98 | _apply(row, col, f); 99 | updateColRanges(col); 100 | } 101 | updateRowRanges(row); 102 | } 103 | return this; 104 | } 105 | 106 | /* 107 | * applyToCol 108 | */ 109 | public GridTable applyToCol(int col, Cell.Function f) { 110 | if (col < 0 || col >= numCols) { 111 | throw new IndexOutOfBoundsException("col"); 112 | } 113 | for (int row = 0; row < numRows; row++) { 114 | _apply(row, col, f); 115 | updateRowRanges(row); 116 | } 117 | updateColRanges(col); 118 | return this; 119 | } 120 | 121 | /* 122 | * applyToRow 123 | */ 124 | public GridTable applyToRow(int row, Cell.Function f) { 125 | if (row < 0 || row >= numRows) { 126 | throw new IndexOutOfBoundsException("row"); 127 | } 128 | for (int col = 0; col < numCols; col++) { 129 | _apply(row, col, f); 130 | updateColRanges(col); 131 | } 132 | updateRowRanges(row); 133 | return this; 134 | } 135 | 136 | /* 137 | * cell 138 | */ 139 | public Collection cell(int row, int col) { 140 | if (row < 0 || row >= numRows) { 141 | throw new IndexOutOfBoundsException("row"); 142 | } 143 | if (col < 0 || col >= numCols) { 144 | throw new IndexOutOfBoundsException("col"); 145 | } 146 | return _cell(row, col); 147 | } 148 | 149 | public int width() { return tableWidth; } 150 | 151 | public int height() { return tableHeight; } 152 | 153 | public int numRows() { return numRows; } 154 | 155 | public int numCols() { return numCols; } 156 | 157 | public int colWidth(int col) { 158 | if (col < 0 || col >= numCols) { 159 | throw new IndexOutOfBoundsException("col"); 160 | } 161 | return colWidths[col]; 162 | } 163 | 164 | public int rowHeight(int row) { 165 | if (row < 0 || row >= numRows) { 166 | throw new IndexOutOfBoundsException("row"); 167 | } 168 | return rowHeights[row]; 169 | } 170 | 171 | public Collection toCell() { 172 | List cell = new ArrayList(tableHeight); 173 | // foreach row 174 | // 175 | for (int row = 0; row < numRows; row++) { 176 | final int rowHeight = rowHeights[row]; 177 | // Build row line buffers 178 | // 179 | StringBuilder[] rowBuffers = new StringBuilder[rowHeight]; 180 | for (int b = 0; b < rowHeight; b++) { 181 | rowBuffers[b] = new StringBuilder(); 182 | } 183 | // foreach col 184 | // 185 | for (int col = 0; col < numCols; col++) { 186 | final Iterator cellLines = _cell(row, col).iterator(); 187 | // Append col lines to row line buffers 188 | // 189 | for (StringBuilder buffer: rowBuffers) { 190 | if (cellLines.hasNext()) { 191 | buffer.append(cellLines.next()); 192 | } 193 | } 194 | } 195 | // Output whole row at once 196 | // 197 | for (StringBuilder b: rowBuffers) { 198 | cell.add(b.toString()); 199 | } 200 | } 201 | return Collections.unmodifiableCollection(cell); 202 | } 203 | 204 | /* **************************************************************************************************************** 205 | * Private Methods 206 | * ***************************************************************************************************************/ 207 | 208 | /* 209 | * updateRowRanges 210 | */ 211 | private void updateRowRanges(int row) { 212 | int height = 0; 213 | for (int col = 0; col < numCols; col++) { 214 | height = Math.max(height, table[row][col].size()); 215 | } 216 | 217 | final int oldHeight = rowHeights[row]; 218 | 219 | rowHeights[row] = height; 220 | 221 | tableHeight = tableHeight - oldHeight + height; 222 | } 223 | 224 | /* 225 | * updateColRanges 226 | */ 227 | private void updateColRanges(int col) { 228 | int width = 0; 229 | for (int row = 0; row < numRows; row++) { 230 | for (String line: table[row][col]) { 231 | width = Math.max(width, line.length()); 232 | } 233 | } 234 | 235 | final int oldWidth = colWidths [col]; 236 | 237 | colWidths[col] = width; 238 | 239 | tableWidth = tableWidth - oldWidth + width; 240 | } 241 | 242 | /* 243 | * _put 244 | */ 245 | private void _put(int row, int col, Collection cell) { 246 | table[row][col] = Collections.unmodifiableCollection(cell); 247 | } 248 | 249 | /* 250 | * _apply 251 | */ 252 | private void _apply(int row, int col, Cell.Function f) { 253 | _put(row, col, f.apply(colWidths[col], rowHeights[row], table[row][col])); 254 | } 255 | 256 | /* 257 | * _cell 258 | */ 259 | private Collection _cell(int row, int col) { 260 | return table[row][col]; 261 | } 262 | 263 | } 264 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/SimpleTable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables; 9 | 10 | import com.inamik.text.tables.cell.base.Function; 11 | 12 | import java.util.Collection; 13 | import java.util.LinkedList; 14 | 15 | /* 16 | * SimpleTable - Optimized for quick table construction without having to know the 17 | * final table dimensions beforehand. It Allows you to build a table one row/cell at 18 | * a time. 19 | * 20 | * Cell functions do not provide any global context. 21 | * 22 | * You can use toGrid() to convert to GridTable for more complex manipulations. 23 | */ 24 | public class SimpleTable 25 | { 26 | private LinkedList>> table = new LinkedList>>(); 27 | private int numRows = 0; 28 | private int numCols = 0; 29 | 30 | public static SimpleTable of() { return new SimpleTable(); } 31 | 32 | public SimpleTable() { /* Empty */ } 33 | 34 | public SimpleTable nextRow() { 35 | LinkedList> row = new LinkedList>(); 36 | table.add(row); 37 | numRows++; 38 | return this; 39 | } 40 | 41 | public SimpleTable nextCell() { 42 | if (table.isEmpty()) { 43 | throw new IllegalStateException("Table is empty. Call nextRow() first"); 44 | } 45 | final LinkedList> row = table.getLast(); 46 | row.add(Cell.EMPTY); 47 | numCols = Math.max(numCols, row.size()); 48 | return this; 49 | } 50 | 51 | public SimpleTable nextCell(String...lines) { 52 | return nextCell().addLines(lines); 53 | } 54 | 55 | public SimpleTable nextCell(Collection lines) { 56 | return nextCell().addLines(lines); 57 | } 58 | 59 | public SimpleTable addLine(String line) { 60 | if (table.isEmpty()) { 61 | throw new IllegalStateException("Table is empty. Call nextRow() first"); 62 | } 63 | LinkedList> row = table.getLast(); 64 | if (row.isEmpty()) { 65 | throw new IllegalStateException("Row is empty. Call nextCell() first"); 66 | } 67 | Collection cell = row.removeLast(); 68 | cell = Cell.append(cell, line); 69 | row.add(cell); 70 | return this; 71 | } 72 | 73 | public SimpleTable addLines(String...lines) { 74 | if (table.isEmpty()) { 75 | throw new IllegalStateException("Table is empty. Call nextRow() first"); 76 | } 77 | LinkedList> row = table.getLast(); 78 | if (row.isEmpty()) { 79 | throw new IllegalStateException("Row is empty. Call nextCell() first"); 80 | } 81 | Collection cell = row.removeLast(); 82 | cell = Cell.append(cell, lines); 83 | row.add(cell); 84 | return this; 85 | } 86 | 87 | public SimpleTable addLines(Collection lines) { 88 | if (table.isEmpty()) { 89 | throw new IllegalStateException("Table is empty. Call nextRow() first"); 90 | } 91 | LinkedList> row = table.getLast(); 92 | if (row.isEmpty()) { 93 | throw new IllegalStateException("Row is empty. Call nextCell() first"); 94 | } 95 | Collection cell = row.removeLast(); 96 | cell = Cell.append(cell, lines); 97 | row.add(cell); 98 | return this; 99 | } 100 | 101 | public SimpleTable applyToCell(Function f) { 102 | if (table.isEmpty()) { 103 | throw new IllegalStateException("Table is empty. Call nextRow() first"); 104 | } 105 | LinkedList> row = table.getLast(); 106 | if (row.isEmpty()) { 107 | throw new IllegalStateException("Row is empty. Call nextCell() first"); 108 | } 109 | Collection cell = row.removeLast(); 110 | cell = f.apply(cell); 111 | row.add(cell); 112 | return this; 113 | } 114 | 115 | public SimpleTable applyToCell(Cell.Function f) { 116 | if (table.isEmpty()) { 117 | throw new IllegalStateException("Table is empty. Call nextRow() first"); 118 | } 119 | LinkedList> row = table.getLast(); 120 | if (row.isEmpty()) { 121 | throw new IllegalStateException("Row is empty. Call nextCell() first"); 122 | } 123 | Collection cell = row.removeLast(); 124 | cell = f.apply(cell); 125 | row.add(cell); 126 | return this; 127 | } 128 | 129 | public int nextRowNum() { return table.size(); } 130 | 131 | public int nextColNum() { return (table.isEmpty()) ? 0 : table.getLast().size(); } 132 | 133 | public int numRows() { return numRows; } 134 | 135 | public int numCols() { return numCols; } 136 | 137 | public GridTable toGrid() { 138 | GridTable grid = GridTable.of(numRows, numCols); 139 | int rowNum = 0; 140 | for (LinkedList> row: table) { 141 | int colNum = 0; 142 | for (Collection cell: row) { 143 | grid.put(rowNum, colNum, cell); 144 | colNum++; 145 | } 146 | rowNum++; 147 | } 148 | return grid; 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/BottomAlign.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.Collection; 13 | 14 | public final class BottomAlign extends FunctionWithHeight 15 | { 16 | public static final BottomAlign INSTANCE = new BottomAlign(); 17 | 18 | @Override 19 | public Collection apply(Integer height, Collection cell) { 20 | cell = TopTruncate.INSTANCE.apply(height, cell); 21 | cell = TopPad .INSTANCE.apply(height, cell); 22 | return cell; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/BottomPad.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | public final class BottomPad extends FunctionWithHeight 17 | { 18 | public static final BottomPad INSTANCE = new BottomPad(); 19 | 20 | @Override 21 | public Collection apply(Integer height, Collection cell) { 22 | // Any padding needed? 23 | // 24 | if (cell.size() >= height) { 25 | return cell; 26 | } 27 | List newCell = new ArrayList(height); 28 | newCell.addAll(cell); 29 | while (newCell.size() < height) { 30 | newCell.add(""); 31 | } 32 | return newCell; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/BottomTruncate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | public final class BottomTruncate extends FunctionWithHeight 17 | { 18 | public static final BottomTruncate INSTANCE = new BottomTruncate(); 19 | 20 | @Override 21 | public Collection apply(Integer height, Collection cell) { 22 | // Any truncating needed? 23 | // 24 | if (cell.size() <= height) { 25 | return cell; 26 | } 27 | List newCell = new ArrayList(height); 28 | for (String line: cell) { 29 | // Skip last n lines 30 | // 31 | if (newCell.size() >= height) { break; } 32 | newCell.add(line); 33 | } 34 | return newCell; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/TopAlign.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.Collection; 13 | 14 | public final class TopAlign extends FunctionWithHeight 15 | { 16 | public static final TopAlign INSTANCE = new TopAlign(); 17 | 18 | @Override 19 | public Collection apply(Integer height, Collection cell) { 20 | cell = BottomTruncate.INSTANCE.apply(height, cell); 21 | cell = BottomPad .INSTANCE.apply(height, cell); 22 | return cell; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/TopPad.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | public final class TopPad extends FunctionWithHeight 17 | { 18 | public static final TopPad INSTANCE = new TopPad(); 19 | 20 | @Override 21 | public Collection apply(Integer height, Collection cell) { 22 | // Any padding needed? 23 | // 24 | if (cell.size() >= height) { 25 | return cell; 26 | } 27 | List newCell = new ArrayList(height); 28 | while (cell.size() + newCell.size() < height) { 29 | newCell.add(""); 30 | } 31 | newCell.addAll(cell); 32 | return newCell; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/TopTruncate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | public final class TopTruncate extends FunctionWithHeight 17 | { 18 | public static final TopTruncate INSTANCE = new TopTruncate(); 19 | 20 | @Override 21 | public Collection apply(Integer height, Collection cell) { 22 | // Any truncating needed? 23 | // 24 | if (cell.size() <= height) { 25 | return cell; 26 | } 27 | List newCell = new ArrayList(height); 28 | int skip = cell.size() - height; 29 | for (String line: cell) { 30 | // Skip first n lines 31 | // 32 | if (skip > 0) { 33 | skip--; 34 | continue; 35 | } 36 | newCell.add(line); 37 | } 38 | return newCell; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/VerticalCenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell; 9 | 10 | import com.inamik.text.tables.cell.base.FunctionWithHeight; 11 | 12 | import java.util.Collection; 13 | 14 | public final class VerticalCenter extends FunctionWithHeight 15 | { 16 | public static final VerticalCenter INSTANCE = new VerticalCenter(); 17 | 18 | @Override 19 | public Collection apply(Integer height, Collection cell) { 20 | // Need to truncate? 21 | // 22 | if (cell.size() > height) { 23 | int over = cell.size() - height; 24 | int carry = over % 2; 25 | int half = (over - carry) / 2; 26 | cell = TopTruncate .INSTANCE.apply(cell.size() + half + carry, cell); 27 | cell = BottomTruncate.INSTANCE.apply(cell.size() + half , cell); 28 | } 29 | else { 30 | // Need to pad? 31 | // 32 | if (cell.size() < height) { 33 | int pad = height - cell.size(); 34 | int carry = pad % 2; 35 | int half = (pad - carry) / 2; 36 | cell = TopPad .INSTANCE.apply(cell.size() + half + carry, cell); 37 | cell = BottomPad.INSTANCE.apply(cell.size() + half , cell); 38 | } 39 | } 40 | return cell; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/Function.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public abstract class Function 16 | { 17 | public abstract Collection apply(Collection cell); 18 | 19 | public static final Function IDENTITY = new Function() { 20 | @Override 21 | public Collection apply(Collection cell) { 22 | return cell; 23 | } 24 | }; 25 | 26 | /* 27 | * From line.Function 28 | */ 29 | public static Function from(final com.inamik.text.tables.line.base.Function f) { 30 | return new Function() { 31 | @Override 32 | public Collection apply(Collection cell) { 33 | // map(cell, f) 34 | // 35 | final List r = new ArrayList(cell.size()); 36 | for (String line: cell) { r.add(f.apply(line)); } 37 | return Collections.unmodifiableCollection(r); 38 | } 39 | }; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithChar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public abstract class FunctionWithChar 16 | { 17 | public abstract Collection apply(Character character, Collection cell); 18 | 19 | public static final FunctionWithChar IDENTITY = new FunctionWithChar() { 20 | @Override 21 | public Function withChar(char _1) { 22 | return Function.IDENTITY; 23 | } 24 | @Override 25 | public Collection apply(Character _1, Collection cell) { 26 | return cell; 27 | } 28 | }; 29 | 30 | /* 31 | * From line.FunctionWithChar 32 | */ 33 | public static FunctionWithChar from(final com.inamik.text.tables.line.base.FunctionWithChar f) { 34 | return new FunctionWithChar() { 35 | @Override 36 | public Function withChar(char character) { 37 | // lift(curry(f, character)) 38 | // 39 | return Function.from(f.withChar(character)); 40 | } 41 | @Override 42 | public Collection apply(Character character, Collection cell) { 43 | // map(cell, curry(f, character)) 44 | // 45 | final List r = new ArrayList(cell.size()); 46 | for (String line: cell) { r.add(f.apply(character, line)); } 47 | return Collections.unmodifiableCollection(r); 48 | } 49 | }; 50 | } 51 | 52 | public Function withChar(final char character) { 53 | // curry(this, character) 54 | // 55 | final FunctionWithChar f = this; 56 | return new Function() { 57 | @Override 58 | public Collection apply(Collection cell) { 59 | return f.apply(character, cell); 60 | } 61 | }; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithCharAndHeight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.Collection; 11 | 12 | public abstract class FunctionWithCharAndHeight 13 | { 14 | public abstract Collection apply(Character character, Integer height, Collection cell); 15 | 16 | public static final FunctionWithCharAndHeight IDENTITY = new FunctionWithCharAndHeight() { 17 | @Override 18 | public FunctionWithHeight withChar(char _1) {return FunctionWithHeight.IDENTITY; } 19 | @Override 20 | public FunctionWithChar withHeight(int _1) { 21 | return FunctionWithChar.IDENTITY; 22 | } 23 | @Override 24 | public Collection apply(Character _1, Integer _2, Collection cell) { 25 | return cell; 26 | } 27 | }; 28 | 29 | public FunctionWithHeight withChar(final char character) { 30 | // curry(this, character) 31 | // 32 | final FunctionWithCharAndHeight that = this; 33 | return new FunctionWithHeight() { 34 | @Override 35 | public Collection apply(Integer height, Collection cell) { 36 | return that.apply(character, height, cell); 37 | } 38 | }; 39 | } 40 | 41 | public FunctionWithChar withHeight(final int width) { 42 | // curry_2(this, width) 43 | // 44 | final FunctionWithCharAndHeight f = this; 45 | return new FunctionWithChar() { 46 | @Override 47 | public Collection apply(Character character, Collection cell) { 48 | return f.apply(character, width, cell); 49 | } 50 | }; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithCharAndWidth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public abstract class FunctionWithCharAndWidth 16 | { 17 | public abstract Collection apply(Character character, Integer width, Collection cell); 18 | 19 | public static final FunctionWithCharAndWidth IDENTITY = new FunctionWithCharAndWidth() { 20 | @Override 21 | public FunctionWithWidth withChar(char _1) {return FunctionWithWidth.IDENTITY; } 22 | @Override 23 | public FunctionWithChar withWidth(int _1) { 24 | return FunctionWithChar.IDENTITY; 25 | } 26 | @Override 27 | public Collection apply(Character _1, Integer _2, Collection cell) { 28 | return cell; 29 | } 30 | }; 31 | 32 | /* 33 | * From line.FunctionWithCharAndWidth 34 | */ 35 | public static FunctionWithCharAndWidth from(final com.inamik.text.tables.line.base.FunctionWithCharAndWidth f) { 36 | return new FunctionWithCharAndWidth() { 37 | @Override 38 | public FunctionWithWidth withChar(char character) { 39 | // lift(curry(f, character)) 40 | // 41 | return FunctionWithWidth.from(f.withChar(character)); 42 | } 43 | @Override 44 | public FunctionWithChar withWidth(int width) { 45 | // lift(curry_2(f, character)) 46 | // 47 | return FunctionWithChar.from(f.withWidth(width)); 48 | } 49 | @Override 50 | public Collection apply(Character character, Integer width, Collection cell) { 51 | // map(cell, curry(curry(f, character), width)) 52 | // 53 | final List r = new ArrayList(cell.size()); 54 | for (String line: cell) { r.add(f.apply(character, width, line)); } 55 | return Collections.unmodifiableCollection(r); 56 | } 57 | }; 58 | } 59 | 60 | public FunctionWithWidth withChar(final char character) { 61 | // curry(this, character) 62 | // 63 | final FunctionWithCharAndWidth f = this; 64 | return new FunctionWithWidth() { 65 | @Override 66 | public Collection apply(Integer width, Collection cell) { 67 | return f.apply(character, width, cell); 68 | } 69 | }; 70 | } 71 | 72 | public FunctionWithChar withWidth(final int width) { 73 | // curry_2(this, width) 74 | // 75 | final FunctionWithCharAndWidth f = this; 76 | return new FunctionWithChar() { 77 | @Override 78 | public Collection apply(Character character, Collection cell) { 79 | return f.apply(character, width, cell); 80 | } 81 | }; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithCharAndWidthAndHeight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.Collection; 11 | 12 | public abstract class FunctionWithCharAndWidthAndHeight 13 | { 14 | public abstract Collection apply(Character character, Integer width, Integer height, Collection cell); 15 | 16 | public static final FunctionWithCharAndWidthAndHeight IDENTITY = new FunctionWithCharAndWidthAndHeight() { 17 | @Override 18 | public FunctionWithWidthAndHeight withChar(char _1) { return FunctionWithWidthAndHeight.IDENTITY; } 19 | @Override 20 | public FunctionWithCharAndHeight withWidth(int _1) { 21 | return FunctionWithCharAndHeight.IDENTITY; 22 | } 23 | @Override 24 | public FunctionWithCharAndWidth withHeight(int _1) { 25 | return FunctionWithCharAndWidth.IDENTITY; 26 | } 27 | @Override 28 | public Collection apply(Character _1, Integer _2, Integer _3, Collection cell) { return cell; } 29 | }; 30 | 31 | public FunctionWithWidthAndHeight withChar(final char character) { 32 | // curry(this, character) 33 | // 34 | final FunctionWithCharAndWidthAndHeight f = this; 35 | return new FunctionWithWidthAndHeight() { 36 | @Override 37 | public Collection apply(Integer width, Integer height, Collection cell) { 38 | return f.apply(character, width, height, cell); 39 | } 40 | }; 41 | } 42 | 43 | public FunctionWithCharAndHeight withWidth (final int width) { 44 | // curry_2(this, width) 45 | // 46 | final FunctionWithCharAndWidthAndHeight f = this; 47 | return new FunctionWithCharAndHeight() { 48 | @Override 49 | public Collection apply(Character character, Integer height, Collection cell) { 50 | return f.apply(character, width, height, cell); 51 | } 52 | }; 53 | } 54 | 55 | public FunctionWithCharAndWidth withHeight(final int height) { 56 | // curry_3(this, height) 57 | // 58 | final FunctionWithCharAndWidthAndHeight f = this; 59 | return new FunctionWithCharAndWidth() { 60 | @Override 61 | public Collection apply(Character character, Integer width, Collection cell) { 62 | return f.apply(character, width, height, cell); 63 | } 64 | }; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithHeight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.Collection; 11 | 12 | public abstract class FunctionWithHeight 13 | { 14 | public abstract Collection apply(Integer height, Collection cell); 15 | 16 | public static final FunctionWithHeight IDENTITY = new FunctionWithHeight() { 17 | @Override 18 | public Function withHeight(int _1) { 19 | return Function.IDENTITY; 20 | } 21 | @Override 22 | public Collection apply(Integer _1, Collection cell) { 23 | return cell; 24 | } 25 | }; 26 | 27 | public Function withHeight(final int height) { 28 | // curry(this, height) 29 | // 30 | final FunctionWithHeight f = this; 31 | return new Function() { 32 | @Override 33 | public Collection apply(Collection cell) { 34 | return f.apply(height, cell); 35 | } 36 | }; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithWidth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.Collections; 13 | import java.util.List; 14 | 15 | public abstract class FunctionWithWidth 16 | { 17 | public abstract Collection apply(Integer width, Collection cell); 18 | 19 | public static final FunctionWithWidth IDENTITY = new FunctionWithWidth() { 20 | @Override 21 | public Function withWidth(int _1) { 22 | return Function.IDENTITY; 23 | } 24 | @Override 25 | public Collection apply(Integer height, Collection cell) { 26 | return cell; 27 | } 28 | }; 29 | 30 | /* 31 | * From line.FunctionWithWidth 32 | */ 33 | public static FunctionWithWidth from(final com.inamik.text.tables.line.base.FunctionWithWidth f) { 34 | return new FunctionWithWidth() { 35 | @Override 36 | public Function withWidth(int width) { 37 | // lift(curry(f, width)) 38 | // 39 | return Function.from(f.withWidth(width)); 40 | } 41 | @Override 42 | public Collection apply(Integer width, Collection cell) { 43 | // map(cell, f) 44 | // 45 | final List r = new ArrayList(cell.size()); 46 | for (String line: cell) { r.add(f.apply(width, line)); } 47 | return Collections.unmodifiableCollection(r); 48 | } 49 | }; 50 | } 51 | 52 | public Function withWidth(final int width) { 53 | // curry(this, width) 54 | // 55 | final FunctionWithWidth f = this; 56 | return new Function() { 57 | @Override 58 | public Collection apply(Collection cell) { 59 | return f.apply(width, cell); 60 | } 61 | }; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/cell/base/FunctionWithWidthAndHeight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.cell.base; 9 | 10 | import java.util.Collection; 11 | 12 | public abstract class FunctionWithWidthAndHeight 13 | { 14 | public abstract Collection apply(Integer width, Integer height, Collection cell); 15 | 16 | public static final FunctionWithWidthAndHeight IDENTITY = new FunctionWithWidthAndHeight() { 17 | @Override 18 | public FunctionWithHeight withWidth(int _1) { 19 | return FunctionWithHeight.IDENTITY; 20 | } 21 | @Override 22 | public FunctionWithWidth withHeight(int _1) { 23 | return FunctionWithWidth.IDENTITY; 24 | } 25 | @Override 26 | public Collection apply(Integer _1, Integer _2, Collection cell) { return cell; } 27 | }; 28 | 29 | public FunctionWithHeight withWidth (final int width) { 30 | // curry(this, width) 31 | // 32 | final FunctionWithWidthAndHeight f = this; 33 | return new FunctionWithHeight() { 34 | @Override 35 | public Collection apply(Integer height, Collection cell) { 36 | return f.apply(width, height, cell); 37 | } 38 | }; 39 | } 40 | 41 | public FunctionWithWidth withHeight(final int height) { 42 | // curry_2(this, height) 43 | // 44 | final FunctionWithWidthAndHeight f = this; 45 | return new FunctionWithWidth() { 46 | @Override 47 | public Collection apply(Integer width, Collection cell) { 48 | return f.apply(width, height, cell); 49 | } 50 | }; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/grid/Border.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.grid; 9 | 10 | import com.inamik.text.tables.Cell; 11 | import com.inamik.text.tables.GridTable; 12 | 13 | import java.util.ArrayList; 14 | import java.util.Collection; 15 | import java.util.List; 16 | 17 | public final class Border 18 | { 19 | 20 | public static final Border DOUBLE_LINE = of(Chars.DOUBLE_LINE); 21 | public static final Border SINGLE_LINE = of(Chars.SINGLE_LINE); 22 | 23 | private final Chars chars; 24 | 25 | public static Border of(Chars chars) { return new Border(chars); } 26 | 27 | public Border(Chars chars) { this.chars = chars; } 28 | 29 | public GridTable apply(GridTable grid) { 30 | final int gr = grid.numRows(); 31 | final int gc = grid.numCols(); 32 | 33 | GridTable b = GridTable.of((gr * 2) + 1, (gc * 2) + 1); 34 | 35 | // Copy source grid first to compute cell maximums 36 | // 37 | for (int r = 0; r < gr; r++) { 38 | for (int c = 0; c < gc; c++) { 39 | b.put((r * 2) + 1, (c * 2) + 1,grid.cell(r,c)); 40 | } 41 | } 42 | 43 | // 44 | // Top Row 45 | // 46 | int r = 0; 47 | int c = 0; 48 | 49 | // Top-Left Corner 50 | // 51 | b.put(r, c, Cell.of(String.valueOf(chars.topLeft))); 52 | c++; 53 | // Top-Horizontals and Intersects 54 | // 55 | for (int h = 0; h < gc; h++) { 56 | // Horizontal-Fill 57 | // 58 | b.put(r, c, hline(grid.colWidth(h))); 59 | c++; 60 | // Top-Intersect 61 | // 62 | if (h < gc -1) { 63 | b.put(r, c, Cell.of(String.valueOf(chars.topIntersect))); 64 | c++; 65 | } 66 | } 67 | // Top-Right Corner 68 | // 69 | b.put(r, c, Cell.of(String.valueOf(chars.topRight))); 70 | c++; 71 | 72 | // 73 | // Middle Rows 74 | // 75 | 76 | for (int v = 0; v < gr; v++) { 77 | // 78 | // Cell-Line 79 | // 80 | 81 | r++; 82 | c = 0; 83 | // Vertical-Fill 84 | // 85 | b.put(r, c, vline(grid.rowHeight(v))); 86 | c++; 87 | for (int h = 0; h < gc; h++) { 88 | // Skip previously-populated data cell 89 | // 90 | c++; 91 | // Vertical-Fill 92 | // 93 | if (h < gc - 1) { 94 | b.put(r, c, vline(grid.rowHeight(v))); 95 | c++; 96 | } 97 | } 98 | // Vertical-Fill 99 | // 100 | b.put(r, c, vline(grid.rowHeight(v))); 101 | c++; 102 | 103 | if (v < gr - 1) { 104 | // 105 | // Border-Line 106 | // 107 | 108 | r++; 109 | c = 0; 110 | // Left Intersect 111 | // 112 | b.put(r, c, Cell.of(String.valueOf(chars.LeftIntersect))); 113 | c++; 114 | for (int h = 0; h < gc; h++) { 115 | // Horizontal-Fill 116 | // 117 | b.put(r, c, hline(grid.colWidth(h))); 118 | c++; 119 | // Intersect 120 | // 121 | if (h < gc - 1) { 122 | b.put(r, c, Cell.of(String.valueOf(chars.intersect))); 123 | c++; 124 | } 125 | } 126 | // Right-Intersect 127 | // 128 | b.put(r, c, Cell.of(String.valueOf(chars.RightIntersect))); 129 | c++; 130 | } 131 | } 132 | 133 | // 134 | // Bottom row 135 | // 136 | 137 | // Bottom-Left Corner 138 | // 139 | r++; 140 | c = 0; 141 | b.put(r, c, Cell.of(String.valueOf(chars.bottomLeft))); 142 | c++; 143 | // Bottom-Horizontals and Intersects 144 | // 145 | for (int h = 0; h < gc; h++) { 146 | // Horizontal-Fill 147 | // 148 | b.put(r, c, hline(grid.colWidth(h))); 149 | c++; 150 | // Bottom-Intersect 151 | // 152 | if (h < gc - 1) { 153 | b.put(r, c, Cell.of(String.valueOf(chars.bottomIntersect))); 154 | c++; 155 | } 156 | } 157 | // Bottom-Right Corner 158 | // 159 | b.put(r, c, Cell.of(String.valueOf(chars.bottomRight))); 160 | c++; 161 | 162 | return b; 163 | } 164 | 165 | private Collection hline(int width) { 166 | StringBuilder sb = new StringBuilder(width); 167 | while (sb.length() < width) { 168 | sb.append(chars.horizontal); 169 | } 170 | return Cell.of(sb.toString()); 171 | } 172 | 173 | private Collection vline(int height) { 174 | List newLines = new ArrayList(height); 175 | final String line = Character.toString(chars.vertical); 176 | while (newLines.size() < height) { 177 | newLines.add(line); 178 | } 179 | return newLines; 180 | } 181 | 182 | /* 183 | * Chars 184 | */ 185 | public static class Chars 186 | { 187 | public static final Chars DOUBLE_LINE = new Chars('╬', '═', '║', '╔', '╦', '╗', '╠', '╣', '╚', '╩', '╝'); 188 | public static final Chars SINGLE_LINE = new Chars('┼', '─', '│', '┌', '┬', '┐', '├', '┤', '└', '┴', '┘'); 189 | 190 | public final char intersect; 191 | public final char horizontal; 192 | public final char vertical; 193 | public final char topLeft; 194 | public final char topIntersect; 195 | public final char topRight; 196 | public final char LeftIntersect; 197 | public final char RightIntersect; 198 | public final char bottomLeft; 199 | public final char bottomIntersect; 200 | public final char bottomRight; 201 | 202 | // * 203 | public static Chars of(char intersect) { 204 | return new Chars(intersect,intersect,intersect,intersect,intersect,intersect,intersect,intersect,intersect,intersect,intersect); 205 | } 206 | 207 | // +-| 208 | public static Chars of(char intersect, char horizontal, char vertical) { 209 | return new Chars(intersect, horizontal, vertical, intersect, intersect, intersect, intersect, intersect, intersect, intersect, intersect); 210 | } 211 | 212 | public Chars(char i, char h, char v, char tl, char ti, char tr, char li, char ri, char bl, char bi, char br) { 213 | this.intersect = i; 214 | this.horizontal = h; 215 | this.vertical = v; 216 | this.topLeft = tl; 217 | this.topIntersect = ti; 218 | this.topRight = tr; 219 | this.LeftIntersect = li; 220 | this.RightIntersect = ri; 221 | this.bottomLeft = bl; 222 | this.bottomIntersect = bi; 223 | this.bottomRight = br; 224 | } 225 | } 226 | 227 | } 228 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/grid/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.grid; 9 | 10 | import com.inamik.text.tables.Cell; 11 | import com.inamik.text.tables.GridTable; 12 | 13 | import java.io.OutputStream; 14 | import java.io.PrintWriter; 15 | import java.io.StringWriter; 16 | import java.io.Writer; 17 | 18 | public final class Util 19 | { 20 | public static void print(GridTable g) { 21 | print(g, System.out); 22 | } 23 | 24 | public static void print(GridTable g, OutputStream out) { 25 | print(g, new PrintWriter(out)); 26 | } 27 | 28 | public static void print(GridTable g, Writer out) { 29 | print(g, new PrintWriter(out)); 30 | } 31 | 32 | public static void print(GridTable g, PrintWriter out) { 33 | // Apply final padding to ensure grid prints properly 34 | // 35 | g = g 36 | .apply(Cell.Functions.TOP_ALIGN) 37 | .apply(Cell.Functions.LEFT_ALIGN) 38 | ; 39 | 40 | // Convert the grid to a cell 41 | // then iterate over the lines and print 42 | // 43 | for (String line: g.toCell()) { 44 | out.println(line); 45 | } 46 | } 47 | 48 | public static String asString(GridTable g) { 49 | StringWriter out = new StringWriter(); 50 | print(g, out); 51 | return out.toString(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/HorizontalCenter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithCharAndWidth; 11 | 12 | public final class HorizontalCenter extends FunctionWithCharAndWidth 13 | { 14 | public static final HorizontalCenter INSTANCE = new HorizontalCenter(); 15 | 16 | @Override 17 | public String apply(Character fill, Integer width, String line) { 18 | // Need to truncate? 19 | // 20 | if (line.length() > width) { 21 | int over = line.length() - width; 22 | int carry = over % 2; 23 | int half = (over - carry) / 2; 24 | line = RightTruncate.INSTANCE.apply(line.length() + half + carry, line); 25 | line = LeftTruncate .INSTANCE.apply(line.length() + half , line); 26 | } 27 | else { 28 | // Need to pad? 29 | // 30 | if (line.length() < width) { 31 | int pad = width - line.length(); 32 | int carry = pad % 2; 33 | int half = (pad - carry) / 2; 34 | line = RightPad.INSTANCE.apply(fill, line.length() + half + carry, line); 35 | line = LeftPad .INSTANCE.apply(fill, line.length() + half , line); 36 | } 37 | } 38 | return line; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/LeftAlign.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithCharAndWidth; 11 | 12 | public final class LeftAlign extends FunctionWithCharAndWidth 13 | { 14 | public static final LeftAlign INSTANCE = new LeftAlign(); 15 | 16 | @Override 17 | public String apply(Character fill, Integer width, String line) { 18 | line = RightTruncate.INSTANCE.apply(width, line); 19 | line = RightPad .INSTANCE.apply(fill, width, line); 20 | return line; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/LeftPad.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithCharAndWidth; 11 | 12 | public final class LeftPad extends FunctionWithCharAndWidth 13 | { 14 | public static final LeftPad INSTANCE = new LeftPad(); 15 | 16 | @Override 17 | public String apply(Character fill, Integer width, String line) { 18 | if (line.length() >= width) { 19 | return line; 20 | } 21 | StringBuilder sb = new StringBuilder(width); 22 | while (sb.length() + line.length() < width) { 23 | sb.append(fill); 24 | } 25 | sb.append(line); 26 | return sb.toString(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/LeftTruncate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithWidth; 11 | 12 | public final class LeftTruncate extends FunctionWithWidth 13 | { 14 | public static final LeftTruncate INSTANCE = new LeftTruncate(); 15 | 16 | @Override 17 | public String apply(Integer width, String line) { 18 | if (line.length() > width) { 19 | return line.substring(line.length() - width); 20 | } 21 | return line; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/RightAlign.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithCharAndWidth; 11 | 12 | public final class RightAlign extends FunctionWithCharAndWidth 13 | { 14 | public static final RightAlign INSTANCE = new RightAlign(); 15 | 16 | @Override 17 | public String apply(Character fill, Integer width, String line) { 18 | line = LeftTruncate.INSTANCE.apply(width, line); 19 | line = LeftPad .INSTANCE.apply(fill, width, line); 20 | return line; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/RightPad.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithCharAndWidth; 11 | 12 | public final class RightPad extends FunctionWithCharAndWidth 13 | { 14 | public static final RightPad INSTANCE = new RightPad(); 15 | 16 | @Override 17 | public String apply(Character fill, Integer width, String line) { 18 | if (line.length() >= width) { 19 | return line; 20 | } 21 | StringBuilder sb = new StringBuilder(width); 22 | sb.append(line); 23 | while (sb.length() < width) { 24 | sb.append(fill); 25 | } 26 | return sb.toString(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/RightTruncate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line; 9 | 10 | import com.inamik.text.tables.line.base.FunctionWithWidth; 11 | 12 | public final class RightTruncate extends FunctionWithWidth 13 | { 14 | public static final RightTruncate INSTANCE = new RightTruncate(); 15 | 16 | @Override 17 | public String apply(Integer width, String line) { 18 | if (line.length() > width) { 19 | return line.substring(0, width); 20 | } 21 | return line; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/base/Function.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line.base; 9 | 10 | public abstract class Function 11 | { 12 | public abstract String apply(String line); 13 | 14 | public static final Function IDENTITY = new Function() { 15 | @Override 16 | public String apply(String line) { 17 | return line; 18 | } 19 | }; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/base/FunctionWithChar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line.base; 9 | 10 | public abstract class FunctionWithChar extends Function 11 | { 12 | public abstract String apply(Character character, String line); 13 | 14 | public static final FunctionWithChar IDENTITY = new FunctionWithChar() { 15 | @Override 16 | public Function withChar(char _1) { 17 | return Function.IDENTITY; 18 | } 19 | @Override 20 | public String apply(Character _1, String line) { return line; } 21 | }; 22 | 23 | public Function withChar(final char character) { 24 | // curry(this, character) 25 | // 26 | final FunctionWithChar f = this; 27 | return new Function() { 28 | @Override 29 | public String apply(String line) { 30 | return f.apply(character, line); 31 | } 32 | }; 33 | } 34 | 35 | /* 36 | * Apply with ' ' 37 | */ 38 | @Override 39 | public String apply(String line) { return apply(' ', line); } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/base/FunctionWithCharAndWidth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line.base; 9 | 10 | public abstract class FunctionWithCharAndWidth extends FunctionWithWidth 11 | { 12 | public abstract String apply(Character character, Integer width, String line); 13 | 14 | public static final FunctionWithCharAndWidth IDENTITY = new FunctionWithCharAndWidth() { 15 | @Override 16 | public FunctionWithWidth withChar(char _1) { 17 | return FunctionWithWidth.IDENTITY; 18 | } 19 | @Override 20 | public FunctionWithChar withWidth(int _1) { 21 | return FunctionWithChar.IDENTITY; 22 | } 23 | @Override 24 | public String apply(Character _1, Integer _2, String line) { return line; } 25 | }; 26 | 27 | public FunctionWithWidth withChar(final char character) { 28 | // curry(this, character) 29 | // 30 | final FunctionWithCharAndWidth f = this; 31 | return new FunctionWithWidth() { 32 | @Override 33 | public String apply(Integer width, String line) { 34 | return f.apply(character, width, line); 35 | } 36 | }; 37 | } 38 | 39 | public FunctionWithChar withWidth(final int width) { 40 | // curry_2(this, width) 41 | // 42 | final FunctionWithCharAndWidth f = this; 43 | return new FunctionWithChar() { 44 | @Override 45 | public String apply(Character character, String line) { 46 | return f.apply(character, width, line); 47 | } 48 | }; 49 | } 50 | 51 | /* 52 | * Apply with ' ' 53 | */ 54 | @Override 55 | public String apply(Integer width, String line) { return apply(' ', width, line); } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/inamik/text/tables/line/base/FunctionWithWidth.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables.line.base; 9 | 10 | public abstract class FunctionWithWidth 11 | { 12 | public abstract String apply(Integer width, String line); 13 | 14 | public static final FunctionWithWidth IDENTITY = new FunctionWithWidth() { 15 | @Override 16 | public Function withWidth(int _1) { 17 | return Function.IDENTITY; 18 | } 19 | @Override 20 | public String apply(Integer _1, String line) { return line; } 21 | }; 22 | 23 | public Function withWidth(final int width) { 24 | // curry(this, width) 25 | // 26 | final FunctionWithWidth f = this; 27 | return new Function() { 28 | @Override 29 | public String apply(String line) { 30 | return f.apply(width, line); 31 | } 32 | }; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/com/inamik/text/tables/GridTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables; 9 | 10 | import com.inamik.text.tables.grid.Border; 11 | import org.junit.Assert; 12 | import org.junit.Test; 13 | 14 | import static com.inamik.text.tables.Cell.Functions.*; 15 | 16 | public class GridTableTest 17 | { 18 | private static final String[] FULL_TABLE = { 19 | "╔══════════╦══════════╦══════════╗", 20 | "║Left^^^^^^║ Center ║ Right║", 21 | "║Top^^^^^^^║ Top ║ Top║", 22 | "║^^^^^^^^^^║ ║ ║", 23 | "║^^^^^^^^^^║ ║ ║", 24 | "║^^^^^^^^^^║ ║ ║", 25 | "║^^^^^^^^^^║ ║ ║", 26 | "╠══════════╬══════════╬══════════╣", 27 | "║ ║..........║ ║", 28 | "║ ║..........║ ║", 29 | "║Left ║..Center..║ Right║", 30 | "║Center ║..Center..║ Center║", 31 | "║ ║..........║ ║", 32 | "║ ║..........║ ║", 33 | "╠══════════╬══════════╬══════════╣", 34 | "║ ║ ║__________║", 35 | "║ ║ ║__________║", 36 | "║ ║ ║__________║", 37 | "║ ║ ║__________║", 38 | "║Left ║ Center ║_____Right║", 39 | "║Bottom ║ Bottom ║____Bottom║", 40 | "╚══════════╩══════════╩══════════╝", 41 | }; 42 | 43 | @Test 44 | public void testFullTable() { 45 | final int width = 10; 46 | final int height = 6; 47 | 48 | // Build grid table 49 | // Each cell will be $width chars x $height chars 50 | // 51 | // NOTE: Apply vertical alignment FIRST ! 52 | // 53 | GridTable g = GridTable.of(3, 3) 54 | .put(0, 0, Cell.of("Left" , "Top" )) 55 | .put(0, 1, Cell.of("Center", "Top" )) 56 | .put(0, 2, Cell.of("Right" , "Top" )) 57 | 58 | .put(1, 0, Cell.of("Left" , "Center")) 59 | .put(1, 1, Cell.of("Center", "Center")) 60 | .put(1, 2, Cell.of("Right" , "Center")) 61 | 62 | .put(2, 0, Cell.of("Left" , "Bottom")) 63 | .put(2, 1, Cell.of("Center", "Bottom")) 64 | .put(2, 2, Cell.of("Right" , "Bottom")) 65 | 66 | .applyToRow(0, TOP_ALIGN .withHeight(height)) 67 | .applyToRow(1, VERTICAL_CENTER.withHeight(height)) 68 | .applyToRow(2, BOTTOM_ALIGN .withHeight(height)) 69 | 70 | .apply(0, 0, LEFT_ALIGN.withWidth(width).withChar('^')) 71 | .apply(1, 0, LEFT_ALIGN) 72 | .apply(2, 0, LEFT_ALIGN) 73 | 74 | .apply(0, 1, HORIZONTAL_CENTER.withWidth(width)) 75 | .apply(1, 1, HORIZONTAL_CENTER.withChar('.')) 76 | .apply(2, 1, HORIZONTAL_CENTER) 77 | 78 | .apply(0, 2, RIGHT_ALIGN.withWidth(width)) 79 | .apply(1, 2, RIGHT_ALIGN) 80 | .apply(2, 2, RIGHT_ALIGN.withChar('_')) 81 | ; 82 | 83 | Assert.assertEquals(g.numRows(), 3); 84 | Assert.assertEquals(g.numCols(), 3); 85 | Assert.assertEquals(g.width() , 30); 86 | Assert.assertEquals(g.height() , 18); 87 | 88 | // Add border 89 | // 90 | g = Border.DOUBLE_LINE.apply(g); 91 | 92 | Assert.assertEquals(g.numRows(), 7); 93 | Assert.assertEquals(g.numCols(), 7); 94 | Assert.assertEquals(g.width() , 34); 95 | Assert.assertEquals(g.height() , 22); 96 | 97 | Assert.assertArrayEquals(FULL_TABLE, g.toCell().toArray()); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/test/java/com/inamik/text/tables/SimpleTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * iNamik Text Tables for Java 3 | * 4 | * Copyright (C) 2016 David Farrell (DavidPFarrell@yahoo.com) 5 | * 6 | * Licensed under The MIT License (MIT), see LICENSE.txt 7 | */ 8 | package com.inamik.text.tables; 9 | 10 | import com.inamik.text.tables.grid.Border; 11 | import org.junit.Assert; 12 | import org.junit.Test; 13 | 14 | import static com.inamik.text.tables.Cell.Functions.*; 15 | 16 | public class SimpleTableTest 17 | { 18 | private static final String[] FULL_TABLE = { 19 | "┌──────────┬──────────┬──────────┐", 20 | "│Left^^^^^^│ Center │ Right│", 21 | "│Top^^^^^^^│ Top │ Top│", 22 | "│^^^^^^^^^^│ │ │", 23 | "│^^^^^^^^^^│ │ │", 24 | "│^^^^^^^^^^│ │ │", 25 | "│^^^^^^^^^^│ │ │", 26 | "├──────────┼──────────┼──────────┤", 27 | "│ │..........│ │", 28 | "│ │..........│ │", 29 | "│Left │..Center..│ Right│", 30 | "│Center │..Center..│ Center│", 31 | "│ │..........│ │", 32 | "│ │..........│ │", 33 | "├──────────┼──────────┼──────────┤", 34 | "│ │ │__________│", 35 | "│ │ │__________│", 36 | "│ │ │__________│", 37 | "│ │ │__________│", 38 | "│Left │ Center │_____Right│", 39 | "│Bottom │ Bottom │____Bottom│", 40 | "└──────────┴──────────┴──────────┘", 41 | }; 42 | 43 | @Test 44 | public void testFullTable() { 45 | final int width = 10; 46 | final int height = 6; 47 | 48 | // Build simple table 49 | // Each cell will be $width chars x $height chars 50 | // 51 | // NOTE: Apply vertical alignment FIRST ! 52 | // 53 | SimpleTable s = SimpleTable.of() 54 | .nextRow() 55 | .nextCell() 56 | .addLine("Left") 57 | .addLine("Top") 58 | .applyToCell(TOP_ALIGN .withHeight(height)) 59 | .applyToCell(LEFT_ALIGN.withWidth (width ).withChar('^')) 60 | .nextCell() 61 | .addLine("Center") 62 | .addLine("Top") 63 | .applyToCell(TOP_ALIGN .withHeight(height)) 64 | .applyToCell(HORIZONTAL_CENTER.withWidth (width )) 65 | .nextCell() 66 | .addLine("Right") 67 | .addLine("Top") 68 | .applyToCell(TOP_ALIGN .withHeight(height)) 69 | .applyToCell(RIGHT_ALIGN.withWidth (width )) 70 | .nextRow() 71 | .nextCell() 72 | .addLine("Left") 73 | .addLine("Center") 74 | .applyToCell(VERTICAL_CENTER.withHeight(height)) 75 | .applyToCell(LEFT_ALIGN .withWidth (width )) 76 | .nextCell() 77 | .addLine("Center") 78 | .addLine("Center") 79 | .applyToCell(VERTICAL_CENTER .withHeight(height)) 80 | .applyToCell(HORIZONTAL_CENTER.withWidth (width ).withChar('.')) 81 | .nextCell() 82 | .addLine("Right") 83 | .addLine("Center") 84 | .applyToCell(VERTICAL_CENTER.withHeight(height)) 85 | .applyToCell(RIGHT_ALIGN .withWidth (width )) 86 | .nextRow() 87 | .nextCell() 88 | .addLine("Left") 89 | .addLine("Bottom") 90 | .applyToCell(BOTTOM_ALIGN.withHeight(height)) 91 | .applyToCell(LEFT_ALIGN .withWidth (width )) 92 | .nextCell() 93 | .addLine("Center") 94 | .addLine("Bottom") 95 | .applyToCell(BOTTOM_ALIGN .withHeight(height)) 96 | .applyToCell(HORIZONTAL_CENTER.withWidth (width )) 97 | .nextCell() 98 | .addLine("Right") 99 | .addLine("Bottom") 100 | .applyToCell(BOTTOM_ALIGN.withHeight(height)) 101 | .applyToCell(RIGHT_ALIGN .withWidth (width ).withChar('_')) 102 | ; 103 | 104 | Assert.assertEquals(s.numRows(), 3); 105 | Assert.assertEquals(s.numCols(), 3); 106 | 107 | // Convert to grid 108 | // 109 | GridTable g = s.toGrid(); 110 | 111 | Assert.assertEquals(g.numRows(), 3); 112 | Assert.assertEquals(g.numCols(), 3); 113 | Assert.assertEquals(g.width() , 30); 114 | Assert.assertEquals(g.height() , 18); 115 | 116 | // Add border 117 | // 118 | g = Border.SINGLE_LINE.apply(g); 119 | 120 | Assert.assertEquals(g.numRows(), 7); 121 | Assert.assertEquals(g.numCols(), 7); 122 | Assert.assertEquals(g.width() , 34); 123 | Assert.assertEquals(g.height() , 22); 124 | 125 | Assert.assertArrayEquals(FULL_TABLE, g.toCell().toArray()); 126 | 127 | } 128 | 129 | } 130 | --------------------------------------------------------------------------------