Breite von Spalten anpassen

ich_Schmiddy

Mitglied
Hallo!

Ich habe eine Tabelle, bei der die Spalten am Anfang eine bestimmte Breite haben. Die Inhalte der Spalten können am Anfang oft nicht komplett dargestellt werden, das ist soweit OK.

Ist es jetzt möglich die Tabelle so zu definieren, daß wenn man auf den Strich zwischen zwei Spalten doppelklickt, die jeweilige Spalte dann auf die Breite geht, die zur kompletten Darstellung der Spalte benötigt wird?

Ist etwas blöd erklärt, ich weiß, ich will halt einfach die Tabelle so haben,, daß man eine Spalte per Doppelklick größer machen kann, so wie es bei verschiedenen Tabellenkalkulationen der Fall ist.
 
Original geschrieben von ich_Schmiddy
Hallo!

Ich habe eine Tabelle, bei der die Spalten am Anfang eine bestimmte Breite haben. Die Inhalte der Spalten können am Anfang oft nicht komplett dargestellt werden, das ist soweit OK.

Ist es jetzt möglich die Tabelle so zu definieren, daß wenn man auf den Strich zwischen zwei Spalten doppelklickt, die jeweilige Spalte dann auf die Breite geht, die zur kompletten Darstellung der Spalte benötigt wird?

Ist etwas blöd erklärt, ich weiß, ich will halt einfach die Tabelle so haben,, daß man eine Spalte per Doppelklick größer machen kann, so wie es bei verschiedenen Tabellenkalkulationen der Fall ist.

Das gibts bestimmt, ist aber Fummelei, den Mausklick zu behandeln.
Wie wäre es mit dieser Implementierung, die für alle Spalten die Breiten optimiert? (Einzubauen in Deiner von JTable abgeleiteten Klasse)

Code:
	/**
	 * Setzt für alle Spalten die optimale Spaltenbreite.
	 * 
	 */
	void sizeColumnsOptimal()
	{
		Point upperRow = null;
		Point lowerRow = null;

		// Bestimme die Anzahl der zu optimierenden Spalten.
		int optimizingColumns = getColumnCount();

		// Die verbrauchte Gesamtbreite
		int usedWidth = 0;

		for (int index = 0; index < optimizingColumns; index++)
		{
			// Bestimme die zu optimierenden Zeilen
			int fromRow = 0;
			int toRow = getRowCount();

			usedWidth += sizeColumnOptimal(index, fromRow, toRow);
		} // for 0..columnCount

		// Wenn die letzte Spalte nicht optimiert worden ist
		if (optimizingColumns < getColumnCount()
			&& getColumnCount() >= 0
			&& getScrollPane() != null
			&& getScrollPane().getViewport() != null)
		{
			// Ermittle die zur Verfügung stehende Breite
			int useableWidth = getScrollPane().getViewport().getWidth();

			// Setze die letzte Spalte auf die verbleibende Breite
			int remainingWidth = Math.max(0, useableWidth - usedWidth);
			TableColumn column = getColumnModel().getColumn(getColumnCount() - 1);

			column.setPreferredWidth(remainingWidth);
			column.setWidth(remainingWidth);
		}
	}


	/**
	 * Stellt für eine Spalte eine optimale Breite ein
	 * @param index der Index der Spalte
	 * @param fromRow die erste zu optimierende Zeile
	 * @param toRow die letzte zu optimierende Zeile
	 * @return die ermittelte Breite
	 */
	public int sizeColumnOptimal(int index, int fromRow, int toRow)
	{
		TableColumn col = getColumnModel().getColumn(index);
		int prefSize = 0;

		if (col.getHeaderRenderer() != null)
		{
			prefSize =
				col
					.getHeaderRenderer()
					.getTableCellRendererComponent(
						null,
						col.getHeaderValue(),
						false,
						false,
						0,
						0)
					.getPreferredSize()
					.width;
		}
		else
		{
			prefSize =
				getDefaultRenderer(String.class)
					.getTableCellRendererComponent(
						this,
						col.getHeaderValue(),
						false,
						false,
						0,
						0)
					.getPreferredSize()
					.width;
		}

		for (int rowIndex = fromRow; rowIndex < toRow; rowIndex++)
		{
			prefSize =
				Math.max(
					prefSize,
					getCellRenderer(rowIndex, index)
						.getTableCellRendererComponent(
							this,
							getValueAt(rowIndex, index),
							false,
							false,
							rowIndex,
							index)
						.getPreferredSize()
						.width);
		}

		// Für die Optik
		prefSize += getIntercellSpacing().width;

		col.setPreferredWidth(prefSize);
		col.setWidth(prefSize);

		return prefSize;
	}
 
Vielen Dank für den Tip

EIgentlich eine gute Idee, aber das Problem ist halt: manche Spalten sind sehr breit und sie sollen nur in der vollen breite angezeigt werden, wenn der Benutzer das wirklich will, nicht immer...
 
Snape hat gesagt.:
Das gibts bestimmt, ist aber Fummelei, den Mausklick zu behandeln.
Wie wäre es mit dieser Implementierung, die für alle Spalten die Breiten optimiert? (Einzubauen in Deiner von JTable abgeleiteten Klasse)

Code:
	/**
	 * Setzt für alle Spalten die optimale Spaltenbreite.
	 * 
	 */
	void sizeColumnsOptimal()
	{
		Point upperRow = null;
		Point lowerRow = null;

		// Bestimme die Anzahl der zu optimierenden Spalten.
		int optimizingColumns = getColumnCount();

		// Die verbrauchte Gesamtbreite
		int usedWidth = 0;

		for (int index = 0; index < optimizingColumns; index++)
		{
			// Bestimme die zu optimierenden Zeilen
			int fromRow = 0;
			int toRow = getRowCount();

			usedWidth += sizeColumnOptimal(index, fromRow, toRow);
		} // for 0..columnCount

		// Wenn die letzte Spalte nicht optimiert worden ist
		if (optimizingColumns < getColumnCount()
			&& getColumnCount() >= 0
			&& getScrollPane() != null
			&& getScrollPane().getViewport() != null)
		{
			// Ermittle die zur Verfügung stehende Breite
			int useableWidth = getScrollPane().getViewport().getWidth();

			// Setze die letzte Spalte auf die verbleibende Breite
			int remainingWidth = Math.max(0, useableWidth - usedWidth);
			TableColumn column = getColumnModel().getColumn(getColumnCount() - 1);

			column.setPreferredWidth(remainingWidth);
			column.setWidth(remainingWidth);
		}
	}


	/**
	 * Stellt für eine Spalte eine optimale Breite ein
	 * @param index der Index der Spalte
	 * @param fromRow die erste zu optimierende Zeile
	 * @param toRow die letzte zu optimierende Zeile
	 * @return die ermittelte Breite
	 */
	public int sizeColumnOptimal(int index, int fromRow, int toRow)
	{
		TableColumn col = getColumnModel().getColumn(index);
		int prefSize = 0;

		if (col.getHeaderRenderer() != null)
		{
			prefSize =
				col
					.getHeaderRenderer()
					.getTableCellRendererComponent(
						null,
						col.getHeaderValue(),
						false,
						false,
						0,
						0)
					.getPreferredSize()
					.width;
		}
		else
		{
			prefSize =
				getDefaultRenderer(String.class)
					.getTableCellRendererComponent(
						this,
						col.getHeaderValue(),
						false,
						false,
						0,
						0)
					.getPreferredSize()
					.width;
		}

		for (int rowIndex = fromRow; rowIndex < toRow; rowIndex++)
		{
			prefSize =
				Math.max(
					prefSize,
					getCellRenderer(rowIndex, index)
						.getTableCellRendererComponent(
							this,
							getValueAt(rowIndex, index),
							false,
							false,
							rowIndex,
							index)
						.getPreferredSize()
						.width);
		}

		// Für die Optik
		prefSize += getIntercellSpacing().width;

		col.setPreferredWidth(prefSize);
		col.setWidth(prefSize);

		return prefSize;
	}

Das wäre das, was ich gebrauchen könnte, allerdings habe ich ein prob bei der Implementierung. Ich benutze den Visual Editor für Eclipse.

Warum frägst Du in der von JTable abgeleiteten Klasse (in meinem Fall MyTable.java) getScrollPane ab? Das gibt's bei mir gar nicht in der Klasse, wenn dann nur in der Klasse, wo die Tabelle reinkommt. Steh ich auf dem Schlauch, oder wie kann ich mir das sonst erklären?

Danke ;)

Der nette Mann
 
Der nette Mann hat gesagt.:
Das wäre das, was ich gebrauchen könnte, allerdings habe ich ein prob bei der Implementierung. Ich benutze den Visual Editor für Eclipse.

Warum frägst Du in der von JTable abgeleiteten Klasse (in meinem Fall MyTable.java) getScrollPane ab? Das gibt's bei mir gar nicht in der Klasse, wenn dann nur in der Klasse, wo die Tabelle reinkommt. Steh ich auf dem Schlauch, oder wie kann ich mir das sonst erklären?

Danke ;)

Der nette Mann

Sorry, da habe ich wohl etwas vergessen. :)

Code:
	/**
	 * Liefert die ScrollPane, in der diese Tabelle liegt
	 */
	JScrollPane getScrollPane()
	{
		Container cont = getParent();

		while (cont != null && !(cont instanceof JScrollPane))
		{
			cont = cont.getParent();
		}

		return (JScrollPane) cont;
	}
 
Hab mich schon gewundert ;) Hab Dein Code etwas umgeschrieben und es funktioniert bei mir ganz wunderbar. Genauso sollte das aussehen.

Vielen Dank für diesen Tipp (auch wenn er schon etwas älter war ;) das suchen hat sich somit gelohnt)


Grüße

Der nette Mann
 
Der nette Mann hat gesagt.:
Hab mich schon gewundert ;) Hab Dein Code etwas umgeschrieben und es funktioniert bei mir ganz wunderbar. Genauso sollte das aussehen.

Prima. Was hast Du geändert? Etwas das ich wissen sollte?

Vielen Dank für diesen Tipp (auch wenn er schon etwas älter war ;) das suchen hat sich somit gelohnt)

Grüße
Der nette Mann

Prima. :)
 
Och, ich hab eigentlich nix weltbewegendes geändert. Ich hab die Breite der Spalten angepasst ohne dass ich auf die darunterliegende ScrollPane Rücksicht genommen habe.

Die Schleifen über die Spalten hab ich auch gemacht und mir dann die Werte der Breite über den Funktionsaufruf sizeColumnOptimal geholt.

Wie gesagt, hab genau das gewünschte Ergebnis :)

Gruß

Der nette Mann
 
Zurück