IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SWT/JFace Java Discussion :

Formater un xml dans un Text (swt.widgets.text)


Sujet :

SWT/JFace Java

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 40
    Points : 41
    Points
    41
    Par défaut Formater un xml dans un Text (swt.widgets.text)
    Bonjour à tous.

    Mon problème est le suivant :

    Je récupère un code XML (tout en ligne) que j'affiche dans un Text.
    Ce XML (qui peut être parfois assez long en longueur vu qu'il est sur une même ligne) dépasse très souvent de mon Text.
    Je cherche donc à formater ce XML dans ce Text comme on peut le faire sur Eclipse en faisant Ctrl+Shift+F, soit en créant un raccourci qui fera ce formatage soit en codant une méthode qui affichera le XML déjà formaté.

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
     
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.graphics.Font;
    import org.eclipse.swt.graphics.Point;
    import org.eclipse.swt.graphics.Rectangle;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Dialog;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Text;
     
    public class AffichageFormateDialog extends Dialog{
     
    	private Shell dialog;
     
    	private String texte;
    	private String type;
     
    	private int height = 750;
    	private int width = 650;
     
     
    	public AffichageFormateDialog(Shell parent) {
    		super(parent);
    	}
     
    	public AffichageFormateDialog(Shell parent, String texte, String type){
    		this(parent);
    		this.texte = texte;
    		this.type = type;
    	}
     
    	public String open() {
    	    Shell parent = getParent();
    	    /*Shell*/ dialog = new Shell(parent, SWT.DIALOG_TRIM
    	        | SWT.APPLICATION_MODAL);
    	    dialog.setSize(width, height);
    	    dialog.setText("Affichage du " + this.type);
     
    	    Rectangle parentSize = getParent().getBounds();
    	    int locationX, locationY;
    		locationX = (parentSize.width - width)/2+parentSize.x;
    		locationY = (parentSize.height - height)/2+parentSize.y;
    		dialog.setLocation(new Point(locationX, locationY));
     
    		createContent();
     
    	    dialog.open();
    	    Display display = parent.getDisplay();
    	    while (!dialog.isDisposed()) {
    	      if (!display.readAndDispatch())
    	        display.sleep();
    	    }
    	    return "OK";
    	}
     
    	private void createContent(){
    		GridLayout layoutComposite = new GridLayout();
    		layoutComposite.marginHeight=0;
    		layoutComposite.marginWidth=0;
    		dialog.setLayout(layoutComposite);
     
    		Composite cAffichage = new Composite(dialog, SWT.BORDER);
     
    		GridLayout glcAffichage = new GridLayout(1, false);
    		cAffichage.setLayout(glcAffichage);
    		GridData gdcAffichage = new GridData();
    		gdcAffichage.widthHint = 650;
    		gdcAffichage.heightHint = 750;
    		cAffichage.setLayoutData(gdcAffichage);
     
    		Text txt = new Text(cAffichage, SWT.NONE | SWT.MULTI | SWT.V_SCROLL);
    		txt.setText(this.texte);
     
    		//txt.setEditable(false);
    		GridData gdTxt = new GridData();
    		gdTxt.heightHint = 700;
    		gdTxt.widthHint = 620;
    		txt.setLayoutData(gdTxt);
     
    	}
     
    }
    En espérant avoir été clair dans mes explications.
    Je vous remercie par avance pour votre aide.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Je ne comprends pas bien quelle est ta question... hormis le style WRAP (au lieu de MULTI) qui va faire un retour à la ligne si la ligne est trop longue au lieu de le faire lors d'un newline, il suffit que tu formattes ton xml avant de l'affecter au composant Text,

    • soit par expression régulière, ou enchaînement d'expressions régulières, pour un résulat plus ou moins potable, mais sans indentation ;
    • avec un petit automate à état, qui peut s'avérer plus puissant que les expressions régulières, mais un peu plus siouxe à mettre au point selon le résulat voulu. C'est la solution qui offre le plus de possibilité d'obtenir le résultat exactement voulu et qui offre le meilleur tremplin vers une possiblité de colorisation(en utilisant un StyledText au lieu d'un Text), content assist, etc.
    • utiliser un sérialisateur standard, DOM, SAX ou STaX, avec leurs défauts à contourner avec plus ou moins de travail (voir exemples ci-après), ou une API Trierce (JDOM par exemple),


    Le défaut étant de devoir revenir à l'état d'origine à la sauvegarder éventuellement.

    Voici un petit POC avec les différentes méthodes pour exemple (assez limités) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    import java.io.StringReader;
    import java.io.StringWriter;
     
    import javax.xml.stream.FactoryConfigurationError;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLOutputFactory;
    import javax.xml.stream.XMLStreamConstants;
    import javax.xml.stream.XMLStreamException;
    import javax.xml.stream.XMLStreamReader;
    import javax.xml.stream.XMLStreamWriter;
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
     
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.layout.FillLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Text;
     
    public class DemoXmlFormat {
     
    	private static final int INDENT = 4;
     
    	public static void main(String[] args) {
    	    Display display = new Display();
    	    try {
    		    Shell shell = new Shell(display);
    		    shell.setText("Démo");
    		    shell.setSize(600, 200);
    		    shell.setLayout(new FillLayout());
    		    setText1(shell); // WRAP
    		    setText2(shell); // REGEXP SIMPLE
    		    setText3(shell); // REGEXP ++
    		    setText4(shell); // AUTOMATE
    		    setText5(shell); // XML FORMATTING (TRANSFORMER)
    		    setText6(shell); // XML FORMATTING (STaX)
    		    shell.open();
    		    while (!shell.isDisposed()) {
    		      if (!display.readAndDispatch())
    		        display.sleep();
    		    }
    	    }finally {
    	    	display.dispose();
    	    }
    	  }
     
    	private static void setText1(Composite parent) {
    		// WRAP
    	    Text text = new Text(parent, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL); 
    	    text.setText(getXML());
    	}
     
    	private static void setText2(Composite parent) {
    		// REGEXP simple : on passe à la ligne après >
    	    Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    	    text.setText(getXML().replaceAll(">", ">\n"));
    	}
     
    	private static void setText3(Composite parent) {
    		// REGEXP ++ : on passe à la ligne après >, on passe à la ligne avant </, sauf s'il est précédé d'un passage à la ligne
    	    Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    	    text.setText(getXML().replaceAll(">", ">\n").replaceAll("(?<!\n)</","\n</"));
    	    // alternative on passe à la ligne avant </, sauf s'il est précédé d'un >, on passe à la ligne après > 
    	    // text.setText(getXML().replaceAll("(?<!>)</","\n</").replaceAll(">", ">\n"));
    	}
     
    	private static void setText4(Composite parent) {
    		// Automate à état
    	    Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    	    StringBuilder builder = new StringBuilder();
    	    String s = getXML();
    	    boolean inTag=false;
    	    boolean empty=false; 
    	    char previous='\0';
    	    char last='\0';
    	    int indent=0; 
    	    boolean open=false;
    	    for(int i=0; i<s.length(); i++) {
    	    	char c = s.charAt(i); 
    	    	if ( last=='\n' ) {
    				builder.append(getIndent(indent));
    	    	}
    	    	if ( inTag ) {
    		    	switch(c) {
    		    	case '/':
    		    		if ( previous=='<' ) {
    		    			empty=true;
    		    			open=false;
    		    			builder.delete(builder.length()-1-INDENT, builder.length()-1);
    		    		} 
    	    			indent--;
    		    		builder.append(c);
    		    		break;
    		    	case '>':
    		    		builder.append(c);
    		    		builder.append('\n');
    		    		if (empty) {
    		    			empty=false; 
    		    		}
    		    		else if ( open ) {
    		    			indent++;
    		    		}
    		    		open=false;
    		    		inTag=false;
    		    		break;
    	    		default:
    		    		builder.append(c);
    		    	}
    	    	}
    	    	else {
    	    		switch(c) {
    	    		case '<':
    	    			open=true;
    	    			if ( previous!='\0' ) {
    	    				//indent++;
    		    			if ( previous!='>' ) {
    		    				builder.append('\n');
    		    				builder.append(getIndent(indent));
    		    			}
    	    			}
    	    			inTag=true;
    	    			break;
    	    		}
    	    		builder.append(c);
    	    	}
    	    	previous=c;
    	    	last = builder.charAt(builder.length()-1);
    	    }
    	    text.setText(builder.toString());
    	}
     
    	private static void setText5(Composite parent) {
    	    Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
     
    	    try {
    		    Source input = new StreamSource(new StringReader(getXML()));
    	        StringWriter stringWriter = new StringWriter();
    	        StreamResult output = new StreamResult(stringWriter);
    	        TransformerFactory transformerFactory = TransformerFactory.newInstance();
    	        //transformerFactory.setAttribute("indent-number", 4); // voir autre solution alternative ci-dessous
    	        Transformer transformer = transformerFactory.newTransformer(); 
    	        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    	        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    	        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    	        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    	        transformer.transform(input, output); 
     
    		    text.setText(output.getWriter().toString().toString());
    		} catch (TransformerException e) { 
    			e.printStackTrace();
    		} 
     
    	}
     
    	private static void setText6(Composite parent) {
    	    Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
     
    	    try {
    			XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(getXML()));
    			try {
    		    	StringWriter stringWriter = new StringWriter();
    				XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(stringWriter);
    				int indent=0;
    				try {
    					while(reader.hasNext()){
    						switch(reader.getEventType()) {
    						case XMLStreamConstants.START_ELEMENT:
    							writer.writeCharacters(getIndent(indent)); 
    							writer.writeStartElement(reader.getLocalName());
    							for(int i=0; i<reader.getAttributeCount(); i++) {
    								writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i));
    							}
    							writer.writeCharacters("\n");
    							indent++;
    							break;
    						case XMLStreamConstants.END_ELEMENT:
    							indent--;
    							writer.writeCharacters(getIndent(indent));
    							writer.writeEndElement();
    							writer.writeCharacters("\n");
    							break;
    						case XMLStreamConstants.CHARACTERS:
    							writer.writeCharacters(getIndent(indent+1));
    							writer.writeCharacters(reader.getText());
    							writer.writeCharacters("\n");
    							break;
    						}
     
    						reader.next();
     
    					}
    					text.setText(stringWriter.toString());
    				}
    				finally {
    					writer.close();
    				}
    			}
    			finally {
    				reader.close();
    			}
    	    } catch (XMLStreamException | FactoryConfigurationError e) { 
    			e.printStackTrace();
    		}
     
    	}
     
    	private static String getIndent(int indent) {
    		if ( indent==0 ) {
    			return "";
    		}
    		return String.format("%1$"+(indent*INDENT)+"s", " ");
    	}
     
    	public static String getXML() {
    		return "<root><elem><subelem>text</subelem></elem><elem><subelem>text</subelem><subelem>text</subelem>text<subelem>text</subelem><empty/><subelem>text</subelem></elem><elem attrb=\"value\">text</elem><empty/></root>";
    	}
     
    }

    Avec les résultats (dans l'ordre ge gauche à droite, mode wrap, regexp simple, regexp enchainées, automate à état, API Transformer, API STaX)

    Nom : XML_SC.PNG
Affichages : 275
Taille : 41,6 Ko

    Il n'y aucun traitement des entités en revanche, qu'il faudra ajouter.


    Il y a éventuellement d'autres solutions, comme utiliser un SourceViewer JFace, en s'inspirant et adaptant le XML Editor d'Eclipse, etc. Si certains aspects sont plus simple, d'autres peuvent être plus complexe (en particulier parce qu'il faut farfouiller le code à la recherche des sous-composants). Il y a un projet dans le pipe de découplage des IEdtiorPart et des composants internes justement pour faciliter ce genre de chose, mais je ne sais pas pour quand c'est prévu et si ce sera effectivement fait.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Afficher un texte en format XML dans un div
    Par Juju54350 dans le forum ASP.NET
    Réponses: 3
    Dernier message: 13/09/2012, 16h44
  2. formater un XML dans un Jtree et vice et versa
    Par Cdic83 dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 10/04/2007, 09h30
  3. colorier une colonne dans un widget text
    Par Chris33 dans le forum Tkinter
    Réponses: 4
    Dernier message: 14/09/2006, 11h20
  4. XML dans un champ text
    Par etien dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 04/07/2006, 11h31
  5. Réponses: 2
    Dernier message: 03/02/2006, 19h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo