# Text in JTextField und JTextArea zur Laufzeit ändern



## Ollek (17. Mrz 2011)

Hallo,

schon wieder ein Problem, das denke ich ein kleines Problem ist.
Ich möchte während meiner Laufzeit den Text in eienr JTextArea ud einem JTextField ändern.

Beispiel:

Ich habe eine Artikelliste in einer JTable dargestellt. Hier wird ein Artikel ausgewählt und angeklickt. Nun möchte ich die Detail Informationen anzeigen. Die Bezeichnung in einer TextArea und die ArtikelNummer in einerm JTextField. Ich woltle es so lösen, dass das ArtikelDetailJPanel  als Obersever auf die Änderungen des Userklicks reagiert. Ich habe eine ArtikelManagement-Klasse, die den angeklickten Artikel in einer Artikel Variable speichert und den Observer Informiert. Vorher wird der Artikel von der JTable in die ArtikelManagement Klasse geschrieben.

Ich habe auch die einzelnen Informationen zu dem Artikel mal ausgegeben im ArtikelDetailPanel, dort wird alles fein auf der Konsole ausgegeben aber nicht angezeigt. Jetzt verstehe ich nicht warum und hänge dort seit 2 tagen. Habe viel gegoogelt, da ich das problem gerne alleine lösen wollte, aber vergebens. Habs repaint, update ausprobiert. 

Ich hoffe ihr könnt mir helfen und eventuell noch eine kleine Meinung zu der Lösung mit der Artikel Management Klasse schreiben, ist es eine saubere Lösung?

Code poste ich nun:

ArtikelPanel

```
package de.viv.view;

import java.awt.Color;

public class ArticleAttribute extends JPanel implements Observer {
	
	private JTextField tfArtNr;
	private JTextField tfSku;
	private Article article;
	private String[] articleSplit;
	private boolean edit = false;
	private ArticleDescriptionArea descriptionArea;
	private int iMaxNumberOfChars = 30;
	private final static String newline = "\n";
	
	public ArticleAttribute(){
		super();
	
		init();		
	}
	
	public ArticleAttribute(boolean edit){
		
		this.edit = edit;
		
		init();
	}

	private void init() {
		this.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(Color.WHITE, Color.GRAY),
				"Hauptattribute", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Arial", Font.PLAIN, 10))); 
		initLayout();
		
		
		
	}

	/**
	 * GridBagLayout Konfiguration
	 */
	private void initLayout() {
		this.setLayout(new GridBagLayout());
		
		GridBagConstraints gbc;
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblDesc = new JLabel("Bezeichnung");
		lblDesc.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblDesc, gbc);
		
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 2;
		gbc.gridheight = 10;
		gbc.gridwidth = 4;
		gbc.weightx = 5;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.LINE_START;
		descriptionArea = new ArticleDescriptionArea();
		descriptionArea.setMaxCharactersPerRow(30);
		descriptionArea.setEditable(true);
		this.add(descriptionArea, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 13;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblArtNr = new JLabel("Artikelnummer");
		lblArtNr.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblArtNr, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 14;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		tfArtNr = new JTextField();
		tfArtNr.setEditable(edit);
		this.add(tfArtNr, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 15;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblMainCat = new JLabel("Hauptkategorie");
		lblMainCat.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblMainCat, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 16;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		JLabel lblMainCatDisp = new JLabel("Innenraum");
		this.add(lblMainCatDisp, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 17;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblSubCat = new JLabel("Unterkategorie");
		lblSubCat.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblSubCat, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 18;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		JLabel lblSubCatDisp = new JLabel("Innenraum");
		this.add(lblSubCatDisp, gbc);

	}
	
	public void splitArtDescription(Article article){
		
		String strDescription = article.getDescription();
		int iNumberofMaxFlows = 0;
		
		if(strDescription.length()%iMaxNumberOfChars > 0)
			iNumberofMaxFlows = (strDescription.length()/iMaxNumberOfChars)+1;
		else
			iNumberofMaxFlows = (strDescription.length()/iMaxNumberOfChars);
		
		articleSplit = new String[iNumberofMaxFlows];
		int startIndex = 0;
		int endIndex = iMaxNumberOfChars;
		System.out.println(strDescription.length()%iMaxNumberOfChars);
		for(int i = 0; i < iNumberofMaxFlows; i++){
			// letzter Split
			if(iNumberofMaxFlows - 1 == i){
				articleSplit[i] = strDescription.substring(startIndex);
				break;
			}
			articleSplit[i] = strDescription.substring(startIndex, endIndex);
			startIndex = startIndex + iMaxNumberOfChars;
			endIndex = endIndex + iMaxNumberOfChars;
		}
	}
	
	@Override
	public void update(Observable o, Object arg) {
		
		this.article = (Article) arg;
		
		splitArtDescription(article);
		System.out.println(articleSplit.length);
		for(String line : articleSplit){
			System.out.println(line);
			this.descriptionArea.append(line.trim() + newline);
		}
		this.tfArtNr.setText(article.getArtnr());
		System.out.println(article.getArtnr());
			
	}
	
	
	
	
	
}
```

