Merkwürdige Größe bei JScrollPane

  • Themenstarter Themenstarter Guest
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo!

Ich bin gerade dabei mir die Grundlagen der JTable-Komponente anzueignen, bin jetzt aber auf ein merkwürdiges Problem gestoßen. Sobald ich die JTable in ein JScrollPane setze, wird man Fenster überdimensional groß (soll heißen: wesentlich größer, als es sein muss), obwohl ich pack() benutze.

Hier mal der Code der Testklasse, bei der ich etwas mit JTable rumspielen wollte und bei der das Problem aufgetreten ist:
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JTableTest extends JFrame {
	private JButton button;
	private JTextField column, row, content;
	private JLabel columnLabel, rowLabel, contentLabel;
	private JTable table;
	
	public JTableTest() {
		super("Tabellen Test");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container cont= getContentPane();
		
		table = new JTable(5,5);
		JScrollPane scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		
		cont.add(BorderLayout.CENTER, scroll);
		
		columnLabel = new JLabel("Column:");
		rowLabel = new JLabel("Row:");
		contentLabel = new JLabel("Content");
		
		column = new JTextField("1");
		row = new JTextField("1");
		content = new JTextField("Content");
		
		JPanel controlPanel = new JPanel(new FlowLayout());
		button = new JButton("Hole Inhalt");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				content.setText((String)table.getValueAt(Integer.parseInt(column.getText()), Integer.parseInt(row.getText())));
			}
		});
		
		controlPanel.add(button);
		controlPanel.add(columnLabel);
		controlPanel.add(column);
		controlPanel.add(rowLabel);
		controlPanel.add(row);
		controlPanel.add(contentLabel);
		controlPanel.add(content);
		cont.add(BorderLayout.SOUTH, controlPanel);
		
		System.out.println(table.getHeight()+ " " + table.getWidth());
		
		pack();
		setVisible(true);		
	}
	
	public static void main(String args[]) {
		JTableTest test = new JTableTest();
	}
}

Ohne JScrollPane hat das Fenster übrigens die optimale Größe.

Ich wäre euch sehr dankbar, wenn ihr mir da auf die Sprünge helfen könntet. Ich habe schon ein paar Tricks ausprobiert, z.B. über setPreferredSize der JScrollPane die Größe der Tabelle zuzuordnen, aber das war auch nie von Erfolg gekrönt.[/code]
 
Hm, aber mit welchen Werten? Ich möchte ja, dass sich das Fenster genau an den optimalen Platz anpasst.
Das Fenster besteht ja nicht nur aus dem JScrollPane. Selbst wenn ich mir die Größe vom JScrollPane holen würde und dann das Fenster entsprechend anpasse, so stimmts immer noch nicht, da das JScrollPane selbst diese merkwürdige Größe besitzt (hab das schonmal per getSize überprüft).
 
Wo hast du denn dein setPreferredSize auf das ScrollPane hingeschrieben?

Code:
 JScrollPane scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
      scroll.setPreferredSize(table.getPreferredSize());
      cont.add(BorderLayout.CENTER, scroll);
bringt zumindest ansatzweise etwas
 
Ich hatte es genau so gemacht, wie du grade geschrieben hast, blos habe ich das (wenn ich mich richtig erinnere) erst nach dem Hinzufügen zum Container gemacht. Was im nachhinein natürlich äußerst wenig Sinn macht.

Ich habs jetzt mal so ausprobiert, wie du es gesagt hast. Das funktioniert auch, blos hat es einen kleinen Haken. Ganz stimmt die Größe immer noch nicht, der Header der Tabelle wird wohl nicht beachtet. Es wird genau eine Zeile zu wenig angezeigt (die man sich dann nur per Scrollbar ansehen kann).

Ich versteh einfach nicht, wo das Problem liegt. Sonst funktioniert das JScrollPane immer problemlos, blos mit der Table hats wohl seine Probleme :/
 
So geht's, aber schön ist es nicht. (Seltsam, dass es Konstant falsch ist)
Code:
ScrollPane scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
      Dimension tableSize = table.getPreferredSize();
      Dimension newSize = new Dimension(tableSize.width,(int)((tableSize.height/table.getRowCount())*(table.getRowCount()+1.15)));
      scroll.setPreferredSize(newSize);
      cont.add(BorderLayout.CENTER, scroll);
 
Hm, ja, danke Ariol, so gehts. Aber wie du ja schon sagst: Schön ist das wirklich nicht. Das ist jetzt ja mehr Rumtrickserei als sonstwas. Da muss es doch eine ander Lösung geben :bahnhof:
 
Ich habe jetzt eine Lösung für das Problem gefunden. Es lag am JTable. Für die JTable kann man separat einen Viewport setzen. D.h. wieviel von der Tabelle standardmäßig im ScollPane angezeigt werden soll. Anscheinend sind die Werte dafür von Beginn an sehr groß, weshalb man das bei kleinen Tabellen besser selbst noch über setPreferredScrollableViewportSize() skaliert.

Ich habs folgendermaßen gelöst:
Code:
table.setPreferredScrollableViewportSize(new Dimension((int)table.getPreferredScrollableViewportSize().getWidth(), int)table.getPreferredSize().getHeight()));
f.pack();
Ich setze also die Breite auf die voreingestelte Breite (denn die war soweit brauchbar) und die Höhe auf die Höhe der Tabelle.
Dann hat das Frame exakt die Größe, die ich haben will.


Die Funktion scheint wohl neu zu sein. Ich hab sie blos durch rumstöbern in der API und in Beispielen von Sun selbst gefunden. In der Fachliteratur in der ih nachgesehen habe, konnte ich dazu nichts finden. Selbst die Beispiele in "Java ist auch eine Insel" haben diese Befehle nicht und man erhält ein viel zu großes Fenster, wenn man sie selbst kompiliert.[/code]
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben