Prozent basierender LayoutManager

Ich bräuchte einen LM, welche die Komponenten nach Prozentangaben Platz vorgibt.
Zum Beispiel:

add(panel, "25%"); // 25 % des vorhandenen Platzes

add(panel, "*"); // Rest des Platzes

Das sind so die Funktionen die ich bräuchte.
Habe mir gedacht den kannste auch selber schreiben, dabn hast du auch mal einen gemacht.

Gut, gesagt getan. Klasse erstellt, LayoutManager2 implementieren…
Nun haperts aber an dem ausrichten der Komponenten. Ich weiß leider nicht wie ich festlegen soll, dass die Komponenten eben nur diese 25% kriegen und nicht mehr oder weniger. Es soll bämlich auch möglich sein zu sagen, dass die 1.Komponente 25% kriegt, die zweite 30%, die dritte 10% und die vierte den Rest.

Hoffe mal ihr habt ne Idee, wie ich das machen könnte.
Danke im voraus,

groggy

Ist wohl ein recht häufiger Wunsch: Suche nach „java percentlayout“ liefert erwartungsgemäß etliche Ergebnisse, einmal JavaDoc, willkürlich:
http://jalbum.net/api/se/datadosen/component/buttonbar/PercentLayout.html
sieht dem, was du suchst, schon SEHR ähnlich :wink: Eine konkrete Empfehlung kann ich nicht geben, aber… man findet da doch sicher was passendes darunter?

Ja das Problem ist das ich für einen LayoutManager net ne ganze lib voller neuen Swing Komponenten einbinden will die ich so oder so nicht brauchen werde… Das iat unnötiger “Balast”, den man net umbedingt braucht.
Das habe ich auch gefunden. Viele der dort vorgestelltwn LayoutManagern(sind eigentlich nur zwei, die sich immer wieder auf anderen Seiten befinden), wursen zuletzt 2007 gewartet. Sie besitzen noch keibe Generics und weiteren Schnick Schnack. Darum dachte ich mir man könnte es auch selber schreiben.

Spontan wüßte ich nicht, wo ein LayoutManager Generics verwenden sollte. Wenn die seit 2007 “fertig” sind und perfekt funktionieren, ist ja alles OK (ich will nicht wissen, wann das GridLayout zuletzt geändert wurde ;)). Aber zugegeben, ich habe mir die noch nicht alle angesehen, dewegen kann ich das natürlich nicht im Detail beurteilen.

MigLayout ist recht bekannt, und scheint auch Prozente zu unterstützen ( http://migcalendar.com/miglayout/cheatsheet.html ), aber vielleicht kann ja noch jemand eine konkretere Empfehlung geben.

Zu Generics:
Es wird intern mit Hastable gearbeitet(ist die net langsamer als HashMap zB?). Da muss gecastet werden bis zum Umfallen -_-

Edit:
Das Layout ist auch net Thread sicher, da es keinen tree-lock durchführt. So könnten dann im EDT ArrayIndexOutOfBoundsExceptions fliegen(ich meine es waren diese Exceptions)…

Ich kann leider den Ersteller der Klasse PercentLayout aus dem Projekt l2fprob nicht kontaktieren(e-mail geht net),also wollte ixh noch was kleines Fragen:
Wenn ich die Klasse kopiere und dann überarbeite um sie zB Thread-Safe zu machen und dann veröffnentliche(wenn dann unter Apache 2 wie die Klasse an sich) aber erwähne, dass dies eine verbesserte Version der Klasse XXX ist, habe ich rechtliche Konsequenzen zu befürchten?

Ich weiß nicht, auf welches Projekt du dich genau beziehst, aber die Apache License ist sehr liberal. Bei genauren Infos dürfen gerne die Rechtsexperten vorpreschen (deren Anzahl hier kürzlich sprunghaft gestiegen ist :smiley: ), aber soweit ich weiß (!) ist es kein Problem, wenn du unmißverständlich sagst, welches die Original-Version (inkl. Copyright+Lizenz) ist, und dass du darauf aufgebaut hast.

IANAL
aber:
Kapitel 4

Was soll IANAL heißen?
Ok habs mir mal durchgelesen, aind ja nur ein paar Sachen zu beachten…

I
Am
Not
A
Lawyer

Nix schweinisches :smiley:

Ok die Arkürzung ist mir neu :slight_smile:

Ein möglicher Ansatz eines eigenen LayoutManagers wäre folgender - wie immer ohne Gewährleistung :wink: Kann aber sein, dass er sich unterbestimmten Umständen merkwürdig verhält.

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager2;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PercentLayoutDemo {
	public static void main(String[] s) {
		JPanel panel = new JPanel(new PercentLayout());
		JLabel label = new JLabel("Test OUT");
		label.setOpaque(true);
		label.setBackground(Color.GREEN);
		panel.add(label, .25);
		JPanel inner = new JPanel(new PercentLayout(PercentLayout.VERTICAL));
		panel.add(inner);
		
		label = new JLabel("Test Out");
		label.setOpaque(true);
		label.setBackground(Color.BLUE);
		panel.add(label, .35);
		
		label = new JLabel("Test IN");
		label.setOpaque(true);
		label.setBackground(Color.ORANGE);
		inner.add(label, .5);
		label = new JLabel("Test IN");
		label.setOpaque(true);
		label.setBackground(Color.DARK_GRAY);
		inner.add(label, .1);
		label = new JLabel("Test IN REST");
		label.setOpaque(true);
		label.setBackground(Color.YELLOW);
		inner.add(label);
		
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(panel);
		frame.setBounds(0, 0, 200, 200);
		frame.setVisible(true);
	}
}

class PercentLayout implements LayoutManager2 {
	public static final int HORIZONTAL = 0;
	public static final int VERTICAL = 1;

	private int orientation;
	private double sum;
	private List<Component> components;
	private List<Double> weights;

	public PercentLayout() {
		this(HORIZONTAL);
	}

	public PercentLayout(int orientation) {
		this.orientation = orientation;
		this.components = new ArrayList<Component>();
		this.weights = new ArrayList<Double>();
	}

	public Dimension preferredLayoutSize(Container parent) {
		synchronized (parent.getTreeLock()) {
			int w = 0, h = 0;
			for (Component c: components) {
				w += c.getPreferredSize().width;
				h += c.getPreferredSize().height;
			}
			return new Dimension(w, h);
		}
	}

	public Dimension minimumLayoutSize(Container parent) {
		synchronized (parent.getTreeLock()) {
			int w = 0, h = 0;
			for (Component c: components) {
				w += c.getMinimumSize().width;
				h += c.getMinimumSize().height;
			}
			return new Dimension(w, h);
		}
	}

	public void layoutContainer(Container parent) {
		synchronized (parent.getTreeLock()) {
			int w = parent.getWidth();
			int h = parent.getHeight();
			
			if (this.orientation == HORIZONTAL) {
				int x = 0;
				for (int i=0; i<components.size() ; i++) {
					Component c = components.get(i);
					double weight = weights.get(i);
					int width = (int)(w*weight);
					if (weight==0d)
						width = (int)(w - w*sum);
					c.setBounds(x, 0, width, h);
					x += width;
				}
			}
			else {
				int y = 0;
				for (int i=0; i<components.size() ; i++) {
					Component c = components.get(i);
					double weight = weights.get(i);
					int height= (int)(h*weight);
					if (weight==0d)
						height = (int)(h - h*sum);
					c.setBounds(0, y, w, height);
					y += height;
				}
			}
		}
	}

	public void addLayoutComponent(Component comp, Object constraints) {
		if (constraints instanceof Double) {
			double val = (Double) constraints;
			sum = 0;
			for (Double d : weights) {
				sum += d;
			}
			if (sum + val > 1) {
				throw new IllegalArgumentException(String.format("Not enough space left. Available %.1f%% , requested %.1f%%", (1-sum)*100, val*100));
			}
			components.add(comp);
			weights.add(val);
			sum += val;
		} else if (constraints == null) {
			if (weights.contains(0d)) {
				throw new IllegalArgumentException("Component weight zero already existing");
			}
			else {
				this.addLayoutComponent(comp, 0d);
			}
		} else {
			throw new IllegalArgumentException("Only double values supported");
		}
		
	}

	public Dimension maximumLayoutSize(Container target) {
		return this.preferredLayoutSize(target);
	}

	public float getLayoutAlignmentX(Container target) {
		return 0;
	}

	public float getLayoutAlignmentY(Container target) {
		return 0;
	}

	public void addLayoutComponent(String name, Component comp) {
		throw new IllegalArgumentException(
				"add(String, Component) ist not supported. Use add(Component, Object) or just add(Component) instead!");
	}

	public void invalidateLayout(Container target) {}

	public void removeLayoutComponent(Component comp) {}
}```

Danke :smiley: