[GroupBagLayout] Bekomme das Aligment zweier Buttons einfach nicht hin

Hallo Leute,

ich habe jetzt schon so viel versucht, gesucht und war letztendlich grade kurz davor, irgendwas kaputt zu machen :grr: . Also ich komme schlicht und ergreifend nicht mehr weiter.

Was ich möchte: Unter der rechten Liste 2 Buttons haben, der obere Heißt „PM“, der untere „Senden“, dazwischen eine kleine Gap. Die Buttons konnte ich schon tauschen, größer und kleiner machen, aber dass der Senden Button unter dem PM steht, kriege ich nicht hin.

Dabei ist doch das Alignment auf TRAILING, also folgend, eingestellt…

Vielleicht lacht der eine oder andere drüber, und sicherlich ist es sogar was triviales, nur sehe ich es nicht und ich wäre unglaublich dankbar für eine Lösung des Ganzen. :idea:

Danke! :slight_smile:

package chat.client;


import java.awt.Color;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.swing.*;

import com.sun.istack.internal.logging.Logger;

public class testGUI extends javax.swing.JFrame {    
	
	
	// Variables declaration - do not modify
	private DataOutputStream dos;
    private DataInputStream dis;
    private Socket socket;
    private String clientName;
    private String serverAdress;
    private int serverPort = 1337;
//    private DefaultListModel listModel=new DefaultListModel();
    private ArrayList<String> alClientList = new ArrayList<String>();
    private boolean pmSent = false;
    private boolean humanPlayer = false;
    private String pmRecipient;

	
    private javax.swing.JTextArea Screen;
    private javax.swing.JButton send_Button;
    private javax.swing.JTextPane Text_Field;
    private javax.swing.JList jlClientList;
    private javax.swing.JButton privateMessage_Button;
    private javax.swing.JColorChooser font_chooser;
    private javax.swing.JScrollPane jScrollPaneOutputOfChatMessages;
    private javax.swing.JScrollPane jScrollPaneShowConnectedClients;
    private javax.swing.JScrollPane jScrollPaneInputOfChatMessage;
    // End of variables declaration
    
    
    /** Creates new form Client */
    public testGUI() {
        initComponents();
        Screen.setEditable(false);

        jlClientList.setVisibleRowCount(8);
        alClientList.add(clientName);
    }
    
    
    public testGUI(String serverAddressInput, String nameInput) {

    }
    

    @SuppressWarnings("unchecked")
    
    private void initComponents() {

        font_chooser = new javax.swing.JColorChooser();
       
        Screen = new javax.swing.JTextArea();
       
        
        jScrollPaneOutputOfChatMessages = new javax.swing.JScrollPane();
        jScrollPaneInputOfChatMessage = new javax.swing.JScrollPane();
        jScrollPaneShowConnectedClients = new javax.swing.JScrollPane();
        
        privateMessage_Button = new javax.swing.JButton();
       
        
        Text_Field = new javax.swing.JTextPane();
        
        jlClientList = new javax.swing.JList();
        
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Wallenstein Chat V 0.5");
        setResizable(false);

        Screen.setColumns(20);
        Screen.setRows(5);
        
        jScrollPaneOutputOfChatMessages.setViewportView(Screen);

        //Label und ActionListener für den Senden Button
        send_Button = new javax.swing.JButton();
        send_Button.setText("Senden");
        send_Button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                send_ButtonActionPerformed(evt);
            }
        });
        
        
        //Label und ActionListener für den PM Button
        privateMessage_Button.setText("Private Nachricht");
        privateMessage_Button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                privateMessage_ButtonActionPerformed(evt);
            }
        });

        jlClientList.setModel(new javax.swing.AbstractListModel() {
        	// Hier werden die verbunden Clients hinzugefügt
            String[] strArrayClients = { "ClientName 1", "ClientName 2", clientName, clientName, clientName };
            public int getSize() { return strArrayClients.length; }
            public Object getElementAt(int i) { return strArrayClients**; }
        });
        jlClientList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        jScrollPaneShowConnectedClients.setViewportView(jlClientList);

      
        

        Text_Field.setOpaque(true);
        Text_Field.setBackground(Color.red);
        Text_Field.setCursor(new java.awt.Cursor(java.awt.Cursor.TEXT_CURSOR));
        Text_Field.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                Text_FieldKeyPressed(evt);
            }
        });
        jScrollPaneInputOfChatMessage.setViewportView(Text_Field);

        javax.swing.GroupLayout groupLayout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(groupLayout);
        
