GridBagLayout - Anfängerprobleme

Status
Nicht offen für weitere Antworten.

Tobias

Top Contributor
Hallo,

ich baue zum ersten Mal eine Struktur mit GridBagLayout zusammen. Das Ergebnis soll eine Tastatur darstellen, die dieser hier in etwa ähnelt:

skb.gif

(Schattierungen, Zahlen und die grauen Linien bitte ignorieren, die sind nur zu Dokuzwecken da)

Ich habe mich zunächst einmal an den Buchstabenblock begeben und dort ein bißchen rumgebastelt (so Sachen wie die Abstände etc interessieren mich gerade weniger, wichtig ist erstmal nur die korrekte Ausrichtung). Da ich (wie oben zu sehen) einige Buttons habe, die eine halbe Buttonbreite in die nächste Spalte hineinragen, habe ich mir ein Raster hinter den Buttons vorgestllt, dessen Spaltenbreite halb so groß ist wie die Breite eines Buttons und dessen Zeilenhöhe der Höhe eines normalen Buttons entspricht.

So bin ich bis hierher gekommen:

skb-ist.gif

(die roten Rechtecke habe ich später zur Verdeutlichung der Probleme eingezeichnet, die weißen Quadrate mit rotem Kreuz sind Standardicons, die gewählt werden, wenn eine Grafik fehlt - einfach ignorieren)

