Позициониране на компонентите на Java GridBagLayout

Опитвам се да направя просто оформление, където етикетите са до бутоните и затварят. Ето реда, в който ги добавям:

add(label_1, cons);

cons.gridx = 1;
add(textArea,cons);

cons.gridx = 0;
cons.gridy = 2;
add(button_1,cons);

cons.gridx= 0;
cons.gridy = 4;
add(button_2,cons);

cons.gridx=0;
cons.gridy=6;
add(button_3,cons);

cons.gridx = 1;
cons.gridy = 2;
add(label_2, cons);       

cons.gridy=4;
add(label_3,cons);

cons.gridy=6;
add(label_4,cons);

Което изглежда така:

въведете описание на изображението тук

Просто ми трябват етикетите, разположени по-близо до бутоните, но изглежда, че най-близката стойност x, която мога да им дам, е 1, изглежда относително позиционирана - има ли начин да ги позиционирам абсолютно?


person joe    schedule 02.06.2014    source източник
comment
Можете да промените подравняването на бутоните и етикетите съответно надясно и наляво, което ще ги приближи. Освен това предлагам да използвате различен екземпляр на GridBagConstraints за всеки компонент.   -  person Jonathan Drapeau    schedule 02.06.2014


Отговори (4)


Имате няколко налични опции, в зависимост от това как искате да изглежда това, всички обяснени във вече публикувания урок.

  1. Задайте полето fill на ограниченията на HORIZONTAL и подравняване на етикетите на WEST (Или LINE_START, което от двете сте свикнали), заедно с положително теглоx. Това ще накара както етикетите, така и бутоните да заемат цялото налично хоризонтално пространство и тяхното подравняване ще означава, че текстът ще бъде в левия край.
  2. Използвайте полето anchor. Това контролира къде ще бъде разположен по-малък компонент в клетката - вероятно искате дясно или централно подравняване за бутоните и ляво за етикетите.
  3. Ако искате етикетите да са близо до бутоните, без нищо да променя размера, тогава мрежата няма да ви служи много добре, тъй като полето "Въведете изречение" е твърде дълго. Може да искате да имате 2 различни панела за горния и долния (BorderLayout много?) или по-интелигентен мениджър на оформлението
person Ordous    schedule 02.06.2014
comment
Настройването на файла с ограниченията на хоризонтално проработи, благодаря! - person joe; 02.06.2014

въведете описание на изображението тук

Горният прозорец е произведен с кода по-долу, който използва 3 външни класа.

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class GridBagLayout{

  JFrame      frame;

  public GridBagLayout() {
    initComponents();
  }

  private void initComponents(){
    JTextField  text  = new JTextField("",10);
    JButton     but1  = new JButton("button 1");
    JButton     but2  = new JButton("button 2");
    JButton     but3  = new JButton("button 3");
    JLabel      lab0  = new JLabel("Enter a sentence");
    JLabel      lab1  = new JLabel("test 1");
    JLabel      lab2  = new JLabel("test 2");
    JLabel      lab3  = new JLabel("test 3");

    frame  = new JFrame("TestGridBagLayout");
    frame.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    frame.setLayout(new java.awt.GridBagLayout());

    frame.add(lab0,   new GBConstraints(0,0));
    frame.add(text,   new GBConstraints(1,0));

    frame.add(but1,   new GBConstraints(0,1));
    frame.add(lab1,   new GBConstraints(1,1));

    frame.add(but2,   new GBConstraints(0,2));
    frame.add(lab2,   new GBConstraints(1,2));

    frame.add(but3,   new GBConstraints(0,3));
    frame.add(lab3,   new GBConstraints(1,3));

    frame.setVisible(true);
    frame.pack();
  }  

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

Прозорецът по-долу беше създаден чрез промяна на new GBConstraints редовете по-горе на редовете, показани под снимката, като въпросът е, че има няколко доста лесни начина да промените оформлението, за да изглежда точно както искате - колко близо един до друг и колко вертикално подравнени, за два броя.

въведете описание на изображението тук

frame.add(lab0,   new GBConstraints(0,0).anchor(EAST));
frame.add(text,   new GBConstraints(1,0).ipad(100, 0).anchor(WEST));

frame.add(but1,   new GBConstraints(0,1));
frame.add(lab1,   new GBConstraints(1,1));

frame.add(but2,   new GBConstraints(0,2));
frame.add(lab2,   new GBConstraints(1,2).insets(15, -15, 5, 5));

frame.add(but3,   new GBConstraints(0,3).anchor(EAST));
frame.add(lab3,   new GBConstraints(1,3).anchor(WEST));

Имайте предвид, че вторият ред по-горе има две ограничения, добавени към GBConstraint; гъвкавостта се осигурява от класове Fill, Anchor и GBConstraints, предоставени от @SplungeBob в тази нишка.

person DSlomer64    schedule 02.06.2014
comment
Има пакети, които някои хора биха могли да сметнат за по-добри от пакета (Fill, Anchor, GBConstraints), любезно предоставен от @SplungeBob; този по-горе просто се оказа единственият, който съм проучвал, откакто Splunge го предложи. Подейства ми чудесно. - person DSlomer64; 03.06.2014

Опитайте да си поиграете със следните свойства на GridBagConstraints: gridheight и weighty. Бих се опитал да променя тази част от вашия код:

cons.gridx = 1;
cons.gridy = 2;
cons.weighty = 0;
add(label_2, cons);

За повече информация: http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

Проверете този код, може би ще ви помогне:

public class GUITest {
private JPanel mainPanel;   
private JLabel l1;
private JLabel l2;
private JLabel l3;
private JButton b1;
private JButton b2;
private JTextField text;
private JFrame guiFrame;
private Container pane;

public GUITest() {
    // TODO Auto-generated constructor stub
    guiFrame = new JFrame();
    pane = new Container();
    pane.setLayout(new BorderLayout());
    //make sure the program exits when the frame closes
    guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    guiFrame.setTitle("Example GUI");
    guiFrame.setSize(300,250);

    mainPanel = new JPanel(new GridBagLayout());

    l1 = new JLabel("Label 1");
    b1 = new JButton("Button 1");
    l2 = new JLabel("Label 2");
    b2 = new JButton("Button 2");
    l3 = new JLabel("Enter a sentence");
    text = new JTextField(50);

    GridBagConstraints c = new GridBagConstraints();
    c.gridheight = 1;
    c.gridwidth = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 0;
    c.weighty = 0;
    Insets i = new Insets(5, 5, 5, 5);
    c.insets = i;

    c.gridx= 0;
    c.gridy = 0;
    mainPanel.add(l3,c);

    c.gridx = 1;
    c.gridy = 0;        
    mainPanel.add(text, c);

    c.gridx = 0;
    c.gridy = 1;
    mainPanel.add(b1,c);

    c.gridx = 1;
    c.gridy = 1;
    mainPanel.add(l1,c);

    c.gridx= 0;
    c.gridy = 2;
    mainPanel.add(b2,c);

    c.gridx = 1;
    c.gridy = 2;
    mainPanel.add(l2, c);



    pane.add(mainPanel,BorderLayout.NORTH);
    guiFrame.setContentPane(pane);
    guiFrame.setVisible(true);

}

public static void main(String[] args) {
    GUITest g = new GUITest();
}

}

person pitregallego    schedule 02.06.2014
comment
Съжалявам, но не виждам как настройката на gridy или gridheight ще реши проблема с OP или хоризонталното разстояние. - person Ordous; 02.06.2014

Когато използвате GridBagLayout, използването на относително позициониране винаги е по-лесно за поддържане.

Сега по отношение на ляво/дясно позициониране, което трябва да използвате правилно

  • теглоx
  • котва

И двете свойства ще ви помогнат там (има друга опция, използваща запълване и игра с подравняване на текст на JLabel, но е много по-малко елегантна, защото вашето оформление зависи както от свойствата на компонента, така и от свойствата на оформлението):

И в крайна сметка крайният резултат:

въведете описание на изображението тук

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class TestGridBagLayout {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestGridBagLayout().initUI();
            }
        });
    }

    private JLabel label_1 =  new JLabel("Enter a sentence");
    private JLabel label_2 =  new JLabel("test");
    private JLabel label_3 =  new JLabel("test");
    private JLabel label_4 =  new JLabel("test");
    private JTextField textArea = new JTextField(15);
    private JButton button_1 = new JButton("button 1");
    private JButton button_2 = new JButton("button 2");
    private JButton button_3 = new JButton("button 3");

    protected void initUI() {
        JFrame frame= new JFrame(TestGridBagLayout.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints left = new GridBagConstraints();
        left.anchor = GridBagConstraints.EAST;
        left.weightx = 1;
        left.insets = new Insets(5, 5, 5, 5);
        GridBagConstraints right = new GridBagConstraints();
        right.weightx=1;
        right.gridwidth = GridBagConstraints.REMAINDER;
        right.anchor = GridBagConstraints.WEST;
        right.insets = new Insets(5, 5, 5, 5);

        panel.add(label_1, left);
        panel.add(textArea,right);

        panel.add(button_1 ,left);
        panel.add(label_2, right);

        panel.add(button_2,left);
        panel.add(label_3,right);

        panel.add(button_3,left);
        panel.add(label_4,right);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}
person Guillaume Polet    schedule 02.06.2014