Swing Wie erreiche ich folgende Buttonanordung?

martin1989

Aktives Mitglied
Hallo!

Ich würde gerne folgende Buttonanordung realisieren (siehe bild).

Zur erklärung:

Das Panel besteht aus einem borderlayout mit den bereichen "center" und "south". Im center sitzt eine scrollpane mit jtable. Im south bereich möchte ich gerne zwei Buttons.
Einen zentriert in der Mitte und einen ganz rechts am rand.

Habe es mit einem FlowLayout für den South Bereich versucht und. Kann hier entweder einen Button mittig platzeiren (Flowlayout.Center) ODER einen button ganz rechts (FlowLayout.CENTER). (Befehle aus dem Kopf).

Aber sobald ich versuche beide darzustellen, bekomme ich immer einen Fehler (scheint also nicht zu funktionieren).

Wie kann ich diese Darstellung sonst noch erreichen?

Habe schon an absolute Positionierung gedacht (Fensterbreite / 2) für den ersten Button und Fensterbreite - Buttongröße/2 für den Zweiten. Jedoch würde ich hier nur die x Koordinaten berechnen, die y würde ich gerne automatisch bekommen.

Was meint ihr?

Danke!button.jpg
 

Gucky

Top Contributor
Ich benutze immer das GroupLayout aber du kannst auch das GridBagLayout benutzen und dann unten ein Panel mit dem FlowLayout verwenden.
 

martin1989

Aktives Mitglied
ja ich hab unten im "south" bereich ja schon das flowlayout versucht. nur wie sage ich jetzt den zwei buttons das einer mittig und einer rechts sein soll?

Java:
		       paneld.setLayout(borderlayout);
		       JPanel buttonpanel = new JPanel();
		       buttonpanel.setLayout(fl);
		       bd.setPreferredSize(new Dimension(50,40));
		       selAll.setPreferredSize(new Dimension(50,40));
		       buttonpanel.add(bd, fl.CENTER);
		       buttonpanel.add(selAll, fl.RIGHT);
		       paneld.add(buttonpanel, BorderLayout.SOUTH);


bd und selAll wären die zwei Buttons.
paneld ist das ganze Panel des frames
buttonpanel wäre das panel für den south bereich


bekomme da immer folgenden fehler:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: illegal component position
 
Zuletzt bearbeitet:

Gucky

Top Contributor
Dann könntest du wieder das BorderLayout verwenden. Dann bräuchtest du allerdings links einen Platzhalter.

Guck mal hier. Vielleicht hilft dir das.
 

martin1989

Aktives Mitglied
ja einfach in den OST bereich den button was ich will und in den WEST bereich den gleichen nur unsichtbar ^^
Und im center dann einen button mit maximaler größe von mir definiert, sonst strecht er ihn ja im center bereich immer so extrem ^^

hmm die idee kam mir auch, dachte vll ginge es einfacher :D

EDIT: also der button im center bereich wird mir egal was ich definiere immer über die ganze fensterbreite gezogen :S
 
Zuletzt bearbeitet:

Gucky

Top Contributor
Obwohl du rechts noch einen Button hast? Du könntest ein leeres Label hinzufügen.
Vielleicht funktioniert aber auch das GroupLayout für deine Zwecke.

Alternativ kannst du dir einen Layoutmanager auch selber schreiben.
 

Tom299

Bekanntes Mitglied
Was passiert, wenn du 2 FlowLayouts übereinander legst? Wird nur 1 angezeigt? In JavaFX ist das mit einer StackPane kein Problem :D

Ansonsten fällt mir jetzt auch nur BorderLayout mit Center + East ein für die beiden Buttons oder GridBagLayout oder auf JavaFX umsteigen ;)
 
Zuletzt bearbeitet:

Gucky

Top Contributor
Du könntest dir den LayoutManager noch selber schreiben oder du guckst dir mal das GroupLayout an.
Mir würde sonst auch kein Layout mehr einfallen.

EDIT: Eine Idee habe ich noch. Ein leeres Platzhalterlabel links hinzugefügt, dass als Text Leerzeichen enthält.
 
Zuletzt bearbeitet:

martin1989

Aktives Mitglied
hab mir das group layout schon angeschaut, aber da ists auch ned so einfach den richtigen abstand zwischen den beiden buttons zu schaffen, da das fenster ja dynamisch ist.

zu deinem edit:

ja, das problem ist nur, das mit der button der dann in der mitte ja im center bereich ist und dieser wird mir immer über die ganze breite gezogen ...
 

Gucky

Top Contributor
Dann sehe ich nur noch die Möglichkeit das Ganze selber zu schreiben. Ich glaube aber nicht, dass es so schwer werden wird, da du nur zwei Komponenten nebeneinander unterstützen musst.