Wie an den roten Rechtecken zu erkennen ist, gibt es ein paar Probleme. Beispielsweise wird der Versatz von einer halben Buttonbreite zwischen der zweiten und der dritten Reihe nicht umgesetzt. Verantwortlich sind die zu breiten Buttons "Q" und """. Der Enter-Button ist zu breit, dafür aber nicht hoch genug - dafür ist der "-"-Button viel zu lang, der nimmt den "freigehaltenen" Platz des Enter-Buttons ein. Der Delete-Button ist glaube ich korrekt, der scheinbare Fehler wird hier wohl durch den fehlenden Versatz links ausgelöst.

Hier noch der Code, mit dem ich das Layout zusammenbaue:

Code:
private void initKeyBoard() {
		setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.gridheight = 1;
		c.gridwidth = 2;
		c.fill = GridBagConstraints.BOTH;

		// First row
		add(layout.getButton(0, 0), c); // Button links oben - layout.getButton(Spalte, Zeile)
		add(layout.getButton(1, 0), c);
		add(layout.getButton(2, 0), c);
		add(layout.getButton(3, 0), c);
		add(layout.getButton(4, 0), c);
		add(layout.getButton(5, 0), c);
		add(layout.getButton(6, 0), c);
		add(layout.getButton(7, 0), c);
		add(layout.getButton(8, 0), c);
		add(layout.getButton(9, 0), c);
		add(layout.getButton(10, 0), c);
		add(layout.getButton(11, 0), c);
		add(layout.getButton(12, 0), c);
		c.gridwidth = GridBagConstraints.REMAINDER;
		add(layout.getButton(13, 0), c);

		// second row
		c.gridwidth = 2;
		add(layout.getButton(0, 1), c);
		add(layout.getButton(1, 1), c);
		add(layout.getButton(2, 1), c);
		add(layout.getButton(3, 1), c);
		add(layout.getButton(4, 1), c);
		add(layout.getButton(5, 1), c);
		add(layout.getButton(6, 1), c);
		add(layout.getButton(7, 1), c);
		add(layout.getButton(8, 1), c);
		add(layout.getButton(9, 1), c);
		add(layout.getButton(10, 1), c);
		add(layout.getButton(11, 1), c);
		c.gridwidth = GridBagConstraints.REMAINDER;
		add(delete, c);

		// third row
		c.gridwidth = 3;
		add(shiftLock, c);
		c.gridwidth = 2;
		add(layout.getButton(1, 2), c);
		add(layout.getButton(2, 2), c);
		add(layout.getButton(3, 2), c);
		add(layout.getButton(4, 2), c);
		add(layout.getButton(5, 2), c);
		add(layout.getButton(6, 2), c);
		add(layout.getButton(7, 2), c);
		add(layout.getButton(8, 2), c);
		add(layout.getButton(9, 2), c);
		add(layout.getButton(10, 2), c);
		add(layout.getButton(11, 2), c);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.gridheight = 2;
		add(enter, c);

		// fourth row
		c.gridwidth = 5;
		add(shift, c);
		c.gridwidth = 2;
		add(layout.getButton(2, 3), c);
		add(layout.getButton(3, 3), c);
		add(layout.getButton(4, 3), c);
		add(layout.getButton(5, 3), c);
		add(layout.getButton(6, 3), c);
		add(layout.getButton(7, 3), c);
		add(layout.getButton(8, 3), c);
		add(layout.getButton(9, 3), c);
		add(layout.getButton(10, 3), c);
		c.gridwidth = GridBagConstraints.REMAINDER;
		add(layout.getButton(11, 3), c);

		// fifth row
		c.gridwidth = GridBagConstraints.REMAINDER;
		add(space, c);
	}

Mein komplettes Testprogramm zu posten würde wohl etwas weitgehen. Ich hoffe, ihr kommt mit obigem Code klar, das Objekt "layout" wird jeweils um den Button an der gegebenen Stelle gebeten, die Parameter bedeuten (Spalte, Zeile). Wie kann ich die oben beschriebenen Fehler beheben? Ist mein Ansatz beim Umgang mit dem GridBagLayout überhaupt vernünftig?

mpG
Tobias
 
der Enter-Button scheint nicht so definiert zu sein, dass er zwei Zeilen belegt,
ohne Code kann man da nix genaues zu sagen,

---

zur Ecke Ä - Delete - Enter:
Grid-Linien sind gerade und durchgängig, da gibt es keinen Versatz,
Spalte 13 musst du also in zwei Spalten aufteilen,

ach das gilt ja für die gesamte Zeile 3, übel 😉
wahrscheinlich ist es dann besser, da ein neues unteres JPanel mit eigenen GridLayout anzulegen

> Wie an den roten Rechtecken zu erkennen ist, gibt es ein paar Probleme. Beispielsweise wird der Versatz von einer halben Buttonbreite zwischen der zweiten und der dritten Reihe nicht umgesetzt

wie glaubst du es denn in deinem Programm bisher lösen zu können?

----------

> add(layout.getButton(6, 2), c);
> add(layout.getButton(7, 2), c);
> add(layout.getButton(8, 2), c);
> add(layout.getButton(9, 2), c);
....


Tipp zur Verkürzung: schreibe dir eine Hilfsoperation, so dass du nur noch
add(6, 2, c);
add(7, 2, c);
add(8, 2, c);
add(9, 2, c);
schreiben musst,

oder wenn das layout als Parameter unverzichtbar ist, dann zumindest
add(layout, 6, 2, c);
add(layout, 7, 2, c);
add(layout, 8, 2, c);
add(layout, 9, 2, c);
 
@Marco13: Mit TableLayout habe ich noch nicht gearbeitet, ich gucke es mir gerade mal an.

@SlaterB: Mein Grid für das Layout besitzt Spalten mit einer Breite von einer halben Buttonbreite. Deshalb habe ich ganz am Anfang der Methode c.gridwidth auf 2 gesetzt. Dies ändere ich für die einzelnen Funktionstasten auf ihre entsprechenden Werte.
Beim Enter-Button habe ich gridheight auf 2 gesetzt, damit ist doch die Definition "sei zwei Zeilen hoch" abgeschlossen, oder?
Mittlerweile benutze ich Hilfsfunktionen, um mir das ständige Ändern der GridBagConstraints zu vereinfachen. Das fand ich weit anstrengender, als das bißchen layout.getButton(x, y), welches IMHO zusätzlich auch zur Lesbarkeit beiträgt. Aber danke für den Hinweis 😉.

mpG
Tobias
 
> damit ist doch die Definition "sei zwei Zeilen hoch" abgeschlossen, oder?

mag sein, setzt du aber die Höhe für die anderen Elemente wieder auf 1 zurück oder sind alle dann 2 hoch?
sorgst du dafür, dass in der nächsten Zeile die Zelle direkt darunter frei bleibt?

grundsätzlich würde ich zur Sicherheit auch empfehlen, ein eigenes c-Objekt pro Button anzulegen,
(auch wenn es in diesem Fall nicht nötig ist)

ohne lauffähigen Code kann man aber bei allem nur raten,
 
Ok, ich hab mal zwei JARs gezaubert, die nicht nur lauffähig sind (sein sollten, getestet auf XP Prof), sondern auch den Quellcode enthalten. Es ist allerdings ziemlich viel Quellcode - der interessante Teil ist aber in der Klasse ScreenKeyBoard konzentriert (de.tobiasdemuth.cube.xul.renderer.basic.swing.fa.keyboard.ScreenKeyBoard), speziell in der Methode initKeyBoard() und ein bißchen in add(Component, int, int) und add(Component, int, int, int, int).

Die beiden JARs müssen im selben Ordner liegen, gestartet werden kann nur die keyboard.jar.

mpG
Tobias

P.S.: commons.jar: http://www.java-forum.org/de/userfiles/user497/commons.jar
keyboard.jar: http://www.java-forum.org/de/userfiles/user497/keyboard.jar
 
also ich warte darauf, bis du ein 150-Zeilen Programm hier im Forum postest :bae:
 
So, hat zwar knapp 200 Zeilen, aber wenn du die Kommentare streichst, kommt es in etwa hin 😉:

Code:
public class KeyBoardLayoutTest extends JFrame {

	GridBagConstraints constraints = new GridBagConstraints();

	public KeyBoardLayoutTest() {
		super("KeyBoardLayoutTest");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		initKeyBoard();

		pack();
		setVisible(true);
	}

	/**
	 * Initializes the graphical representation of the keyboard.
	 */
	private void initKeyBoard() {
		setLayout(new GridBagLayout());

		// First row
		add("!", 0, 0);
		add("\"", 2, 0);
		add("§", 4, 0);
		add("$", 6, 0);
		add("%", 8, 0);
		add("&", 10, 0);
		add("/", 12, 0);
		add("(", 14, 0);
		add(")", 16, 0);
		add("=", 18, 0);
		add("?", 20, 0);
		add("#", 22, 0);
		add("€", 24, 0);
		add("ß", 26, 0);
		// Num-block
		add(",", 32, 0);
		add("/", 34, 0);
		add("*", 36, 0);
		add("-", 38, 0);

		// second row
		add("@", 0, 1);
		add("Q", 2, 1);
		add("W", 4, 1);
		add("E", 6, 1);
		add("R", 8, 1);
		add("T", 10, 1);
		add("Z", 12, 1);
		add("U", 14, 1);
		add("I", 16, 1);
		add("O", 18, 1);
		add("P", 20, 1);
		add("Ü", 22, 1);
		add("Delete", 24, 1, 4, 1);
		// Num-block
		add("7", 32, 1);
		add("8", 34, 1);
		add("9", 36, 1);
		add("+", 38, 1, 2, 2);

		// third row
		add("Lock", 0, 2, 3, 1);
		add("A", 3, 2);
		add("S", 5, 2);
		add("D", 7, 2);
		add("F", 9, 2);
		add("G", 11, 2);
		add("H", 13, 2);
		add("J", 15, 2);
		add("K", 17, 2);
		add("L", 19, 2);
		add("Ö", 21, 2);
		add("Ä", 23, 2);
		add("Enter", 25, 2, 3, 2);
		// Num-Block
		add("4", 32, 2);
		add("5", 34, 2);
		add("6", 36, 2);

		// fourth row
		add("Shift", 0, 3, 5, 1);
		add("Y", 5, 3);
		add("X", 7, 3);
		add("C", 9, 3);
		add("V", 11, 3);
		add("B", 13, 3);
		add("N", 15, 3);
		add("M", 17, 3);
		add(",", 19, 3);
		add(".", 21, 3);
		add("-", 23, 3);
		add("^", 28, 3);
		// Num-Block
		add("1", 32, 3);
		add("2", 34, 3);
		add("3", 36, 3);
		add("Ent", 38, 3, 2, 2);

		// fifth row
		add("Space", 0, 4, 26, 1);
		add("<", 26, 4);
		add("v", 28, 4);
		add(">", 30, 4);
		// Num-Block
		add("0", 32, 4, 4, 1);
		add("Del", 36, 4);
	}

	/**
	 * Resets the constraints-object.
	 * 
	 * @return the resetted constraints-object.
	 */
	private GridBagConstraints resetConstraints() {
		constraints.anchor = GridBagConstraints.CENTER;
		constraints.fill = GridBagConstraints.BOTH;
		constraints.gridheight = 1; // A normal button spans one row
		constraints.gridwidth = 2; // and two columns
		constraints.gridx = GridBagConstraints.RELATIVE;
		constraints.gridy = GridBagConstraints.RELATIVE;
		constraints.insets = new Insets(0, 0, 0, 0);
		constraints.ipadx = 10; // Just to provide a nicer layout
		constraints.ipady = 10;
		constraints.weightx = 0;
		constraints.weighty = 0;

		return constraints;
	}

	/**
	 * Adds the given component at the specified position to the grid.
	 * 
	 * @param text
	 *            the text for the label to add.
	 * @param column
	 *            the column the left edge of the component should lay in.
	 * @param row
	 *            the row the left upper edge of the component should lay in.
	 */
	private void add(String text, int column, int row) {
		resetConstraints();
		constraints.gridx = column;
		constraints.gridy = row;

		JLabel l = new JLabel(text);
		l.setHorizontalAlignment(SwingConstants.CENTER);
		l.setOpaque(true);
		l.setBackground(Color.WHITE);
		l.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));

		add(l, constraints);
	}

	/**
	 * Adds a component at the specified position with given width and height.
	 * 
	 * @param text
	 *            the text for the JLabel to add.
	 * @param column
	 *            the column the upper left edge of the component should be
	 *            placed in.
	 * @param row
	 *            the row the upper left edge of the component should be placed
	 *            in.
	 * @param width
	 *            how much columns should the component span
	 * @param height
	 *            how much rows should the component span
	 */
	private void add(String text, int column, int row, int width, int height) {
		resetConstraints();
		constraints.gridx = column;
		constraints.gridy = row;
		constraints.gridwidth = width;
		constraints.gridheight = height;

		JLabel l = new JLabel(text);
		l.setHorizontalAlignment(SwingConstants.CENTER);
		l.setOpaque(true);
		l.setBackground(Color.WHITE);
		l.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));

		add(l, constraints);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new KeyBoardLayoutTest();
	}

}

Die Probleme sind die selben wie oben angesprochen - der Enter-Button ist zu breit (dafür mittlerweile aber zwei Zeilen hoch) und der Versatz zwischen zweiter und dritter Zeile fehlt.

Wäre toll, wenn du mir einen Tipp geben könntest, was hier verkehrt ist ...

mpG
Tobias
 
die Buttons sind nun zwar schön versetzt, allerdings trickst Java dich aus:
die Spalten sind abwechselnd 50 Pixel und 1 Pixel breit, so dass kein Versatz zu erkennen ist

ich habe mal eine Taktgeber-Zeile unten eingebaut,
wie man das ansonsten schöner lösen kann weiß ich nicht

bin immer noch dafür, zwei unterschiedliche JPanel für diese Bereiche zu nehmen,
so dass 90% der Buttons genau eine Zelle belegen, nur Enter & Co. mehr,
bei dir sind ja ALLE zwei Felder breit..


-----

die drei Zeilen, die die Enter-Taste belegt, sind auch dann noch z.T. überproportioal breit, weil der Text 'Enter' reinpassen muss,
wenn du dem ganzen Layout genug Platz gibt, dann sind wieder alle Spalten gleich breit


-----

Code:
public class KeyBoardLayoutTest
    extends JFrame
{

    GridBagConstraints constraints = new GridBagConstraints();

    public KeyBoardLayoutTest()
    {
        super("KeyBoardLayoutTest");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        initKeyBoard();

        setSize(800, 300);
        setVisible(true);
    }

    /**
     * Initializes the graphical representation of the keyboard.
     */
    private void initKeyBoard()
    {
        setLayout(new GridBagLayout());

        // First row
        add2("!", 0, 0);
        add2("\"", 2, 0);
        add2("§", 4, 0);
        add2("$", 6, 0);
        add2("%", 8, 0);
        add2("&", 10, 0);
        add2("/", 12, 0);
        add2("(", 14, 0);
        add2(")", 16, 0);
        add2("=", 18, 0);
        add2("?", 20, 0);
        add2("#", 22, 0);
        add2("€", 24, 0);
        add2("ß", 26, 0);
        // Num-block
        add2(",", 32, 0);
        add2("/", 34, 0);
        add2("*", 36, 0);
        add2("-", 38, 0);

        // second row
        add2("@", 0, 1);
        add2("Q", 2, 1);
        add2("W", 4, 1);
        add2("E", 6, 1);
        add2("R", 8, 1);
        add2("T", 10, 1);
        add2("Z", 12, 1);
        add2("U", 14, 1);
        add2("I", 16, 1);
        add2("O", 18, 1);
        add2("P", 20, 1);
        add2("Ü", 22, 1);
        add("Delete", 24, 1, 4, 1);
        // Num-block
        add2("7", 32, 1);
        add2("8", 34, 1);
        add2("9", 36, 1);
        add("+", 38, 1, 2, 2);

        // third row
        add("Lock", 0, 2, 3, 1);
        add2("A", 3, 2);
        add2("S", 5, 2);
        add2("D", 7, 2);
        add2("F", 9, 2);
        add2("G", 11, 2);
        add2("H", 13, 2);
        add2("J", 15, 2);
        add2("K", 17, 2);
        add2("L", 19, 2);
        add2("Ö", 21, 2);
        add2("Ä", 23, 2);
        add("Enter", 25, 2, 3, 2);
        // Num-Block
        add2("4", 32, 2);
        add2("5", 34, 2);
        add2("6", 36, 2);

        // fourth row
        add("Shift", 0, 3, 5, 1);
        add2("Y", 5, 3);
        add2("X", 7, 3);
        add2("C", 9, 3);
        add2("V", 11, 3);
        add2("B", 13, 3);
        add2("N", 15, 3);
        add2("M", 17, 3);
        add2(",", 19, 3);
        add2(".", 21, 3);
        add2("-", 23, 3);
        add2("^", 28, 3);
        // Num-Block
        add2("1", 32, 3);
        add2("2", 34, 3);
        add2("3", 36, 3);
        add("Ent", 38, 3, 2, 2);

        // fifth row
        add("Space", 0, 4, 26, 1);
        add2("<", 26, 4);
        add2("v", 28, 4);
        add2(">", 30, 4);
        // Num-Block
        add("0", 32, 4, 4, 1);
        add2("Del", 36, 4);

        for (int i = 0; i < 40; i++)
        {
            add1("", i, 5);
        }

    }

    private GridBagConstraints resetConstraints()
    {
        constraints.anchor = GridBagConstraints.CENTER;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.gridheight = 1; // A normal button spans one row
        constraints.gridwidth = 2; // and two columns
        constraints.gridx = GridBagConstraints.RELATIVE;
        constraints.gridy = GridBagConstraints.RELATIVE;
        constraints.insets = new Insets(0, 0, 0, 0);
        constraints.ipadx = 10; // Just to provide a nicer layout
        constraints.ipady = 10;
        constraints.weightx = 0;
        constraints.weighty = 0;

        return constraints;
    }

    private void add1(String text, int column, int row)
    {
        resetConstraints();
        constraints.gridx = column;
        constraints.gridy = row;
        constraints.gridwidth = 1;
        constraints.weightx = 1;

        JLabel l = new JLabel(text);
        l.setHorizontalAlignment(SwingConstants.CENTER);
        l.setOpaque(true);
        l.setBackground(Color.WHITE);
        l.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));

        add(l, constraints);
    }

    private void add2(String text, int column, int row)
    {
        resetConstraints();
        constraints.gridx = column;
        constraints.gridy = row;

        JLabel l = new JLabel(text);
        l.setHorizontalAlignment(SwingConstants.CENTER);
        l.setOpaque(true);
        l.setBackground(Color.WHITE);
        l.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));

        add(l, constraints);
    }

    private void add(String text, int column, int row, int width, int height)
    {
        resetConstraints();
        constraints.gridx = column;
        constraints.gridy = row;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = width;

        JLabel l = new JLabel(text);
        l.setHorizontalAlignment(SwingConstants.CENTER);
        l.setOpaque(true);
        l.setBackground(Color.WHITE);
        l.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));

        add(l, constraints);
    }

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

}
 
ich denke mal, dass sich für so etwas ein eigener LayoutManager lohnen könnte. Mit den StandardManagern kriegt man das nie so genau hin.
Hier mal ein unvollständiges aber kompilierbares Bsp. Es hat sicherlich noch Optimierungspotetial.
Code:
import java.awt.*;
import javax.swing.*;

public class KeyBoardLayout extends JPanel implements LayoutManager {
	private double ratio = 0.8d; //gewünschtes Seitenverhältnis einer Taste Hoehe/Breite
	private double inGap = 0.3d; //relativer Versatz von Zeile 3 und 4
	
	private JButton[] buttonLine1 = new JButton[14];
	private String[] bL1String = new String[] {"!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "#", "€", "ß"};
	private JButton[] buttonLine2 = new JButton[12];
	private String[] bL2String = new String[] {"@", "Q", "W", "E", "R", "T", "Z", "U", "I", "O", "P", "Ü"};
	private JButton[] buttonLine3 = new JButton[11];
	private String[] bL3String = new String[] {"A", "S", "D", "F", "G", "H", "J", "K", "L", "Ö", "Ä"};
	
	private JButton delButton = new JButton("Delete");
	private JButton shiftLockButton = new JButton("v");
	private JButton shiftButton = new JButton("^");
	private JButton enterButton = new JButton("Enter");
	private JButton spaceButton = new JButton("Space");
	
	public KeyBoardLayout() {
		this.setLayout(this);
		for (int i=0; i<buttonLine1.length; i++) {
			buttonLine1[i] = new JButton(bL1String[i]);
			this.add(buttonLine1[i]);
		}
		for (int i=0; i<buttonLine2.length; i++) {
			buttonLine2[i] = new JButton(bL2String[i]);
			this.add(buttonLine2[i]);
		}
		for (int i=0; i<buttonLine3.length; i++) {
			buttonLine3[i] = new JButton(bL3String[i]);
			this.add(buttonLine3[i]);
		}
		this.add(delButton);
		this.add(shiftLockButton);
		this.add(shiftButton);
		this.add(enterButton);
		this.add(spaceButton);
	}
	
	private int standardWidth; // Variable für die optimale Breite normaler Tasten
	public void layoutContainer(Container container) {
		//Bestimmung der optimalen Breite
		if ((container.getBounds().getHeight()/5)/(container.getBounds().getWidth()/14)>ratio)
			standardWidth = container.getWidth()/14;
		else
			standardWidth = (int) (container.getHeight()/ratio/5);
		//Positionieren der einzelnen Tasten
		for (int i=0; i<buttonLine1.length; i++)
			buttonLine1[i].setBounds(i*standardWidth, 0, standardWidth, (int)(standardWidth*ratio));
		for (int i=0; i<buttonLine2.length; i++) {
			buttonLine2[i].setBounds(i*standardWidth, (int)(standardWidth*ratio), standardWidth, (int)(standardWidth*ratio));
		}
		for (int i=0; i<buttonLine3.length; i++) {
			buttonLine3[i].setBounds((i+1)*standardWidth +(int)(standardWidth*inGap), (int)(2*standardWidth*ratio), standardWidth, (int)(standardWidth*ratio));
		}
		
		delButton.setBounds(12*standardWidth, (int)(standardWidth*ratio), 2*standardWidth, (int)(standardWidth*ratio));
		shiftLockButton.setBounds(0, (int)(2*standardWidth*ratio), standardWidth + (int)(standardWidth*inGap), (int)(standardWidth*ratio));
		enterButton.setBounds(12*standardWidth +(int)(standardWidth*inGap), (int)(2*standardWidth*ratio), 2*standardWidth - (int)(standardWidth*inGap), 2*(int)(standardWidth*ratio));
		shiftButton.setBounds(0, (int)(3*standardWidth*ratio), 2*standardWidth + (int)(standardWidth*inGap), (int)(standardWidth*ratio));
		spaceButton.setBounds((int)(4.5d*standardWidth),4*(int)(standardWidth*ratio), 5*standardWidth, (int)(standardWidth*ratio));
	}
	public void removeLayoutComponent(Component arg0) {}
	public void addLayoutComponent(String arg0, Component arg1) {}
	public Dimension minimumLayoutSize(Container arg0) {return new Dimension(0,0);}
	public Dimension preferredLayoutSize(Container arg0) {return new Dimension(0,0);}
	
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(new KeyBoardLayout());
		frame.setBounds(50,50,600,250);
		frame.setVisible(true);
	}
}
 
Interessanter Ansatz. Ich bin aber gerade ganz glücklich mit der GridBagLayout-Sache und werde mich vorerst anderen Problemen meines Programms zuwenden. Aber wer weiß, ob ich nicht beim nächsten Refactoring auf diese Idee zurückkomme ...

mpG
Tobias
 
Ist bereits mit JButtons gelöst, es wird aber nur GridBagLayout verwendet und trifft deine Skizze sehr genau:
Code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class KeyboardPanel extends JPanel {

	public KeyboardPanel() {
		Insets i = new Insets(0, 0, 0, 0);
		GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, i, 0, 0);
		setLayout(new GridBagLayout());

		JPanel firstAndSecond = createFirstAndSecondRow();
		JPanel thirdAndFourth = createThirdAndFourthRow();
		JPanel fifth = createFifthRow();
		JPanel arrows = createArrowKeys();
		JPanel nums = createNumBock();
		add(firstAndSecond, c);
		c.gridy++;
		c.fill = GridBagConstraints.HORIZONTAL;
		add(thirdAndFourth, c);
		c.gridy++;
		add(fifth, c);
		c.gridx++;
		c.gridy = 0;
		c.gridheight = 3;
		c.fill = GridBagConstraints.VERTICAL;
		add(arrows, c);
		c.gridx++;
		c.fill = GridBagConstraints.NONE;
		add(nums, c);
		
	}

	private JPanel createFirstAndSecondRow() {
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());

		String[] firstRow = new String[] { "!", "\"", "§", "$", "%", "&", "/",
				"(", ")", "=", "?", "#", "€", "ß" };
		String[] secondRow = new String[] { "@", "Q", "W", "E", "R", "T", "Z",
				"U", "I", "O", "P", "Ü", "Delete" };

		Insets i = new Insets(1, 1, 1, 1);
		GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, i, 0, 0);

		for (int j = 0; j < firstRow.length; j++) {
			String s = firstRow[j];
			JButton jb = createButton(s, 25, 20);

			if (j == firstRow.length - 1)
				c.weightx = 1.0;
			p.add(jb, c);
			c.gridx++;
		}

		c.weightx = 0.0;
		c.gridx = 0;
		c.gridy++;

		for (int j = 0; j < secondRow.length - 1; j++) {
			String s = secondRow[j];
			JButton jb = createButton(s, 25, 20);
			p.add(jb, c);
			c.gridx++;
		}
		JButton jb = createButton(secondRow[secondRow.length - 1], 25, 20);
		c.gridwidth = 2;
		c.fill = GridBagConstraints.HORIZONTAL;
		p.add(jb, c);

		return p;
	}

	private JPanel createThirdAndFourthRow() {
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());
		String[] thirdRow = new String[] { "Lock", "A", "S", "D", "F", "G",
				"H", "J", "K", "L", "Ö", "Ä" };
		String[] fourthRow = new String[] { "Shift", "Y", "X", "C", "V", "B",
				"N", "M", ",", ".", "-" };

		Insets i = new Insets(1, 1, 1, 1);
		GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, i, 0, 0);

		JButton jb = createButton(thirdRow[0], 35, 20);
		p.add(jb, c);
		c.gridx++;
		for (int j = 1; j < thirdRow.length; j++) {
			String s = thirdRow[j];
			jb = createButton(s, 25, 20);
			p.add(jb, c);
			c.gridx++;
		}
		c.gridx = 0;
		c.gridy++;
		c.gridwidth = 2;
		c.fill = GridBagConstraints.HORIZONTAL;

		jb = createButton(fourthRow[0], 0, 20);
		p.add(jb, c);
		c.gridx += 2;
		c.gridwidth = 1;
		c.fill = GridBagConstraints.NONE;
		for (int j = 1; j < fourthRow.length; j++) {
			String s = fourthRow[j];
			jb = createButton(s, 25, 20);
			p.add(jb, c);
			c.gridx++;
		}

		jb = createButton("Enter", 0, 0);
		c.gridy = 0;
		c.gridheight = 2;
		c.fill = GridBagConstraints.BOTH;
		c.weightx = 1.0;
		c.weighty = 1.0;
		p.add(jb, c);

		return p;
	}

	private JPanel createFifthRow() {
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());

		Insets i = new Insets(1, 1, 1, 1);
		GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, i, 0, 0);

		JButton jb = createButton("Space", 150, 20);
		c.anchor = GridBagConstraints.NORTH;
		c.weightx = 1.0;

		p.add(jb, c);
		jb = createButton("<", 25, 20);
	
		c.anchor = GridBagConstraints.NORTHWEST;
		c.weightx = 0.0;
		c.gridx++;
		p.add(jb, c);

		return p;
	}
	
	private JPanel createArrowKeys() {
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());

		Insets i = new Insets(1, 1, 1, 1);
		GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, i, 0, 0);
		
		JButton jb = createButton("^", 25, 20);
		
		c.anchor = GridBagConstraints.SOUTHWEST;
		c.weighty = 1.0;
		p.add(jb, c);
		c.anchor = GridBagConstraints.NORTHWEST;
		c.weighty = 0.0;
		jb = createButton("v", 25, 20);
		c.gridy++;
		p.add(jb, c);
		jb = createButton(">", 25, 20);
		c.gridx++;
		p.add(jb, c);
		
		
		return p;
	}
	
	private JPanel createNumBock() {
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());

		Insets i = new Insets(1, 1, 1, 1);
		GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, i, 0, 0);
		
		String[] s = new String[]{",", "/", "*", "-", "7", "8", "9", "4", "5", "6", "1", "2", "3"};
		
		JButton jb = null;
		for(int j = 0; j < 4; j++){
			jb = createButton(s[j], 25, 20);
			p.add(jb, c);
			c.gridx++;
		}
		c.gridy++;
		c.gridx=0;
		for(int j = 4; j < 7; j++){
			jb = createButton(s[j], 25, 20);
			p.add(jb, c);
			c.gridx++;
		}
		c.gridy++;
		c.gridx=0;
		for(int j = 7; j < 10; j++){
			jb = createButton(s[j], 25, 20);
			p.add(jb, c);
			c.gridx++;
		}
		c.gridy++;
		c.gridx=0;
		for(int j = 10; j < 13; j++){
			jb = createButton(s[j], 25, 20);
			p.add(jb, c);
			c.gridx++;
		}
		
		jb = createButton("+", 25, 0);
		c.gridx = 3;
		c.gridy = 1;
		c.gridheight = 2;
		c.fill = GridBagConstraints.VERTICAL;
		p.add(jb, c);
		
		jb = createButton("0", 0, 20);
		c.gridx = 0;
		c.gridy = 4;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridwidth = 2;
		c.gridheight = 1;
		p.add(jb, c);
		
		jb = createButton("Entf", 0, 20);
		jb.setFont(new Font("Dialog", Font.PLAIN, 10));
		c.gridx = 2;		
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridwidth = 1;
		p.add(jb, c);
		
		jb = createButton("Enter", 25, 0);
		
		jb.setFont(new Font("Dialog", Font.PLAIN, 8));
		c.gridx = 3;		
		c.gridy = 3;
		c.fill = GridBagConstraints.VERTICAL;		
		c.gridheight = 2;
		p.add(jb, c);
		
		
		return p;
	}

	private JButton createButton(String s, int w, int h) {
		Dimension dim = new Dimension(w, h);
		JButton b = new JButton(s);
		b.setHorizontalTextPosition(SwingConstants.CENTER);
		b.setMinimumSize(dim);
		b.setMaximumSize(dim);
		b.setPreferredSize(dim);
		b.setMargin(new Insets(0, 0, 0, 0));
		return b;
	}

	public static void main(String[] args) {
		JFrame f = new JFrame("Keyboard");

		Container cont = f.getContentPane();
		cont.setLayout(new BorderLayout());
		cont.add(new KeyboardPanel(), BorderLayout.CENTER);

		f.pack();
		f.setLocationRelativeTo(null);
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f.setVisible(true);
	}
}
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben