2012-03-12 2 views
2

Considérez la figure suivante:éléments swing pile de haut en bas

Required Design

J'ai besoin de développer une interface graphique swing les regards comme celui-ci. Je les ai simplement nommés jLabel mais il y a quelques images et jLabels dedans. L'arrière-plan awt par défaut visible est un JPanel et chaque arrière-plan rouge visible est un JPanel. Maintenant, j'ai besoin d'eux pour être empilés comme indiqué ci-dessus. J'ai essayé un certain nombre de LayoutManagers et ça ne marche toujours pas.

Le point important ici est que le nombre de div rouges n'est pas constant. S'il n'y a qu'un seul div rouge, alors il doit être affiché en haut, pas au centre. Pour autant que je sais GridBagLayout devrait fonctionner, mais il centre le jpanel coloré rouge unique disponible. Tous les gestionnaires de disposition les centrent mais ne les empilent pas de haut en bas.

+0

Je suis tout à ne pas obtenir ce que vous meant.The contenu des JPanel sont vraiment dynamiques. Quel est le gestionnaire de disposition APPROPRIÉE qui fait cela? et pour couronner le jpanel le plus externe (celui avec l'arrière-plan awt) est ajouté à un 'JScrollPane'. Donc 'FlowLayout' ne fonctionne pas – sasidhar

Répondre

3

Même avec jeu d'ancrage NORD puis les panneaux sera toujours centrée. Vous pouvez contourner ce problème en ajoutant un panneau factice pour remplir l'espace restant. Personnellement, je resterais loin de GridBagLayout cependant.

JFrame frame = new JFrame(); 
JPanel content = new JPanel(); 
content.setBorder(BorderFactory.createLineBorder(Color.red)); 
frame.setContentPane(content); 
frame.getContentPane().setLayout(new GridBagLayout()); 
frame.setSize(400, 300); 

for (int i = 0; i < 3; i++) { 
    JPanel panel = new JPanel(); 
    panel.add(new JLabel("label1")); 
    panel.add(new JLabel("label2")); 
    panel.add(new JLabel("label3")); 
    panel.setBorder(BorderFactory.createLineBorder(Color.red)); 
    GridBagConstraints con = new GridBagConstraints(); 
    con.gridy = i; 
    con.gridx = 0; 
    con.anchor = GridBagConstraints.NORTHWEST; 
    con.ipady = 10; 
    frame.getContentPane().add(panel, con); 
} 

// dummy panel to use up the space (force others to top) 
frame.getContentPane().add(
     new JPanel(), 
     new GridBagConstraints(0, 3, 1, 1, 1, 1, 
       GridBagConstraints.NORTHWEST, 
       GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0, 
       0)); 

frame.setVisible(true); 

Exemple GroupLayout (mon gestionnaire de disposition favori).

JFrame frame = new JFrame(); 
JPanel content = new JPanel(); 
frame.setContentPane(content); 
frame.getContentPane().setLayout(
     new BoxLayout(content, BoxLayout.Y_AXIS)); 
frame.setSize(400, 300); 
GroupLayout gLayout = new GroupLayout(content); 
content.setLayout(gLayout); 
ParallelGroup hGroup = gLayout.createParallelGroup(); 
gLayout.setHorizontalGroup(hGroup); 
SequentialGroup vGroup = gLayout.createSequentialGroup(); 
gLayout.setVerticalGroup(vGroup); 
for (int i = 0; i < 3; i++) { 
    JPanel panel = new JPanel(); 
    panel.add(new JLabel("label1")); 
    panel.add(new JLabel("label2")); 
    panel.add(new JLabel("label3")); 
    panel.setBorder(BorderFactory.createLineBorder(Color.red)); 
    hGroup.addComponent(panel); 
    vGroup.addComponent(panel, GroupLayout.PREFERRED_SIZE, 
      GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE); 
    vGroup.addGap(10); 
} 

frame.setVisible(true); 
+0

Est-ce que la mise en page de groupe est destinée au code de codage manuel? Je suis resté loin de toute ma vie ... Et je n'ai pas compris où vous avez inséré ce panneau factice? – sasidhar

+1

@sasidhar Oui GroupLayout peut être utilisé "à la main" - après avoir dit que beaucoup de gens ont du mal à comprendre. Le panneau factice est celui ajouté après les 3 panneaux d'exemple - j'ai ajouté un commentaire au code pour le signaler. – Adam

0

Assurez-vous de GridBagConstraints.anchor = GridBagConstraints.NORTH lorsque vous ajoutez des composants au panneau.

+0

essayé' GridBagConstraints.NORTH', 'GridBagConstraints.FIRST_LINE_START' et aussi' GridBagConstraints.PAGE_START' rien ne semble fonctionner – sasidhar

+0

@sasidhar Oui j'ai essayé NORTH mais ça n'a pas fonctionné, je devais ajouter un panneau factice pour remplir l'espace restant pour forcer les choses vers le haut. Voir ma solution – Adam

2

vous pouvez utiliser verticale BoxLayout, par exemple: http://www.java-tips.org/java-se-tips/javax.swing/how-to-use-swing-boxlayout.html

+1

essayé, cela obtient le premier élément dans la position voulue, mais lorsqu'il n'y a que deux éléments, l'élément suivant est agrandi pour occuper l'emplacement total – sasidhar

+0

Essayez d'ajouter le panneau de disposition au nord d'un panneau avec une bordure . –

+0

A eu le même problème, résolu en utilisant BoxLayout avec Axis = y. merci Wajdy –

2

personne ne nous a dit que tous les JComponents doivent être visibles, par exemple

enter image description here

enter image description here

enter image description here

à partir du code

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

public class AddComponentsAtRuntime { 

    private JFrame f; 
    private JPanel panel; 
    private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack; 

    public AddComponentsAtRuntime() { 
     f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     panel = new JPanel(new GridLayout(0, 1)); 
     f.add(panel, "Center"); 
     f.add(getCheckBoxPanel(), "South"); 
     f.setLocation(200, 200); 
     f.pack(); 
     f.setVisible(true); 
    } 

    private JPanel getCheckBoxPanel() { 
     checkValidate = new JCheckBox("validate"); 
     checkValidate.setSelected(false); 
     checkReValidate = new JCheckBox("revalidate"); 
     checkReValidate.setSelected(false); 
     checkRepaint = new JCheckBox("repaint"); 
     checkRepaint.setSelected(false); 
     checkPack = new JCheckBox("pack"); 
     checkPack.setSelected(false); 
     JButton addComp = new JButton("Add New One"); 
     addComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JPanel b = new JPanel(new GridLayout(0, 4)); 
       b.setBackground(Color.red); 
       b.setBorder(new LineBorder(Color.black, 2)); 
       //b.setPreferredSize(new Dimension(600, 20)); 
       for (int i = 0; i < 4; i++) { 
        JLabel l = new JLabel("label" + i + 1); 
        b.add(l); 
        if (i == 2) { 
         l.setVisible(false); 
        } 
       } 
       panel.add(b); 
       makeChange(); 
       System.out.println(" Components Count after Adds :" + panel.getComponentCount()); 
      } 
     }); 
     JButton removeComp = new JButton("Remove One"); 
     removeComp.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       int count = panel.getComponentCount(); 
       if (count > 0) { 
        panel.remove(0); 
       } 
       makeChange(); 
       System.out.println(" Components Count after Removes :" + panel.getComponentCount()); 
      } 
     }); 
     JPanel panel2 = new JPanel(); 
     panel2.add(checkValidate); 
     panel2.add(checkReValidate); 
     panel2.add(checkRepaint); 
     panel2.add(checkPack); 
     checkPack.setSelected(true); 
     panel2.add(addComp); 
     panel2.add(removeComp); 
     return panel2; 
    } 

    private void makeChange() { 
     if (checkValidate.isSelected()) { 
      panel.validate(); 
     } 
     if (checkReValidate.isSelected()) { 
      panel.revalidate(); 
     } 
     if (checkRepaint.isSelected()) { 
      panel.repaint(); 
     } 
     if (checkPack.isSelected()) { 
      f.pack(); 
     } 
    } 

    public static void main(String[] args) { 
     AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime(); 
    } 
} 
+0

Je pense que vous avez raté un point ici, l'image que je vous ai indiquée indique clairement que la hauteur de l'arrière-plan JPanel est fixe et quand elle augmente au-delà, le JScrollPane auquel elle est attachée va créer des barres de défilement. utiliser this.pack et créer un JPanel juste assez pour les composants est une solution triviale qui ne convient pas à mon scénario. – sasidhar

+0

@sasidhar tout ce qui vous entoure est toujours plus simple que ce à quoi vous pensez, – mKorbel

1

Vous devriez essayer le MigLayout c'est simple mais puissant. Ci-dessous, je dis à miglayout de faire pousser des éléments, et de remplir tout l'espace possible, puis après chaque élément je lui dis de passer à une nouvelle ligne (wrap). Vous trouverez des exemples et tutoriel à la page MigLayout http://www.miglayout.com/:

import net.miginfocom.swing.MigLayout; 

public class PanelLearning extends JPanel { 

public PanelLearning() { 
    setLayout(new MigLayout("", "[grow, fill]", "")); 

    for (int i = 0; i < 3; i++) { 
     JPanel panel = new JPanel(); 
     panel.add(new JLabel("label1")); 
     panel.add(new JLabel("label2")); 
     panel.add(new JLabel("label3")); 
     panel.setBorder(BorderFactory.createLineBorder(Color.red)); 
     add(panel, "span, wrap"); 
    } 
} 

public static void main(String[] args) { 
    JFrame frame = new JFrame("Login"); 
    frame.setVisible(true); 

    frame.setContentPane(new PanelLearning()); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
    frame.pack(); 
} 
}