ubuntuusers.de

[Java+Swing] 5 Objekte uebereinander machen, die unterschiedliche Hoehen haben

Status: Ungelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

dersven

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Hallo.

Ich versuche gerade die LayOut-Manager von Java zu verstehen. Bisher habe ich etwa 6 gefunden, und ein wenig damit rumprobiert

  • Border Layout

  • GridLayout

  • BoxLayout

  • AbsoluteLayout

  • SpringLayout

  • FlowLayout

Ich weiss nur nicht, wie ich die miteinander kombinieren muss, damit dass dabei herauskommt was ich mochte. Wenn ich z.B. GridLayout, und zwei Buttons hinzufuege, haben diese alle die gleiche Breite, und alle die gleiche hoehe. die Hoehe eines Buttons kann ich nicht aendern. Wenn ich den Button zuerst in eine Box schreibe, und dann in das Grid, dann ist der Button zwar minimal gross, aber aendern kann ich dessen Groesse immer noch nicht.

Beim BorderLayout kann ich nur drei Felder angeben, und die Groesse auch nicht bestimmen.

Was ich machen moechte ist:

5 Zeilen uebereinander. in zweien ist ein Label drin, wobei eines zu beginn eine bestimmte Hoehe haben soll, bzw, falls es gehet eine hoehe die vom Text abhaengt. Dazu einen Button, der die Breite hat, die der Text benoetingt (und nicht die, die von der Fensterfreite vorgegeben ist), und zudem zum oberen und unteren Feld einen gewissen abstand hat (Bei Boxen kann man ja scheinbar leere Boxen einfuegen, die eine bestimmte Hoehe haben: "createHorizontalStrut"). Eine Einzeilige input-Box, die sich aehnlich verhaelt wie der Button. Und zu guter letzt eine Textbox, die immer den Rest des Fensters ausfuellt.

Ich dachte es ist nich so schwer. Eigentlich muesste ich doch nur das Fenster in 5 Bereiche einteilen, die sich in irgendeiner Weise an die Groesse der Teile anpassen, die Innerhalb der Bereiche liegen. Aber es schein umgekehrt zu laufen, also das alles das was innerhalb ist, sich an die Groesse der Zeug anpasst, was sie umgibt, korrekt? kann man das umstellen?

die Funktion "pack()" bei JFrame waere ja ganz interessant, wenn ich zuvor eine fixe Groesse einige Elemente angeben koennte,...