ArtikelManagementKlasse

```
private Article selectedArticleInView = null;

	public void setSelectedArticleInView(Article viewArticle) {
		setChanged();
		this.selectedArticleInView = viewArticle;
		notifyObservers(this.selectedArticleInView);
		
	}

	public Article getSelectedArticleInView() {
		return selectedArticleInView;
	}
```

ArtikelTabelle

```
listSelectionModel.addListSelectionListener(new ListSelectionListener() {
			
			@Override
			public void valueChanged(ListSelectionEvent e) {
				int iSelectedRow = tblArticle.getSelectedRow();
				
				if(iSelectedRow == -1){
					System.out.println("Nix ausgewählt ;-)");
				} else {
					int iModelIndex = tblArticle.convertRowIndexToModel(iSelectedRow);
					ArticleManagement.getInstance().setSelectedArticleInView(tblModel.getValueAt(iModelIndex));
				}			
			}
		});
```


----------



## SlaterB (17. Mrz 2011)

dein Programm ist unvollständig, es zeigt nicht wo ArticleAttribute verwendet wird,

was ist ArtikelDetailPanel? ist das == Klasse ArticleAttribute?
meinst du die Ausgaben in der update()-Methode, Zeile 175 im geposteten Code?

wenn die erscheinen, sich in der GUI aber nichts tut, dann ist meine Vermutung, dass es zwei ArticleAttribute-Objekte gibt,
eins ist in der GUI eingebunden, ein ANDERES wird geupdatet, dort bringen Änderungen aber nicht viel,
außer natürlich die netten System.out.println()-Ausgaben,

dass es zwei Konstruktoren gibt ist schon sehr verdächtig, bei nur einem Objekt sollte einer reichen,
schreibe dort oder in alle Konstruktoren 
System.out.println("huhu");
rein, um ganz schnell zu erkennen, wie viele Objekte erzeugt werden


----------



## Ollek (17. Mrz 2011)

Hallo SlaterB,

danke für diesen Tipp bzw. Hinweis... 
Genau das war das Problem.. Ich hatte die Klasse 2 mal initalisiert. Einmal mit new beim Obserable und mit new beim adden des JPanels beim JFrame.. 

Ich habe es nun so gelöst:
Habe mir eine Methode in der ArticleManagement gebaut, die als Parameter die Klasse ArticleAttribute erwartet. Und die Klassenübergabe setzt ich dann als Observer. Da die Klasse ArticleManagement als Singleton arbeitet war es kein problem, die Methode in der ArticleAttribute aufzurufen. 
Ist das eine der richtige Lösungen? Es funktioniert so nun..

Hier die neuen Codezeilen:

ArticleAttribute

```
package de.viv.view;

import java.awt.Color;

public class ArticleAttribute extends JPanel implements Observer {
	
	private JTextField tfArtNr;
	private Article article;
	private String[] articleSplit;
	private boolean edit = false;
	private ArticleDescriptionArea descriptionArea;
	private int iMaxNumberOfChars = 30;
	private final static String newline = "\n";
	
	public ArticleAttribute(){
		super();
		ArticleManagement.getInstance().setObserver(this);
		
		init();		
	}


	private void init() {
		this.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(Color.WHITE, Color.GRAY),
				"Hauptattribute", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Arial", Font.PLAIN, 10))); 
		initLayout();
	}

	/**
	 * GridBagLayout Konfiguration
	 */
	private void initLayout() {
		this.setLayout(new GridBagLayout());
		
		GridBagConstraints gbc;
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblDesc = new JLabel("Bezeichnung:");
		lblDesc.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblDesc, gbc);
		
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 2;
		gbc.gridheight = 10;
		gbc.gridwidth = 4;
		gbc.weightx = 5;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.LINE_START;
		descriptionArea = new ArticleDescriptionArea();
		descriptionArea.setMaxCharactersPerRow(30);
		descriptionArea.setEditable(true);
		this.add(descriptionArea, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 13;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblArtNr = new JLabel("Artikelnummer:");
		lblArtNr.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblArtNr, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 14;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		tfArtNr = new JTextField();
		tfArtNr.setEditable(edit);
		this.add(tfArtNr, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 15;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblMainCat = new JLabel("Hauptkategorie:");
		lblMainCat.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblMainCat, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 16;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		JLabel lblMainCatDisp = new JLabel("Innenraum");
		this.add(lblMainCatDisp, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 17;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.insets = new Insets(10, 0, 0, 0);
		JLabel lblSubCat = new JLabel("Unterkategorie:");
		lblSubCat.setFont(new Font("Arial", Font.BOLD, 14));
		this.add(lblSubCat, gbc);
		
		gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 18;
		gbc.gridheight = 1;
		gbc.gridwidth = 1;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.LINE_START;
		JLabel lblSubCatDisp = new JLabel("Innenraum");
		this.add(lblSubCatDisp, gbc);

	}
	
	/**
	 * Methode zieht sich alle 30 Charcters einen
	 * Substring und speichert diesen in ein Array
	 * 
	 * @param article
	 */
	public void splitArtDescription(Article article){
		
		String strDescription = article.getDescription();
		int iNumberofMaxFlows = 0;
		
		if(strDescription.length()%iMaxNumberOfChars > 0)
			iNumberofMaxFlows = (strDescription.length()/iMaxNumberOfChars)+1;
		else
			iNumberofMaxFlows = (strDescription.length()/iMaxNumberOfChars);
		
		articleSplit = null;
		articleSplit = new String[iNumberofMaxFlows];
		int startIndex = 0;
		int endIndex = iMaxNumberOfChars;
		System.out.println(strDescription.length()%iMaxNumberOfChars);
		for(int i = 0; i < iNumberofMaxFlows; i++){
			// letzter Split
			if(iNumberofMaxFlows - 1 == i){
				articleSplit[i] = strDescription.substring(startIndex);
				break;
			}
			articleSplit[i] = strDescription.substring(startIndex, endIndex);
			startIndex = startIndex + iMaxNumberOfChars;
			endIndex = endIndex + iMaxNumberOfChars;
		}
	}
	
	@Override
	public void update(Observable o, Object arg) {
		
		// Artikel der angezeigt werden soll wird übergeben
		this.article = (Article) arg;
		
		splitArtDescription(article);
		this.descriptionArea.setText("");
		
		for(String line : articleSplit)
			this.descriptionArea.append(line.trim() + newline);
		
		this.tfArtNr.setText(article.getArtnr());
	}
}
```