//        Original V1
//        layout.setHorizontalGroup(
//            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
//            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
//                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
//                    .addComponent(jScrollPaneInputOfChatMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE)
//                    .addComponent(jScrollPaneOutputOfChatMessages, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE))
//                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
//                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
//                    .addComponent(privateMessage_button, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
//                    .addComponent(Send_Button, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
//                    .addComponent(jScrollPaneShowConnectedClients, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE))
//                .addContainerGap())
//        );
//        
//        layout.setVerticalGroup(
//            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
//            .addGroup(layout.createSequentialGroup()
//                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
//                    .addComponent(jScrollPaneOutputOfChatMessages, javax.swing.GroupLayout.PREFERRED_SIZE, 286, javax.swing.GroupLayout.PREFERRED_SIZE)
//                    .addComponent(jScrollPaneShowConnectedClients, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE))
//                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
//                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
//                    .addComponent(Send_Button, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
//                    .addComponent(jScrollPaneInputOfChatMessage, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE))
//                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
//                .addComponent(privateMessage_button, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
//                .addGap(11, 11, 11))
//        );

        
        
//      Advanced V2
      groupLayout.setHorizontalGroup(
    		  
      groupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, groupLayout.createSequentialGroup()
    		  
          .addGroup(groupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jScrollPaneInputOfChatMessage, javax.swing.GroupLayout.DEFAULT_SIZE, 383, Short.MAX_VALUE)
              .addComponent(jScrollPaneOutputOfChatMessages, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE))
          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
          
          .addGroup(groupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        	  .addComponent(jScrollPaneShowConnectedClients, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
              .addComponent(privateMessage_Button, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
              .addGap(20, 20, 20)
              .addComponent(send_Button, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
              )
          .addContainerGap())
  );
  
  groupLayout.setVerticalGroup(
		  
      groupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      
      .addGroup(groupLayout.createSequentialGroup()
    		  
          .addGroup(groupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jScrollPaneOutputOfChatMessages, javax.swing.GroupLayout.PREFERRED_SIZE, 288, javax.swing.GroupLayout.PREFERRED_SIZE)
              .addComponent(jScrollPaneShowConnectedClients, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE))
          .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
          
          .addGroup(groupLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        		  .addComponent(jScrollPaneInputOfChatMessage, javax.swing.GroupLayout.Alignment.TRAILING, 76, 76, 76))
        		  .addComponent(privateMessage_Button, 33, 33, 33)
        		  .addGap(5, 5, 5)
        		  .addComponent(send_Button, 33, 33, 33)
        		  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        		  )
  );
        
        
        pack();
        
        
//        .getRootPane().setDefaultButton(submitButton);
        
        
    }
    
    
private void write(){


}

private void send_ButtonActionPerformed(java.awt.event.ActionEvent evt) {                                            

    write();

}                                           

//input 
/**
 * Wickelt den PM-Button ab
 * 
 */
private void privateMessage_ButtonActionPerformed(java.awt.event.ActionEvent evt) {
//	
//    try {
//    	
//    	
//    	}
//    		
//    	}
//        socket.close();
//        this.setVisible(false);
//        System.exit(0);
//    } catch (IOException exceptionIO) {
//        Logger.getLogger(ChatClientGUISwing_Mockup.class.getName()).log(Level.SEVERE, null, exceptionIO);
//    }
}


