Могат ли компонентите на gridbaglayout да запълнят родителския кадър при преоразмеряване?

Имам JFrame, чийто корен JPanel е инстанциран с GridBagLayout. По време на изпълнение панелът се попълва с компоненти въз основа на някакво описание, а ширината, височината и координатите x,y са дадени в описанието, което се използва с полетата gridwidth, gridheight, gridx и gridy в GridBagConstraints. Самите компоненти също могат да бъдат JPanels със собствени дъщерни компоненти и GridBagConstraints, GUI е описан в дърво, така че Frame се попълва рекурсивно.

Проблемът, който имам, е, че когато рамката се преоразмерява, вътрешните компоненти не се разтягат, за да запълнят дадените им ширини и височини. Дадох пример за кода на оформлението по-долу, с екранни снимки.

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.util.*;

public class GridBagTest extends JPanel {

    private final GridBagConstraints gbc = new GridBagConstraints();

    public GridBagTest(){

        setLayout(new GridBagLayout());
        add(gbcComponent(0,0,1,2), gbc);    
        add(gbcComponent(1,0,2,1), gbc);            
        add(gbcComponent(1,1,1,1), gbc);            
        add(gbcComponent(2,1,1,1), gbc);            

    }

    //Returns a JPanel with some component inside it, and sets the GBC fields
    private JPanel gbcComponent(int x, int y, int w, int h){

        gbc.gridx = x; 
        gbc.gridy = y;
        gbc.gridwidth = w;
        gbc.gridheight = h;
        gbc.fill = GridBagConstraints.BOTH;
        JPanel panel = new JPanel();
        JTextField text = new JTextField("(" + w + ", " + h + ")");
        panel.setBorder(new TitledBorder("(" + x + ", " + y + ")"));        
        panel.add(text);
        return panel;

    }

    public static void main (String args[]){

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new GridBagTest());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

При стартиранеСлед разтягане

Имам нужда от него, така че на снимка 2 вътрешните JPanel, които държат компонентите, са преоразмерени, за да запълнят съответните си ширини и височини на GridBagLayout, като в идеалния случай също разтягат и компонентите си.


person adnan_252    schedule 13.07.2014    source източник


Отговори (2)


Това обикновено се дължи на това, че не сте задали тегловни ограничения.

Опитвам:

gbc.gridx = x; 
gbc.gridy = y;
gbc.gridwidth = w;
gbc.gridheight = h;

// **** add here:
gbc.weightx = 1.0;
gbc.weighty = 1.0;

Това ще позволи на GUI да се разшири в посоките x и y, ако е необходимо.

person Hovercraft Full Of Eels    schedule 13.07.2014
comment
Изглежда, че това работи! Не мога да повярвам, че никога преди не съм го опитвал. Сега има ли начин вътрешните панели, които имат само един компонент, да имат този компонент да се разтяга по размер, за да го запълни? т.е. ширините на текстовите полета са разтегнати? - person adnan_252; 13.07.2014
comment
@adnan_252: да, но ще трябва да дадете тези вътрешни мениджъри за оформление на JPanel, които позволяват това, като GridBagLayout или BorderLayout, или... В момента вашите вътрешни JPanel използват само FlowLayout по подразбиране и това оформление е доста просто и не разтегнете компоненти. - person Hovercraft Full Of Eels; 13.07.2014
comment
@adnan_252: няма за какво. И благодаря, че публикувахте минимална примерна програма с вашия questino. - person Hovercraft Full Of Eels; 13.07.2014

Можете да зададете columnWidths и rowHeights при преоразмеряване на вашия JPanel. Вижте тази проба. Промених вашия код за случай на две колони:

public GridBagTest(){

    setLayout(new GridBagLayout());
    add(gbcComponent(0,0,1,2), gbc);    
    add(gbcComponent(1,0,1,1), gbc);

    addComponentListener(new java.awt.event.ComponentAdapter() {
        @Override
        public void componentResized(java.awt.event.ComponentEvent evt) {
            GridBagLayout layout = (GridBagLayout) getLayout();
            JPanel panel = (JPanel)evt.getComponent();
            int width = panel.getWidth();
            int height = panel.getHeight();
            int wGap = panel.getInsets().left+panel.getInsets().right;
            int hGap = panel.getInsets().top+panel.getInsets().bottom;
            layout.columnWidths = new int[]{width/2-wGap, width/2-wGap};
            layout.rowHeights = new int[]{height-hGap};
        }
    });

}

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

person Jeff_Alieffson    schedule 04.01.2016