EDIT: Es gibt die Möglichkeit das FlowLayout rechtsbünsig zu machen. Hilft dir das?
 
Zuletzt bearbeitet:

martin1989

Aktives Mitglied
ja einen button alleine kann ich ganz rechts setzen => das ist kein Problem.

aber wenn ich dann den zweiten hinzufüge wirds happig.

wenn ich den abstand zwischen den buttons auf die hälfte des panels setze, schiebt er mir den buton ganz rechts auch um diese distanz weg vom rand.

wenn dieser ganz rechts bleiben würde und er nur den zweiten um die hälfte des panels rüberschieben würde, würds passen ;)




edit:
werds jetzt mal mit dem absolut layout versuchen. Hätte zwar nicht gedacht, dass man für diese einfache anforderung dies benötigt, aber hilft eh nix :)

edit2: das mit dem absolut layout haut irgendwie gar nicht hin ;)
wers jetzt so versuchen:
ein borderlayout für den unteren bereich. im east bereich den rechtesten button und im west bereich ein flowlayout und einen button den ich mit den abstandskoordinaten in die mitte verschieben vrsuche ;)

werde neuerung hier posten ;9
 
Zuletzt bearbeitet:

martin1989

Aktives Mitglied
und genau so habe ichs jetzt auch hinbekommen:

Java:
		        paneld.setLayout(new BorderLayout());
		        JPanel buttonpanel = new JPanel();
		       
		        bd.setPreferredSize(new Dimension(50,40));
		        selAll.setPreferredSize(new Dimension(50,40));

		         paneld.add(buttonpanel, BorderLayout.SOUTH);
		      
   			  this.add(paneld);

		   	   JScrollPane scrollPane = new JScrollPane(table);
		   	   scrollPane.getViewport().setPreferredSize(table.getPreferredSize());

		   	   paneld.add(scrollPane, BorderLayout.CENTER);
		   	   
		   	   buttonpanel.setLayout(new BorderLayout());
		   	   buttonpanel.add(selAll, BorderLayout.EAST);
		   	   JPanel left = new JPanel();
		   	   buttonpanel.add(left, BorderLayout.WEST);
		   	   
		   	   this.pack();
		   	   this.setLocationRelativeTo(null);
		   
			   left.setLayout(new FlowLayout(FlowLayout.LEFT, scrollPane.getWidth()/2-25,0));
		   	   left.add(bd);

die "-25" sind die hälfte des buttons die noch abgezogen werden muss, da die koordinate des buttons immer am linken rand gemeint ist.
 

Foxei

Bekanntes Mitglied
Hallo 1989,
einmal ein kleines Gedankenexperiment: Wir suchen ein Möglichkeit einen Button in der Mitte und eine am linken Rand zu Positionieren und dies auf selber höhe.
Ein Panel kann nur ein Layout habe. Aber zwei Panel könnten zwei Panel haben also bauen wir und einfach einen JComponenten der zwei Panels übereinander legt.
Idee:
<JLayeredpane>
<JPanel opacity=false>​
<Flowlayout alignment=Left>​
<JButton />​
</FlowLayout>​
</jPanel>​
<JPanel opacity=false>​
<Flowlayout alignment=Center>​
<JButton />​
</FlowLayout>​
</jPanel>​
</JLayeredpane>

Vorteile bei solch einer Lösung: Wir haben keine absolute Position angaben mehr man kann diese Layout Struktur also auf alle JComponenten mit beliebiger breite anwenden.
Nachteil die beiden JComponenten können sich bei einem zu kleinen Fenster überlagern.

Gruß Simon
 

Gucky

Top Contributor
Es ginge auch noch mit dem GroupLayout und einem Platzhalterpanel. Da würde dann auch gewährleistet sein, dass alles relativ zur Framegröße am Ort bleibt.
Aber Foxeis Lösung geht natürlich auch.
 

martin1989

Aktives Mitglied
Danke foxey, diese idee gefällt mir ganz gut. habe auch versucht:


relevanter code:

Java:
JLayeredPane lpane = new JLayeredPane();
		       
		        lpane.setPreferredSize(new Dimension(300, 310));
		        lpane.setBorder(BorderFactory.createTitledBorder("ss"));
		     	
		     	
		     	  JPanel right = new JPanel();
		     	   right.setLayout(new FlowLayout(FlowLayout.RIGHT));
		     	   right.setOpaque(false);
		   	             JButton rightb = new JButton();
		   	                 right.add(rightb);
		   	      JPanel left = new JPanel();
		   	         left.setOpaque(false);
		   	         left.setLayout(new FlowLayout(FlowLayout.LEFT));
		   	            JButton leftb = new JButton();
		   	               left.add(leftb);
		   	     lpane.add(right);
		   	     lpane.add(left);
		     
		   	     paneld.add(lpane, BorderLayout.SOUTH);
		   	     this.add(paneld);

	   	   
		   	   this.pack();
		   	   this.setLocationRelativeTo(null);