Irgendwelche Elemente, die eine fixe Groesse haben, die nicht kleiner gemacht werden kann, waere auch sehr hilfreich. die Beispiele dich ich z.B. auf der Seite java2s.com gefunden habe, haben mir bei meinem Problem nicht weitergeholfen (manchmal sind die deutlich umfangreicher als sie sein muessten. Am besten fand ich bisher http://www.java2s.com/Code/Java/Swing-JFC/BoxLayoutSample.htm).

NaJa, ich hoffe jemand kann mir helfen, auch wenn es basics sind, die wahrscheinlich umfangreich zu erklaeren sindm,,...

Danke schonmal

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Teils ist es Gewohnheitssache, wie man das Problem angeht, aber für konkrete Hilfe wäre eine Skizze hilfreich.

Ich arbeite meist mit BorderLayout und BoxLayout in Kombination.

BoxLayout ist praktisch für alles, was einheitlich groß sein soll.

An die Schrift passen sich die Komponenten selbst an, und werden, wenn man es nicht verbietet, mindestens so groß wie nötig, um einen Text darzustellen. AbsoluteLayout solltest Du vermeiden, weil sich dies nicht anpaßt. Wenn Deine Anwendung internationalisiert wird, und längere oder kürzere Beschriftungen deshalb hat, dann passt sich das Layout daran an, wenn kein AbsoluteLayout verwendet wird. Oder Du erlaubst dem User eine größere Schrift auszuwählen, und trallabumm werden alle Komponenten einen Deut größer.

Eine Einzeilige input-Box, die sich aehnlich verhaelt wie der Button.

Ein JTextField? Inwiefern verhält wie ein Button?

Wenn die Textbox groß sein soll, dann bietet sich ein BorderLayout an, und im Center die JTextArea. Im Norden ein weiteres Panel, und in dem BoxLayout mit Deinen 4 Elementen (Label, Button, JTextField).

GridBoxLayout ist übrigens auch noch weit verbreitet.

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Hi. Also, das BorderLayout mag ich an sich auch ganz gerne. z.B. ist auf der Seite http://www.java2s.com/Code/Java/Swing-JFC/BoxLayoutSample.htm vom Ansatz her das zu sehen, was ich haben moechte. Allerdings sind in Ausnahmslos allen Beispielen die ich bisher gesehen habe, nur 3 Elemente dargestellt. Wie kann ich das Bewerkstelligen, wenn ich im Norden z.B. zweit JLabels haben moechte? Platziere ich dann dort einen Container, der wieder alle Himmelsrichtungen hat, oder eine Box, oder kann eine Box nur ein einziges Element enthalten?

Wenn die Textbox groß sein soll, dann bietet sich ein BorderLayout an, und im Center die JTextArea. Im Norden ein weiteres Panel, und in dem BoxLayout mit Deinen 4 Elementen (Label, Button, JTextField).

In allen Beispielen die ich bisher angeschaut habe, wurde das Panel nur dann verwendet, wenn Mann die Objekte nebeneinander anordnen wollt,...Dann geht es scheinbar auch uebereinander? Ich werde mir das mal anschauen.

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Merkwurdig,... gestern hat das mit diesen verticalBoxes bei mir nicht geklappt. da muss mir wohl ein Fehler unterlaufen sein. Nur das setzen der Groesse des Textfeldder klappt noch nicht. zumindest nicht mit setSize. Wahrscheinlich muss ich dort setMinimumSize nehmen. (obwohl mir das andere intuitiver erscheint.)

Seltsamerweise werden beim Setzen der Dimenson auch die Buttons nach rechts verschoben und sind mit einem Male halbherzig zentriert anstatt wie vorher linksbuendig.

Ist es auch moeglich, dann beide Textfelder sich den neuen Verfuegbaren Platz gleichmaessig aufteilen? bisher wird nur eines der Beiden Textfelder Groesse.

 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
import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

// http://www.java2s.com/Code/Java/Swing-JFC/BoxLayoutSample.htm

public class BoxLayoutSample {
	public static void main(String args[]) {
		JFrame verticalFrame = new JFrame("Vertical");
		verticalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Box verticalBox1 = Box.createVerticalBox();
		Box verticalBox2 = Box.createVerticalBox();
		
		JTextField text1 = new JTextField("Middle");
		text1.setMinimumSize(new Dimension(100, 100));
		
		verticalBox1.add(new JLabel("Top"));
		verticalBox1.add(text1);
		verticalBox1.add(new JTextField("Middle"));
		verticalBox1.add(new JButton("Bottom"));
		verticalBox1.add(new JButton("Bottom"));
		
		verticalBox2.add(new JLabel("Top"));
		verticalBox2.add(new JTextField("Middle"));
		verticalBox2.add(new JButton("Bottom"));
		
		verticalFrame.getContentPane().add(verticalBox1, BorderLayout.CENTER);
		verticalFrame.getContentPane().add(verticalBox2, BorderLayout.SOUTH);
		verticalFrame.setSize(150, 150);
		
//		verticalFrame.pack();
		verticalFrame.setVisible(true);
		
	}
	
}

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

Ich habe mal zwei datein angehaegt von dem was ich versuche umzusetzen.

Ich glaube ich werde davon behindert, dass ich schon so klare Vorstellungen von dem habe was ich machen moechte.

Die Textfelder solle uebrigens auch Scrollbalken haben. da habe ich gelesen, dass ich die erst in ein "Scrollable" packen muss. Darein werde ich vorm Mittag wohl noch einige Zeit investieren ☺

Bilder

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Aus welchem Grund sind Button 1 und Button 1 [sic] zusammen breiter als die oberen Komponenten? Soll das so sein?

Wenn Du Komponenten zusammenfassen willst, weil sie zusammengehören (Label + Textarea) oder weil sie sich die die Größe teilen sollen (TA 1 und TA 2), dann pack sie in ein gemeinsames Panel.

Das ist die gewollte Vorgehensweise: Ein Panel im Panel im Panel im Panel.

Textarea 1 + Label würde ich spontan in ein BorderLayout (North + Center) packen. (tal1) Textarea 2 + Label genauso. (tal2) Tal1 und Tal2 dann gemeinsam wieder in ein Panel. But1 u. 2 auch in ein gemeinsames Panel, mit BoxLayout.LINE_AXIS. Anfangs benutzte man BoxLayout.X_AXIS und Y_AXIS um die Elemente von links nach rechts und von rechts nach links anzuordnen. Dann stellte man fest, daß es praktisch ist, wenn man nur PAGE_AXIS und LINE_AXIS vorgibt, und anhand der Locale feststellt, ob man in dem Kulturraum von rechts nach links und von unten nach oben schreibt, und so auch die Komponenten anordnet. Das macht dann das Layout, und Du mußt Dich nicht drum kümmern, aber in Israel sieht Deine Anwendung plötzlich ganz anders aus. ☺

Ein Layoutdemo, bei dem der ActionListener nicht state of the Art ist (man würde mit Swingthreads arbeiten), die meisten Komponenten nur im Vorbeigehen erzeugt werden, und so ohne Referenz in einem Programm recht nutzlos sind, und der Font als Attribut war auch nur die schnellste Möglichkeit das ganze mit Gewalt zum Laufen zu bringen - es zeigt aber wie in einem Panel mit e. Layoutmanager ein weiteres sitzt mit einem anderen Layoutmanager, und wie das Layout auf Änderung der Fontsize reagiert - mit Änderung der Fenstergröße bitte selbst experimentieren.

  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

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
	MultipanelLayout

	@author Stefan Wagner
	@date Fr 7. Aug 13:44:45 CEST 2009
*/
public class MultipanelLayout extends JFrame implements ActionListener
{
	public MultipanelLayout ()
	{
		super ("demo 0.1");
		JPanel mainpanel = new JPanel ();
		mainpanel.setLayout (new BoxLayout (mainpanel, BoxLayout.PAGE_AXIS));
		this.getContentPane ().add (mainpanel);

		mainpanel.add (jpNorth ());
		JPanel jpTal = new JPanel ();
		jpTal.setLayout (new BoxLayout (jpTal, BoxLayout.PAGE_AXIS));	
		jpTal.add (taL ("Label 1"));
		jpTal.add (taL ("Laber 2"));
		mainpanel.add (jpTal);
		mainpanel.add (jpButtons ());
		
		setSize (400, 400);
		setLocation (100, 100);
		setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		center ();
		setVisible (true);
	}

	private JPanel jpNorth ()
	{
		JPanel jp = new JPanel ();
		jp.setLayout (new BorderLayout ());
		jp.add (new JLabel ("<html>Dies ist ein ziemlich großes <br /> JLabel. <br /> Dies ist ein ziemlich großes JLabel. Dies ist ein ziemlich großes <br /> JLabel. Dies ist ein ziemlich großes <br /> JLabel.</html>"), BorderLayout.CENTER);	
		jp.add (labeledField ("JText mit ausreichender Höhe"), BorderLayout.SOUTH);
		return jp;
	}

	private JPanel labeledField (String label)
	{
		JPanel jp = new JPanel ();
		jp.setLayout (new BoxLayout (jp, BoxLayout.PAGE_AXIS));	
		jp.add (new JLabel (label));
		jp.add (Box.createVerticalGlue());
		jp.add (new JTextField (label));
		jp.add (Box.createVerticalGlue());
		return jp;
	}
	
	private JPanel taL (String label) 
	{
		JPanel jp = new JPanel ();
		jp.setLayout (new BorderLayout ());
		jp.add (new JLabel (label), BorderLayout.NORTH);
		jp.add (new JTextArea (), BorderLayout.CENTER);
		return jp;
	}

	private JPanel jpButtons ()
	{
		JPanel jp = new JPanel ();
		jp.setLayout (new BoxLayout (jp, BoxLayout.LINE_AXIS));
		JButton fs = new JButton ("fontsize");
		fs.addActionListener (this);
		JButton ex = new JButton ("exit");
		ex.addActionListener (this);
		jp.add (fs);
		jp.add (ex);
		return jp;
	}

	private void center ()
	{
		Toolkit tk = Toolkit.getDefaultToolkit ();
		Dimension screen = tk.getScreenSize ();
		Dimension d = getSize ();
		setLocation ((screen.width - d.width) / 2, (screen.height - d.height) / 2);
	}

	public static void main (String args[])
	{
		new MultipanelLayout ();
	}

	@Override
	public void actionPerformed (ActionEvent e)
	{
		String cmd = e.getActionCommand ();
		if (cmd.equals ("exit"))
		{
			dispose ();
		}
		else 
		{
			f = getFont ();
			float fsize = f.getSize2D ();
			f = f.deriveFont (1.2f * fsize);
			decorate (this);
			pack ();
		}
	}
	
	private Font f;
	
	private void decorate (Component jc) 
	{
		jc.setFont (f);
		if (jc instanceof Container)
		{
			Container con = (Container) jc;
			Component[] ca = con.getComponents ();
			for (Component c : ca)
			{
				decorate (c);
			}
		}
	}
}

Für verschiebbare Grenzen kannst Du eine JSplitPane nehmen wenn ich mich recht erinnere.

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

ich glaube ich geb die Sache mit den GUIs erstmal fuer eine Weile auf. es wird scheinbar eh nicht funktionieren.

Das Script was du gepostet hat funktioniert leider nicht, und zudem sind zu viele Sachen drin, die ich nicht verstehe.

Was bedeutet dieses "@Override"? (da wird bei mir eine Fehlermeldung angezeigt)

eine weitere Fehlermeldung bekomme ich bei "for (Component c : ca)"

wann man "extends" verwendet anstatt einfach eine bestehende Klasse zu verwenden (was ja irgendwie aufs gleiche rauskommt, oder auch nicht) ist mir auch noch nicht klar.

Mein letzter Versuch den ich unternommen hatte war, dass ich vertical Boxes erzeugt habe, die jeweils ein Object enthielten. (ich glaube was aehnliches hatte ich auch gepostet). Ich glaube in der Zwischenzeit ist es mir total egal, wo die Texte und die Boxen stehen, meinetwegen alles untereinander. Nur sollen sich z.B diese JTextFields nicht vergroessern. die sind doch einzeilig. die Sollen einfach einzeilig bleiben egal welche Schriftgroesse da oder wie gross das Komplette fenster ist. Und wenn das Fenster Groesser wird, dann sollen zweit textfelder diesen Groessenunterschied ausgleichen. Ich hatte gerade versucht in ein Dimension Objekt eine Groesse zu schreiben,, so dann die den maximalen Platz einnehmen,... aber erfolgreich war ich damit nicht.

Egal, ich versuche es in 2 monaten nochmal

Riddle

Avatar von Riddle

Anmeldungsdatum:
27. Juli 2007

Beiträge: 201

Wohnort: 127.0.0.1

Scheinbar verwendest du ein relativ altes JDK, weil die angegebene for-Schleife mit JDK 1.5 eingeführt wurde (zur Zeit sollte irgendetwas in der Größenordnung 1.6 aktuell sein).

@Override kennzeichnet Methoden, die man von anderen Klassen bzw. Interfaces geerbt hat.

Eine weitere Möglichkeit wäre übrigens auch noch GridBagLayout als Layoutmanager zu verwenden, damit kann man eigentlich relativ gute Oberflächen erstellen. Allerdings ist das nicht besonders angenehm zu programmieren weshalb ich persönlich meistens auf eine Kombination aus FlowLayout, GridLayout und BorderLayout ausweiche.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Hast Du noch Java-1.4?

java -version

bringt es an den Tag.

dersven

(Themenstarter)

Anmeldungsdatum:
16. August 2005

Beiträge: 792

Wohnort: Kreuzlingen, Schweiz

java version "1.6.0_0"
OpenJDK Runtime Environment (IcedTea6 1.4.1) (6b14-1.4.1-0ubuntu10)
OpenJDK 64-Bit Server VM (build 14.0-b08, mixed mode)

in eclipse habe ich auch keine extra einstellungen vorgenommen

xabbuh Team-Icon

Anmeldungsdatum:
25. Mai 2006

Beiträge: 6411

Riddle

Avatar von Riddle

Anmeldungsdatum:
27. Juli 2007

Beiträge: 201

Wohnort: 127.0.0.1

Da muss irgendwo anders der Wurm drin sein. Ich hab grad mal alles komplett auf OpenJDK umgestellt und da funktioniert das Beispiel perfekt.

Was ich mir vorstellen könnte ist, dass eventuell gcj als Compiler eingestellt ist.

Bitte mal mit

sudo update-alternatives --config javac

auf eine aktuelle Version umstellen.

Antworten |