ArticleManagement

```
public void setSelectedArticleInView(Article viewArticle) {
		setChanged();
		this.selectedArticleInView = viewArticle;
		notifyObservers(this.selectedArticleInView);
		
	}

	public Article getSelectedArticleInView() {
		return selectedArticleInView;
	}
	
	public void setObserver(ArticleAttribute articleAtt){
		this.addObserver(articleAtt);
	}
```

ArticleView (Das ist das Panel, wo ArticleAttribute geadded wird)

```
public class ArticleView extends JPanel {

	public ArticleView(){
		init();
	}

	private void init() {
		this.setLayout(new BorderLayout());
		this.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), ("Artikel-Details"), 
				TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.BELOW_TOP, new Font("Arial", Font.PLAIN, 10)));
		
		
		ArticleImage artImage = new ArticleImage();
		this.add(artImage, BorderLayout.CENTER);
		
		ArticleAttribute artAttribute = new ArticleAttribute();
		this.add(artAttribute, BorderLayout.SOUTH);
		
	}
	
}
```

An der ArticleTable hat sich nix geändert....
So besitzte ich nur noch ein Object von ArticleAttritbute..


----------



## SlaterB (17. Mrz 2011)

ist nicht unbedingt Standard, wer immer das Objekt erzeugt sollte es eigentlich überall dorthin leiten können,
wo es gebraucht wird, oder in einem Attribut ablegen, von dem es später abgeholt werden kann,
aber so gehts im Grunde auch


----------



## Ollek (17. Mrz 2011)

Könntest du mir dort bitte ein einfach Beispiel geben?  
Also mit dem weiterleiten denke ich mir, dass es über die Konstruktiren gemacht wird, richtig?


----------



## SlaterB (17. Mrz 2011)

schau dir JTextArea descriptionArea an, dort wird auch nur ein Objekt erzeugt welches an zwei Stellen benötigt wird:
in GUI einfügen vs. in update() darauf zugreifen, sind zwar 2 Stellen in derselben Klasse aber dennoch würdest du keine neue TextArea-Klasse erstellen und dort im Konstruktor irgendwas machen

ArticleAttribute erstellt die JTextArea an sinnvoller Stelle, nämlich beim Einfügen in die GUI und speichert sie in einem Attribut,
wer immer sonst noch die JTextArea braucht, kann dieses Attribut abfragen

so in etwa ginge es mit dem ArticleAttribute-Objekt bei dessem Aufrufer, ArticleView wie ich jetzt sehe,
ArticleManagement müsste dann irgendwie an ArticleView kommen und dort abfragen, und darauf hoffen dass dort das ArticleAttribute-Objekt auch schon erstellt wurde,
ob, ist bisschen komplizierter,

vielleicht so rum:
da ArticleManagement ja als Singleton überall erreichtbar ist, könnte dieses das ArticleAttribute-Objekt erstellen 
und damit gleich was machen und ArticleView fragt es dann auch vom Singleton ab,
hauptsache der Konstruktor bleibt leer,

perfekt ist das auch nicht da ArticleManagement als GUI-ferne Klasse dann etwas von der GUI erzeugt,
aus einer bestimmten Sichtweise ist dein Ansatz da besser, 

ach alles hin und her, nicht so ernst nehmen was ich nun gerade dazu zu sagen habe


----------



## Ollek (17. Mrz 2011)

Okay, trotzdem danke..

Hab wieder was dazu gelernt :rtfm:


----------