Jedoch wird mir nur eine leere JLayererdPane angezeigt, also keine Buttons drinnen :)
 

martin1989

Aktives Mitglied
dies hilft leider auch nichts :p

Java:
		     	  JPanel right = new JPanel();
		     	   right.setLayout(new FlowLayout(FlowLayout.RIGHT));
		     	   right.setOpaque(false);
		   	             JButton rightb = new JButton();
		   	                 right.setPreferredSize(new Dimension(20,20));
		   	                 right.add(rightb);
		   	      JPanel left = new JPanel();
		   	         left.setOpaque(false);
		   	         left.setLayout(new FlowLayout(FlowLayout.CENTER));
		   	            JButton leftb = new JButton();
		   	            	left.setPreferredSize(new Dimension(20,20));
		   	               left.add(leftb);
		   	     lpane.add(right);
		   	     lpane.add(left);
		     
		   	     paneld.add(lpane, BorderLayout.SOUTH);
		   	     this.add(paneld);
 

Foxei

Bekanntes Mitglied
Bist du sicher das die Layeredpane überhaupt auf die Frame gesetzt wurde?
Edit:
Ich meine z.b. Layout der Parent bzw. Der Frame.
 
Zuletzt bearbeitet:

martin1989

Aktives Mitglied
also ich habe jetzt mal ein eigenes testprogramm geschrieben, kann man so ausführen:

Java:
public class Find extends JFrame {
    public Find() {
     	
    	JPanel paneld = new JPanel();
    	//JFrame frame = new JFrame();
    	this.add(paneld);
    	JLayeredPane lpane = new JLayeredPane();
	       
        lpane.setPreferredSize(new Dimension(300, 310));
        lpane.setBorder(BorderFactory.createTitledBorder("ss"));
     	
     	
     	  JPanel right = new JPanel();
     	   right.setLayout(new FlowLayout(FlowLayout.RIGHT));
     	   right.setOpaque(false);
   	             JButton rightb = new JButton();
   	                 right.setPreferredSize(new Dimension(20,20));
   	                 right.add(rightb);
   	      JPanel left = new JPanel();
   	         left.setOpaque(false);
   	         left.setLayout(new FlowLayout(FlowLayout.CENTER));
   	            JButton leftb = new JButton();
   	            	left.setPreferredSize(new Dimension(20,20));
   	               left.add(leftb);
   	     lpane.add(right);
   	     lpane.add(left);
     
   	     paneld.add(lpane);
   	     this.add(paneld);
   	     this.pack();
    }
     
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
        
                new Find().setVisible(true);
            }
        });
    }
}

auch hier werden die buttons nicht angezeigt
 

martin1989

Aktives Mitglied
so kleine Code Korrektur, hatte einen kleinen fehler oben:

Java:
public class Find extends JFrame {
    public Find() {
 
    	JPanel paneld = new JPanel();
    	//JFrame frame = new JFrame();
    	this.add(paneld);
    	JLayeredPane lpane = new JLayeredPane();
 
        lpane.setPreferredSize(new Dimension(300, 310));
        lpane.setBorder(BorderFactory.createTitledBorder("ss"));
 
 
     	  JPanel right = new JPanel();
     	   right.setLayout(new FlowLayout(FlowLayout.RIGHT));
     	   right.setOpaque(false);
   	             JButton rightb = new JButton();
   	                 rightb.setPreferredSize(new Dimension(20,20));
   	                 right.add(rightb);
   	      JPanel left = new JPanel();
   	         left.setOpaque(false);
   	         left.setLayout(new FlowLayout(FlowLayout.CENTER));
   	            JButton leftb = new JButton();
   	            	leftb.setPreferredSize(new Dimension(20,20));
   	               left.add(leftb);
   	     lpane.add(right);
   	     lpane.add(left);
 
   	     paneld.add(lpane);
   	     this.add(paneld);
   	     this.pack();
    }
 
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
 
                new Find().setVisible(true);
            }
        });
    }
}

wenn ich die buttons direkt auf demjlayererdpane platziere und den buttons mit .setbound() die position und die größe mitgeben funktionierts. aber mehrere panels in der jlayererdpane zu platzieren funktioniert einfach ned ....
 

DieKeksmaffia

Mitglied
Ich kenne persönlich mit GUI noch nicht so gut aus,
aber bei einem JLayeredPane muss man die Größe und Position genau angeben (setBounds(int,int,int,int))
http://stackoverflow.com/questions/7938825/graphics-not-showing-in-jlayeredpane-java-swing hat gesagt.:
If you add a component to a JLayeredPane, it's like adding it to a null layout using container: you must fully specify the component's size and position.
also klapp dann folgender Code:
[Java]import java.awt.Dimension;
import java.awt.*;

