# Schreibschutz eines JTable



## uxilator (14. Dez 2004)

Hallo,

weiß jemand vielleicht wie ich einen Schreibschutz auf eine JTable lege.

SetEnabled(false) kann ich übrigens nicht benutzen da es schon möglich sein soll Zeilen auszuwählen. 
Die Zelleninhalte dürfen halt nur nicht verändert werden.

Danke Axel


----------



## abollm (14. Dez 2004)

uxilator hat gesagt.:
			
		

> Hallo,
> 
> weiß jemand vielleicht wie ich einen Schreibschutz auf eine JTable lege.
> 
> ...



Das so genannte Table model hat eine Methode, die du in diesem Fall überschreiben musst, um zu steuern welche Spalten oder Zellen nicht edierbar sein sollen, z.B.


```
public boolean isCellEditable(row, col)
...
```

Diese Methode sollte dann "true" oder "false" zurückliefern, je nachdem ob das von dir gewünscht (true -> edierbar) ist oder nicht. 

Hdh


----------



## abollm (14. Dez 2004)

Damit das Ganze nicht so trocken ist, hier einmal ein Beispiel einer JTable (mit eigenem TabelModel), bei der die erste Zeile nicht, die anderen aber edierbar sind:

```
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
import java.awt.*;

public class JTable01 {
	public static void main(String[] a) {
		new JTable01().create();
	}

	private void create() {
		int cols = 9;
		int rows = 5;

		Vector data = new Vector();
		Vector header = new Vector();
		header.add("Spalte 1");
		header.add("Spalte 2");
		header.add("Spalte 3");
		header.add("Spalte 4");
		header.add("Spalte 5");
		header.add("Spalte 6");
		header.add("Spalte 7");
		header.add("Spalte 8");
		header.add("Spalte 9");

		TableModel tableModel = new TableModel(data, header);

		Object[] objData = new Object[cols];
		for (int c = 0; c < cols; c++)
			objData[c] = "";

		JTable ivjScrollPaneTable = new JTable(tableModel, new ColModel());
		for (int c = 0; c < rows; c++)
			tableModel.addNewRow(objData);

		/*
		 * ivjScrollPaneTable.setAutoCreateColumnsFromModel(false);
		 * createColumns(cols,ivjScrollPaneTable);
		 */

		ivjScrollPaneTable.setAutoCreateColumnsFromModel(true);// entweder diesen oder den
		// obigen, auskommentierten 
		// nehmen

		JFrame f = new JFrame();
		JPanel p = new JPanel(new BorderLayout());
		p.add(new JScrollPane(ivjScrollPaneTable), BorderLayout.CENTER);
		f.setContentPane(p);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		p.setPreferredSize(new Dimension(600, 100));
		f.setLocation(150, 150);
		f.pack();
		f.setVisible(true);
	}

	private void createColumns(int col, JTable ivjScrollPaneTable) {
		for (int iCtr = 0; iCtr < col; iCtr++) {
			TableColumn column = new TableColumn(iCtr);
			column.setPreferredWidth(100);

			//column.setHeaderValue((Object) ("Profil " + (iCtr + 1)));

			ivjScrollPaneTable.addColumn(column);
		}
	}

	class ColModel extends DefaultTableColumnModel {
		public ColModel() {
			super();
		}

		public void addColumn(TableColumn tablcol) {
			super.addColumn(tablcol);
		}
	}

	class TableModel extends DefaultTableModel {
		public TableModel(Vector data, Vector header) {
			super(data, header);
		}

		public Class getColumnClass(int column) {
			return (getValueAt(0, column).getClass());
		}

		public void addNewRow(Object[] objData) {
			addRow(objData);
		}

		public boolean isCellEditable(int row, int col) {
			boolean ret;
			if (row > 0)
				ret = true;
			else
				ret = false;
			if (ret)
				return true;
			else
				return false;
		}
	}
}
```


----------



## comp89 (16. Dez 2004)

ich glaube er meinte, man soll die zeile anwählen können (markieren können), um z.b. den inhalt oder so zu bekommen, aber man soll die daten in der tabelle nicht verändern können

das würde mich auch interessieren, das lässt sich auch in mein programm einbauen, früher oder später hätte ich eh gefragt


----------



## abollm (17. Dez 2004)

comp89 hat gesagt.:
			
		

> ich glaube er meinte, man soll die zeile anwählen können (markieren können), um z.b. den inhalt oder so zu bekommen, aber man soll die daten in der tabelle nicht verändern können
> 
> das würde mich auch interessieren, das lässt sich auch in mein programm einbauen, früher oder später hätte ich eh gefragt



Also, mindestens dich interessiert es, wie man eine Zeile mit einem Schreibschutz so versehen kann, dass man zwar die einzelnen Zellenwerte in der Zeile lesen aber eben nicht verändern, sprich überschreiben, kann.

Im Prinzp habe ich dafür schon die Lösung, muss aber noch den Code kurz zusammenbauen, dann poste ich ihn hier, ok?


----------



## comp89 (17. Dez 2004)

ja das wäre nett von dir


----------



## Guest (19. Dez 2004)

abollm hat gesagt.:
			
		

> Im Prinzp habe ich dafür schon die Lösung, muss aber noch den Code kurz zusammenbauen, dann poste ich ihn hier, ok?



machst du das jetzt noch?


----------



## bygones (19. Dez 2004)

hä ? ist es schon zu spät und ich check nix mehr...

ihr wollt nur dass die Werte der Tabelle nicht geändert werden dürfen, man soll aber noch alles auswählen können ?

Dafür ist doch schon die Antwort gegeben: isCellEditable muss einfach false zurückgeben....


----------



## abollm (20. Dez 2004)

Anonymous hat gesagt.:
			
		

> ...
> machst du das jetzt noch?



Ja. leider habe ich noch nicht meinen prinzipiellen Ansatz umsetzen können. Dauert doch länger als gedacht, bzw. bisher habe ich die dafür notwendige Zeit noch nicht gefunden.
Das erinnert mich wieder an den kürzesten Entwicklerwitz. Kennst du den?


----------



## comp89 (20. Dez 2004)

nein wie geht er, 

ja dbac genau das wollen wir, stell dir excel vor und du markierst etwas aber es ist ein schreibschutz drauf, dass du es nicht ändern kannst


----------



## abollm (20. Dez 2004)

comp89 hat gesagt.:
			
		

> nein wie geht er,



Der kürzeste Entwicklerwitz -> "Das haben wir gleich."

Ich hatte/habe es mir so vorgestellt, dass man die Werte z.B. in der ersten Zeile markieren und damit letztlich auch edieren kann, aber in dem Moment wo man die betr. Zelle verlässt, wird der Ausgangswert wieder in die Zelle geschrieben.


----------



## abollm (21. Dez 2004)

Nun haben "wir" es aber (hoffentlich):


```
/*
 * Created on 21.12.2004
 *
 * @author ABollm
 * 
 */

import javax.swing.*;
import java.awt.*;
import javax.swing.table.*;
import java.util.*;

public class JTableReadOnlyDemo extends JTable {

	static String[] names = { "A", "B" };

	static Object[][] data = { { "Bleibt stehen, d.h. wird nicht", " aktualisiert nach Verlassen!" }, 
			                   { "kann geändert", "werden" },
							   { "kann geändert", "werden" },
							   { "kann geändert", "werden" },
							   { "kann geändert", "werden" }};

	static Hashtable hash = new Hashtable();

	class myModel extends AbstractTableModel {
		public int getColumnCount() {
			return names.length;
		}

		public int getRowCount() {
			return data.length;
		}

		public Object getValueAt(int row, int col) {
			return data[row][col];
		}

		public String getColumnName(int column) {
			return names[column];
		}

		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		public boolean isCellEditable(int row, int col) {
			return true;
		}

		public void setValueAt(Object aValue, int row, int column) {
			String key = new String(row + "|" + column+ " ");
			if (hash.get(key) != null) {
				System.out.println("Existiert bereits");
				hash.remove(key);
				hash.put(key, " geändert");
			} else {
				System.out.println("Erstmals");
				hash.put(key, " geändert");
			}
			if (row >= 1)
				data[row][column] = aValue;
			System.out.println("Dieser Wert wurde geändert - Zeile: " + row + " - Spalte:" + column);
			System.out.println(hash);
		}
	};

	public JTableReadOnlyDemo() {
		super(data, names);
		dataModel = new myModel();
		this.setModel(dataModel);
		setRowSelectionAllowed(false);
		setCellSelectionEnabled(true);
		this.setRowHeight(20);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Demo für Nur-Lesen-Zeile -> Zeile 0");
		JTableReadOnlyDemo table = new JTableReadOnlyDemo();
		JScrollPane scrollPane = new JScrollPane(table);
		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
		frame.setSize(new Dimension(640, 150));
		frame.setVisible(true);
	}
}
```


----------



## bygones (21. Dez 2004)

abollm hat gesagt.:
			
		

> Ich hatte/habe es mir so vorgestellt, dass man die Werte z.B. in der ersten Zeile markieren und damit letztlich auch edieren kann, aber in dem Moment wo man die betr. Zelle verlässt, wird der Ausgangswert wieder in die Zelle geschrieben.


sry - das halte ich aber nicht für sehr user freundlich... entweder erlaube ich das Ändern oder nicht... Ändern lassen und dann einfach wieder überschreiben find ich sinnlos


----------



## abollm (21. Dez 2004)

deathbyaclown hat gesagt.:
			
		

> abollm hat gesagt.:
> 
> 
> 
> ...



Dafür musst du dich ja nun nicht entschuldigen. Aber im Ernst: Wenn du die Anforderung hast, dass ein Zelle oder von mir aus eine ganze Zeile oder Spalte in einer JTable edierbar sein soll (also lesbar), ohne dass du den Wert durch deinen Ediervorgang überschreiben darfst, was machst du dann?

Meine oben gepostete Lösung ist sicherlich nicht der "Brüller", aber es funktioniert und darauf kommt es an. Halt eine typische Quick-and-Dirty-Lösung. 

Anwendungsbeispiel wäre z.B. in solchen Tabellen gegeben, wo du bestimmte Zellenwerte mitunter einfach per Copy und Paste anderweitig zwingend benötigst. Mir fällt da z.B. der SQL-Navigator von Quest ein: Wenn du mit dem den kompletten Inhalt eine DB-Tabelle in ein Grid ausliest und du als Nutzer nur Lese-Rechte auf dieser Tabelle hast, dann hindert dich zunächst keiner, bestimmte Zellen- oder Grid-Werte per Markieren und Kopieren/Ausschneiden zu lesen und/oder sogar zu verändern. Erst in dem Moment, wo du irrtümlich versuchen solltest, deine Änderungen in die DB durchzuschreiben, erhältst du von der Applikation einen Hinweis, dass deine Änderungen nicht durchgeschrieben werden und der alte Wert wird wieder in die Zelle zurückgeschrieben. Das entspricht praktisch der Anforderung, die Ausgangspunkt für den von mir geposteten Code war. 

Ansonsten aber macht so ein Vorgehen natürlich wirklich nicht viel Sinn, da kann ich dir nur rechtgeben.


----------



## Titus (24. Dez 2004)

Die Lösung steht hier:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=281271

Viele Grüße, Titus


----------



## abollm (25. Dez 2004)

Titus hat gesagt.:
			
		

> Die Lösung steht hier:
> 
> http://forum.java.sun.com/thread.jspa?forumID=57&threadID=281271
> 
> Viele Grüße, Titus



Hi Titus,

wie wäre es, wenn du daraus ein wenig Code basteln würdest und den dann in dieses Forum stellst?
Ich kann so auf die Schnelle nämlich nicht erkennen, dass damit das oben geschilderte Problem erschlagen wird. Aber wie heißt es doch: Man lernt nie aus.
Und ich lerne gerne dazu.


----------

