J’ai ouvert un nouveau projet sur SourceForge qui s’appelle « Ascii Art for Java » et est disponible en ligne sur https://sourceforge.net/projects/asciiart/ pour les sources (Mercurial) et les binaires (jar). Si vous utilisez Maven, il suffit d’ajouter la dépendance suivante dans votre projet:
<dependency>
<groupId>org.alcibiade</groupId>
<artifactId>asciiart-core</artifactId>
<version>0.2.0</version>
</dependency>
Ce projet est un portage de tout le code de gestion de flux ASCII réalisé dans le cadre d’un autre projet et packagé sous forme autonome.
Le projet permet:
- La construction de documents ASCII structurés (tableaux, mises en formes, …);
- La sortie directe de collections et de maps vers des logs JCL ou SLF4j sous forme de tables avec gestion des ruptures de lignes;
- La conversion d’images en ASCII;
- D’autres fonctions viendront dans les releases suivantes…

Il y a trois modules:
- asciiart-core: Le système de rendu (widgets, containers, rasters, …)
- asciiart-jcl: Un wrapper pour sortir directement des données ASCII vers un log Apache commons-logging (dépend de asciiart-core)
- asciiart-slf4j: Un wrapper pour SLF4j (dépend de asciiart-core)
Des exemples valent mieux que de longs discours, pour les questions envoyez moi des mails…
Utilisation d’asciiart-core seul
+--------+ | Fruit | +--------+ | Orange | | Apple | | Lemon | +--------+
Source code:
List<String> items = new ArrayList<String>();
items.add("Orange");
items.add("Apple");
items.add("Lemon");
TableModel tableModel = new TableModelCollectionAdapter(items, "Fruit");
TableWidget tableWidget = new TableWidget(tableModel);
CharacterRaster raster = new ExtensibleCharacterRaster(' ');
tableWidget.render(new RasterContext(raster));
System.out.println(raster);
(Notez ci-dessous l’alignement implicite sur détection de type numérique dans les valeurs)
+-----------+-----------+ | City | Value | +-----------+-----------+ | Amsterdam | 3.1415 | | London | 2012.0 | | Paris | 42.0 | +-----------+-----------+
Source code:
Map<String, Double> items = new TreeMap<String, Double>();
items.put("Paris", 42.);
items.put("London", 2012.);
items.put("Amsterdam", 3.1415);
TableModel tableModel = new TableModelMapAdapter(items, "City", "Value");
TableWidget tableWidget = new TableWidget(tableModel);
CharacterRaster raster = new ExtensibleCharacterRaster(' ');
tableWidget.render(new RasterContext(raster));
System.out.println(raster);
+----------+----------+----------+----------+ | Column 0 | Column 1 | Column 2 | Column 3 | +----------+----------+----------+----------+ | 00:00 | 01:00 | 02:00 | 03:00 | | 00:01 | 01:01 | 02:01 | 03:01 | | 00:02 | 01:02 | 02:02 | 03:02 | | 00:03 | 01:03 | 02:03 | 03:03 | | 00:04 | 01:04 | 02:04 | 03:04 | | 00:05 | 01:05 | 02:05 | 03:05 | +----------+----------+----------+----------+
Source code:
TableWidget tableWidget = new TableWidget(new CustomTableModelImpl());
CharacterRaster raster = new ExtensibleCharacterRaster(' ');
tableWidget.render(new RasterContext(raster));
System.out.println(raster);
class CustomTableModelImpl extends AbstractTableModel {
@Override
public int getWidth() {
return 4;
}
@Override
public int getHeight() {
return 6;
}
@Override
public String getCellContent(int x, int y) {
return String.format("%02d:%02d", x, y);
}
@Override
public String getColumnTitle(int x) {
return "Column " + x;
}
}
_______,,__
__ggggggggg@NNNNNMMPPMNNNg,_
_gNP^` ````_ `*NNg,
_g@NP^,' _#` *NNg_
_gP%P _p` N_ ^MNg,_
_gN`__,gNL _____ggNg _ *qgg__ *NNg_
____,gpNNP #N^NTMNNP*JNP*^*Ngg____gL___ ^Np>- `*Nq@NNg__
N@**^__JNNg_ NZg#* ^NNNNNNNE^Npg__ _` `^*MNNN@gggg______
*N@NNMP5gNP5gNNg@NNN@ggg_ gNNNNgJhN&#_gNPP^ Ng_ `^^*PNNNNNNNN@gp
*NqggP`_dNN{NNNNNNNNNNN ^^^NNNNNggNP^ q_ ^Ng__ ____, ,NNP
gNP_N' ^*NNNNNN*` ^NNNNF Ng,_ ^MNgggg@NNNNFg@NP
%P gP ^NNNNNN^ 'NNk^ NL` ,..wwWNMP**`gNNF
_NN K _NF JN^k _gN ,,ggggpppqNNNNNP`
NNL Ny __ggNNNgg_ ,_NNB ,@P5- NNF
_NNL^NkggP*`NNNNNNNNg,_ ,_^NNB^ _gNM^,+ gNF
T`{Nk ^Nk gNNNNNNNNPNNg__^NNk^ _gNNgM^,
Source code:
File imageFile = new File(args[0]);
int columns = Integer.parseInt(args[1]);
BufferedImage image = ImageIO.read(imageFile);
int rows = columns * image.getHeight() / image.getWidth() / 2;
CharacterRaster raster = new ExtensibleCharacterRaster();
ImageRasterizer.rasterize(image, new RasterContext(raster),
new TextBoxSize(columns, rows));
System.out.print(raster.toString());
Utilisation d’asciiart-slf4j ou asciiart-jcl
22:34:55.331 [main] INFO org.alcibiade.asciiarttest.App - Here is a basic log line 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - +--------+ 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - | Fruits | 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - +--------+ 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - | Orange | 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - | Apple | 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - | Lemon | 22:34:55.348 [main] INFO org.alcibiade.asciiarttest.App - +--------+
Source code:
List<String> items = new ArrayList<String>();
items.add("Orange");
items.add("Apple");
items.add("Lemon");
AsciiArtLogger logger = new AsciiArtLogger(LoggerFactory.getLogger(App.class));
logger.info("Here is a basic log line");
logger.info(items, "Fruits");