import javax.swing.*;

public class Find extends JFrame {
public Find() {

JPanel paneld = new JPanel();
//JFrame frame = new JFrame();
this.add(paneld);
JLayeredPane lpane = new JLayeredPane();

lpane.setPreferredSize(new Dimension(300, 310));
lpane.setBorder(BorderFactory.createTitledBorder("ss"));


JPanel right = new JPanel();
right.setLayout(new FlowLayout(FlowLayout.RIGHT));
right.setBounds(70, 270, 80, 40);
right.setOpaque(false);
JButton rightb = new JButton();
rightb.setPreferredSize(new Dimension(40,20));
right.add(rightb);
JPanel left = new JPanel();
left.setOpaque(false);
left.setLayout(new FlowLayout(FlowLayout.CENTER));
left.setBounds(150, 270, 80, 40);
JButton leftb = new JButton();
leftb.setPreferredSize(new Dimension(40,20));
left.add(leftb);
lpane.add(right);
lpane.add(left);

paneld.add(lpane);
this.add(paneld);
this.pack();
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {

new Find().setVisible(true);
}
});
}
}[/Java]

Hoffe das hat das Problem aus der Welt geschafft :D
 
Zuletzt bearbeitet:

Foxei

Bekanntes Mitglied
Hallo martin1989,
ich habe mir etwas anderes überlegt und wie bereits am Anfang vorgeschlagen einfach einen Layout Manager geschrieben.

Problem gelöst. :D
Nun aber noch zu ein Paar anderen Sachen!

Du hältst bestimmte Programmier Standards nicht ein.
  • Man leitet nicht von JFrame ab wenn man die JFrame nicht auch wirklich erweitert.
  • Man setzt einer JFrame keine Größe sondern lässt sie sich an den Content anpassen. Da sonst bei verschiedenen OS das Fenster wegen verschiedener Decoration Sizes verschieden aussieht.
  • Man verwendet nicht den Absoluten Layout Manager

Hier einmal ein Ordentlicher Quelle Code (Meiner Meinung nach)

Window.java
Java:
package windows.midLeft;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 *
 * @author Simon Schäfer <simon.schaefer@teamkoeln.com>
 */
public class Window {
    public JFrame frame;
    public void launch(){
        frame=new JFrame("Layout Beispiel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        
        JPanel panel =new JPanel(new CenterRightLayout());
        panel.setPreferredSize(new Dimension(400, 50));

        JButton btnCenter=new JButton("Center");
        btnCenter.setPreferredSize(new Dimension(100, 20));
        panel.add(btnCenter);
        
        JButton btnRight=new JButton("Right");
        btnRight.setPreferredSize(new Dimension(100, 20));
        panel.add(btnRight);
        
        
        frame.add(panel,BorderLayout.CENTER); 
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }         
    
    public static void main(String[] args){
        SwingUtilities.invokeLater(() -> {
            try{
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                Window window = new Window();
                window.launch();
            }catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e){
                Logger.getLogger(Window.class.getName()).log(Level.WARNING,null,e);
            }
        });
    }
            
}

CenterRightLayout.java
Java:
package windows.midLeft;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;

/**
 *
 * @author Simon Schäfer <simon.schaefer@teamkoeln.com>
 */
public class CenterRightLayout implements LayoutManager{

    @Override
    public void addLayoutComponent(String name, Component comp) {}

    @Override
    public void removeLayoutComponent(Component comp) {}

    @Override
    public Dimension preferredLayoutSize(Container parent) {
        return parent.getPreferredSize();
    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
        int width=0;
        int height=0;
        for(Component c:parent.getComponents()){
            if(c!=null){
                width+=c.getPreferredSize().width;
                height+=c.getPreferredSize().height;
            }
        }
        return new Dimension(width, height);
    }

    @Override
    public void layoutContainer(Container parent) {
        
        for(int i=0;i<2;i++){
            Component c=parent.getComponent(i);
            int y=(parent.getHeight()-c.getPreferredSize().height)/2;
            switch(i){
                case 0:{
                    int x=(parent.getWidth()-c.getPreferredSize().width)/2;
                    
                    c.setBounds(x, y, c.getPreferredSize().width , c.getPreferredSize().height);
                    break;
                }
                case 1:{
                    int x=parent.getWidth()-c.getPreferredSize().width;
                    c.setBounds(x, y, c.getPreferredSize().width , c.getPreferredSize().height);
                    break;
                }
            }
        }
    }
}


Gruß Simon :)
 

Anhänge

  • LayoutBeispiel.png
    LayoutBeispiel.png
    23 KB · Aufrufe: 20
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben