L'objectiu d'aquest CodeLab és aprendre el mètodes que ofereix JAVA per a la formatació de text.

Veurem com podem controlar l'espai que ocupa un valor quan s'imprimeix, els digits que ha d'ocupar, i per últim el color que ha de tenir.

Desenvoluparem una petita aplicació per a generar tíquets d'una botiga.

Inicia IntelliJ i crea un nou projecte anomenat Formatting.

Els mètodes System.out.printf i System.out.format són equivalents entre sí.

Aquests mètodes permeten especificar el format que ha de tenir un text.

Entre els aspectes més importants de la formatació trobem, l'espaiat, l'alineació i el nombre de decimals.

Vegem un exemple:

public class Main {

   public static void main(String[] args) {

       String text = "hello";
       int numero = 1234;
       float decimal = 56.789f;

       System.out.format("%10s", text);
       System.out.format("%10d", numero);
       System.out.format("%10f", decimal);

       System.out.println(); System.out.println();

       System.out.format("%-10s", text);
       System.out.format("%-10d", numero);
       System.out.format("%-10f", decimal);

       System.out.println(); System.out.println();

       System.out.format("%-10.2f%10.2f", decimal, decimal);
   }
}

Observa com s'ha formatat el text de sortida:

     hello      1234 56,789001

hello     1234      56,789001 

56,79          56,79

El significat dels especificadors és el següent:

%10s

String amb una amplada de 10 caracters

%10d

Enter amb una amplada de 10 caracters

%10f

Float amb una amplada de 10 caracters

%-10s

String amb una amplada de 10 caracters, aliniat a l'esquerra

%-10d

Enter amb una amplada de 10 caracters, aliniat a l'esquerra

%-10f

Float amb una amplada de 10 caracters, aliniat a l'esquerra

%-10.2f

Float amb una amplada de 10 caracters, aliniat a l'esquerra, i amb dos decimals

%10.2f

Float amb una amplada de 10 caracters, amb dos decimals

Podem generalitzar els especificadors així:

% alineació amplada decimals tipus

Combinar text i format

Dintre de la cadena de format podem posar-hi també altres caracters que desitjem que es mostrin:

System.out.format("|%-10s|%10d|%10.2f|", text, enter, decimal);

Un truc interessant és utilitzar el format per a repetir espais en blanc:

System.out.format("hola%10smon","");

String.format()

El mètode format de la classe String, es pot usar exactament igual que System.out.format.

Aquest mètode no imprimeix per pantalla el resultat de la formatació, sinò que retorna el text resultant. Aquest text el podem utilitzar com ens convingui.

String textFormatat = String.format("|%-10s|%10d|%10.2f|", text, enter, decimal);

System.out.println(textFormatat);

Similar al truc anterior, podem usar String.format juntament amb replace, per a repetir qualsevol caracter:

String guions = String.format("%50s", "").replace(" ", "-");

System.out.println(guions);

Els terminals ANSI/VT100 no solament poden mostrar text en blanc i negre; també poden mostrar colors i formats gràcies a les seqüències d'escapament.

Les seqüències d'escapament per als colors i formats tenen el aquesta sintaxi:

On {attr1};...;{attrn} són els codis dels colors o formats que desitjem.

Fem una prova:

public class Main {

   public static void main(String[] args) {
       System.out.println("\033[31mHello Red World!");
   }
}

Podem veure que la seqüencia d'escapament \033[31m inclou l'atribut 31, que correspon al codi del color de text vermell.

Una altra prova:

System.out.println("\033[31;43;1mHello Red World!");

Aquesta vegada els atributs son el 31 (color de text vermell), el 43 (color de fons groc) i l'1 (negreta).

Una última prova:

System.out.println("\033[31;43;4mHello Red World!");

Hem canviat el text en negreta per el text subratllat (atribut 4). No obstant, si executem el codi en IntelliJ, la consola no ens mostrarà el text subratllat, ja que no soporta aquesta opció. L'haurem d'executar en una consola compatible amb VT100.

Obre un terminal, i navega fins al directory de sortida del projecte:

cd IdeaProjects/ANSIColors/out/production/ANSIColors

Executa el programa:

java com.company.Main

Ara sí hauria de sortir el text subratllat...

A més a més veuras que a partir d'una seqüència d'escapament, tot el text següent manté el color i format, així que si volem tornar al color "per defecte" (blanc i negre), haurem de resetejar el color i format (attribut 0) un cop finalitzi el text que hem formatat:

System.out.println("\033[31;43;4mHello Red World!\033[0m");

Taula de codis de colors

A continuació podem veure una taula amb els tots els codis dels atributs que podem utilitzar per a canviar el format, el color de fons, i el color del text:

Format

Set

Codi

Descripció

Exemple

Previsualització

1

Bold/Bright

"Normal \033[1mBold"

Normal Bold

2

Dim

"Normal \033[2mDim"

Normal Dim

4

Underlined

"Normal \033[4mUnderlined"

Normal Underlined

5

Blink

"Normal \033[5mBlink"

Normal Blink

7

Reverse

"Normal \033[7minverted"

Normal inverted

8

Hidden

"Normal \033[8mHidden"

Normal Hidden

Reset

Codi

Descripció

Exemple

Previsualització

0

Reset all attributes

"\033[0mNormal Text"

Normal Text

21

Reset bold/bright

"Normal \033[1mBold \033[21mNormal"

Normal Bold Normal

22

Reset dim

"Normal \033[2mDim \033[22mNormal"

Normal Dim Normal

24

Reset underlined

"Normal \033[4mUnderlined \033[24mNormal"

Normal Underlined Normal

25

Reset blink

"Normal \033[5mBlink \033[25mNormal"

Normal Blink Normal

27

Reset reverse

"Normal \033[7minverted \033[27mNormal"

Normal inverted Normal

28

Reset hidden

"Normal \033[8mHidden \033[28mNormal"

Normal Hidden Normal

Color del text

Codi

Color

Exemple

Previsualització

39

Default

"Default \033[39mDefault"

Default Default

30

Black

"Default \033[30mBlack"

Default Black

31

Red

"Default \033[31mRed"

Default Red

32

Green

"Default \033[32mGreen"

Default Green

33

Yellow

"Default \033[33mYellow"

Default Yellow

34

Blue

"Default \033[34mBlue"

Default Blue

35

Magenta

"Default \033[35mMagenta"

Default Magenta

36

Cyan

"Default \033[36mCyan"

Default Cyan

37

Light gray

"Default \033[37mLight gray"

Default Light gray

90

Dark gray

"Default \033[90mDark gray"

Default Dark gray

91

Light red

"Default \033[91mLight red"

Default Light red

92

Light green

"Default \033[92mLight green"

Default Light green

93

Light yellow

"Default \033[93mLight yellow"

Default Light yellow

94

Light blue

"Default \033[94mLight blue"

Default Light blue

95

Light magenta

"Default \033[95mLight magenta"

Default Light magenta

96

Light cyan

"Default \033[96mLight cyan"

Default Light cyan

97

White

"Default \033[97mWhite"

Default White

Color del fons

Codi

Color

Exemple

Previsualització

49

Default

"Default \033[49mDefault"

Default Default

40

Black

"Default \033[40mBlack"

Default Black

41

Red

"Default \033[41mRed"

Default Red

42

Green

"Default \033[42mGreen"

Default Green

43

Yellow

"Default \033[43mYellow"

Default Yellow

44

Blue

"Default \033[44mBlue"

Default Blue

45

Magenta

"Default \033[45mMagenta"

Default Magenta

46

Cyan

"Default \033[46mCyan"

Default Cyan

47

Light gray

"Default \033[47mLight gray"

Default Light gray

100

Dark gray

"Default \033[100mDark gray"

Default Dark gray

101

Light red

"Default \033[101mLight red"

Default Light red

102

Light green

"Default \033[102mLight green"

Default Light green

103

Light yellow

"Default \033[103mLight yellow"

Default Light yellow

104

Light blue

"Default \033[104mLight blue"

Default Light blue

105

Light magenta

"Default \033[105mLight magenta"

Default Light magenta

106

Light cyan

"Default \033[106mLight cyan"

Default Light cyan

107

White

"Default \033[107mWhite"

Default White

import java.time.LocalDateTime;

class Producte {
   String descripcio;
   float pes;
   float pvp;
}

public class Main {

   private static final String NOM_BOTIGA = "Tuttifrutti S.L.";
   private static final float IVA = 0.21f;

   public static void main(String[] args) {
       Producte[] productes = new Producte[4];

       // Afegim productes a la llista
       productes[0] = new Producte();
       productes[0].descripcio = "Poma";
       productes[0].pes = 10.49f;
       productes[0].pvp = 1.23f;

       productes[1] = new Producte();
       productes[1].descripcio = "Maduixa";
       productes[1].pes = 0.5f;
       productes[1].pvp = 14.99f;

       productes[2] = new Producte();
       productes[2].descripcio = "Kiwi";
       productes[2].pes = 0.829f;
       productes[2].pvp = 2.49f;

       productes[3] = new Producte();
       productes[3].descripcio = "Taronja";
       productes[3].pes = 12.1f;
       productes[3].pvp = 0.99f;

       // Imprimim el tiquet, calculant al mateix temps l'import total
       float baseImponible = 0;
       System.out.printf("%s%n",NOM_BOTIGA);
       System.out.printf("Data: %tD%n", LocalDateTime.now());
       System.out.println();
       System.out.printf("%-12s%8s%8s%8s%n", "DESCRIPCIO", "PES", "PVP", "IMPORT");
       System.out.println(String.format("%36s", "").replace(" ", "-"));
       for (int i = 0; i < productes.length; i++) {
           float importProducte = productes[i].pes*productes[i].pvp;
           baseImponible += importProducte;

           System.out.printf("%-12s%8.2f%8.2f%8.2f%n",
                   productes[i].descripcio,
                   productes[i].pes,
                   productes[i].pvp,
                   importProducte);
       }
       System.out.println(String.format("%36s", "").replace(" ", "-"));
       System.out.printf("%29s%6.2f€%n", "BASE IMPONIBLE", baseImponible);
       System.out.printf("%29s%6.0f%%%n", "IVA", IVA*100);
       System.out.printf("%29s%6.2f€%n", "TOTAL", baseImponible + baseImponible*IVA);
       System.out.println();
       System.out.printf("%30s%n", "GRACIES PER LA SEVA VISITA");
       System.out.printf("%22s%n", "IVA INCLOS");
   }
}