public String getPmRecipient() {
	
	String tempPmRecipient;
	
	do{
    	tempPmRecipient = JOptionPane.showInputDialog("PM Empfänger?"); //Empfänger einlesen
    	
    	if(checkForHumanPlayer(tempPmRecipient)==false){
    		
    		pmRecipient = JOptionPane.showInputDialog("Empfänger ist KI-Spieler; bitte Empfänger eingeben!");
    	}
    	
    	else{
    		setHumanPlayer(true);
    		return tempPmRecipient;
    	}
	}
    
    while(!humanPlayer);
    	
	return tempPmRecipient;
}


public void setPmRecipient(String pmRecipient) {
	this.pmRecipient = pmRecipient;
}


private void Text_FieldKeyPressed(java.awt.event.KeyEvent evt) {

        if(evt.getKeyCode()==KeyEvent.VK_ENTER){
            write();

        }
}



 /**
  * 
  * Helper Functions for Realizing the Implementation
  * 
  */


/**
 * 
 * Prüft, ob ein übergebener Spielername real ist oder einer KI gehört
 * 
 * @param nameInput Der String des zu prüfenden Spielernamens
 * @return Variable boolean, um den Status der Abfrage zu repräsentieren
 * 
 */
private boolean checkForHumanPlayer(String nameInput){
	
	setHumanPlayer(true);
//		if(nameInput.getHumanState()){
//	 setHumanPlayer(true);
//}
//	
	
	return humanPlayer;
	
}


public boolean isPmSent() {
	return pmSent;
}


public void setPmSent(boolean pmSent) {
	this.pmSent = pmSent;
}


public boolean isHumanPlayer() {
	return humanPlayer;
}


public void setHumanPlayer(boolean humanPlayer) {
	this.humanPlayer = humanPlayer;
}



    /**
     * @param args is the array if command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException exceptionCNF) {
            java.util.logging.Logger.getLogger(testGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, exceptionCNF);
        } catch (InstantiationException exceptionI) {
            java.util.logging.Logger.getLogger(testGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, exceptionI);
        } catch (IllegalAccessException exceptionIA) {
            java.util.logging.Logger.getLogger(testGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, exceptionIA);
        } catch (javax.swing.UnsupportedLookAndFeelException exceptionULAF) {
            java.util.logging.Logger.getLogger(testGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, exceptionULAF);
        }
       

        
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {

            	
                new testGUI().setVisible(true);
                
//                new ChatClientGUISwing_Mockup(network.NetworkHelper.getOwnIPAdress(), "User").setVisible(true);
            }
        });
    }


}```

Warum legts Du Die Buttons nicht in ein gemeinsames GridLayout (dem kann man nämlich auch sagen, wie gross der Abstand der Componenten sein soll) und packst dieses an die die richtige Stelle?

bye
TT

Ist in unserem Wiki etwas für dich zu finden?
Byte-Welt Wiki - GroupLayout für Homosapiens

Ansonsten zu LayoutManagern allgemein: Byte-Welt Wiki - LayoutManager

Hallo Leute,

Danke für das Input. Habs zwar probiert, aber ich komme nicht dahinter.

Egal, habs jetzt dynamisch mit nem Null-Layout gemacht.

Grüße,
Haswell

“NullLayout” ist kein LayoutManager und ganz und gar nicht dynamisch. Du kannst mir glauben, wenn ich sage, dass du dir mit null-Layout keinen Gefallen tust.
Hast du mal ein Bild, wie es genau aussehen soll? Dann kann man dir das mal verbessern.

ich denke, so würde es gehen:[SPOILER]```import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class LayoutTest2 {
public static void main(String[] args) {

	JPanel jPanel = new JPanel();
	GroupLayout groupLayout = new GroupLayout(jPanel);
	jPanel.setLayout(groupLayout);

	JTextField field1 = createTextField("1");
	field1.setPreferredSize(new Dimension(400, 300));
	JTextField field2 = createTextField("2");
	JTextField field3 = createTextField("3");
	Component field4 = createButtons();

	groupLayout.setHorizontalGroup(groupLayout
			.createSequentialGroup()
			.addGroup(
					groupLayout.createParallelGroup().addComponent(field1)
							.addComponent(field3))
			.addGap(20, 20, 20)
                            .addGroup(
					groupLayout.createParallelGroup().addComponent(field2)
							.addComponent(field4)));
	groupLayout.setVerticalGroup(groupLayout
			.createSequentialGroup()
			.addGroup(
					groupLayout.createParallelGroup().addComponent(field1)
							.addComponent(field2))
			.addGap(20, 20, 20)
                            .addGroup(
					groupLayout.createParallelGroup().addComponent(field3)
							.addComponent(field4)));
	JOptionPane.showMessageDialog(null, jPanel, "LayoutTest",
			JOptionPane.PLAIN_MESSAGE);
}

private static Component createButtons() {
	JPanel jPanel = new JPanel(new GridLayout(0, 1,10,10));
	jPanel.add(new JButton("Button1"));
	jPanel.add(new JButton("Button2"));

// jPanel.setBorder(BorderFactory.createTitledBorder(“die Buttons …”));
return jPanel;
}

private static JTextField createTextField(String string) {
	JTextField jTextField = new JTextField(string);
	jTextField.setBorder(BorderFactory.createLineBorder(Color.RED, 3));
	return jTextField;
}

}```[/SPOILER]bye
TT

hmm, ein “DynamicNullLayout” wär doch mal ein Projekt xD

@TO: Wie im Beispiell von TT schon zu sehen ist, kann man verschiedene LayoutManager benutzen.
Teste einfach mal extern mit ein paar farbigen Panels und buttons rum um ein Gefühl für die beste Lösung zu bekommen.
Mal eben so aus dem Kopf heraus erfordert ne Menge Übung.

Gruß Vanny

Ist alles keine Hexerei, schau hier z.B mein Draglayout ist quasi ein Dynamisches Null Layout. Man muss alles wie beim Null Layout machen aber das Layout errechnet die preferred Size des Containers:

@bERt0r : Kannst du das im Wiki mal erklären? Dort gibts auch, wie du weißt, einen Bereich für eigene LayoutManager.

Was erklären, das DragLayout im speziellen oder generell Eigene LM? Das DragLayout zielt darauf ab, verschiebbare Komponenten in einem Scrollpane zu haben. Schiebt man eine Komponente über den Rand, vergrößert sich automatisch der Container und die Scrollbalken erscheinen. Dabei spielt sich alles in 3 Methoden ab:

//geht alle Komponenten durch und findet die Extreme in allen Richtungen heraus, berechnet daraus dann die erforderliche Größe
@Override
	public Dimension preferredLayoutSize(Container parent)
	{
		int top = 0,bot = 0,left = 0,right = 0;
		for(Component c:parent.getComponents())
		{
			Rectangle r=c.getBounds();
			if(r.x<left)
			{
				left=r.x;
			}
			else if(r.x+r.width>right)
			{
				right=r.x+r.width;
			}
			if(r.y<top)
			{
				top=r.y;
			}
			else if(r.y+r.height>bot)
			{
				bot=r.y+r.height;
			}
		}
		
		return new Dimension(right+(left*-1),bot+(top*-1));
	}

//Falls Komponenten über den Rand nach oben/links geschoben werden, werden deren Koordinaten negativ.
//Nachdem der Container dann erweitert wurde und diese Komponenten voll zu erfassen ist es notwendig alle Komponenten nach unten rechts zu verschieben
@Override
	public void layoutContainer(Container parent)
	{
		for(Component c:parent.getComponents())
		{
			Point location=c.getLocation();
			if(location.x<0)
			{
				moveAllBy((location.x*-1),0,parent.getComponents());
			}
			if(location.y<0)
			{
				moveAllBy(0,(location.y*-1),parent.getComponents());
			}
		}
	}

//Bewegt alle Komponenten
	private void moveAllBy(int dx,int dy,Component[] components)
	{
		for(Component c:components)
		{
			Point location=c.getLocation();
			location.translate(dx,dy);
			c.setLocation(location);
		}
	}

Der Rest der Methoden sind nur Stubs.