SWT RowLayout的最后一个元素是否占据了多余的水平空间?

时间:2017-07-09 18:50:04

标签: java layout swt

我在水平public static void readIn(String file) throws Exception { Scanner scanner = new Scanner(new File(file)); final Map<Integer,List<String>> resultMap = new HashMap<>(); while (scanner.hasNext()) { String[] columns = scanner.nextLine().split("/t"); for(int i=0;i<columns.length;i++){ resultMap.computeIfAbsent(i, k -> new ArrayList<>()).add(columns[i]); } } resultMap.keySet().forEach(index -> System.out.println(resultMap.get(index).toString()));} 中有两个元素。 我能够为第二个元素(例如200像素)指定(最小)。此外...

a)如果shell的总宽度太小,则第二个元素换行到新行。这适用于export ORACLE_HOME=/path/to/oracle/home/directory

b)如果总和为“大”,则第二个(=最后一个)元素应抓住多余的水平空间

是否可以使用RowLayout?或者我是否需要使用RowLayout并自行实现包装(例如,在网格布局中使用一列或两列,具体取决于元素的大小)?

RowLayout

enter image description here

2 个答案:

答案 0 :(得分:1)

RowLayout不支持您要查找的内容。我建议您按照建议使用GridLayout和调整大小的侦听器,或者实现自己的布局。

答案 1 :(得分:0)

我首先尝试编写一个结果很难的自定义布局。基于GridLayout的第二个策略更容易。以下是自定义Composite的初稿,可将其GridLayout的列数切换为一列或两列,具体取决于其子级的大小。

(调整部分大小时,我仍然遇到闪烁问题。)

package org.treez.core.adaptable.composite;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;

/**
 * A row composite for only two children. If the children are too large for a single line, the second child is wrapped
 * on a second line. The second child always grabs excess horizontal space. This composite automatically sets the
 * LayoutData of its children. Therefore the LayoutData of the children should not be set manually.
 */
public class GrabbingRowComposite extends Composite {

    //#region ATTRIBUTES

    private int widthHintForFirstChild = 80;

    private int minWidthForSecondChild = 200;

    private boolean isSingleLine = true;

    //#end region

    //#region CONSTRUCTORS

    public GrabbingRowComposite(Composite parent) {
        super(parent);
        super.setLayout(createLayout());

        if (parent.getLayout() instanceof GridLayout) {
            GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
            setLayoutData(gridData);
        }

    }

    //#end region

    //#region METHODS

    private GridLayout createLayout() {

        //create default layout for single line
        GridLayout gridLayout = new GridLayout(2, false);

        //change layout to use several lines if required
        this.addControlListener(new ControlAdapter() {

            @Override
            public void controlResized(ControlEvent e) {
                adaptLayout();
            }
        });

        return gridLayout;
    }

    private void adaptLayout() {

        int totalWidth = this.getBounds().width;

        Control[] children = getChildren();
        if (children.length < 2) {
            return;
        }

        Control firstChild = children[0];
        Control secondChild = children[1];
        int firstChildWidth = children[0].getBounds().width;

        setWidthHintForFirstChild(firstChild);
        setGrapHorizontalSpaceForSecondChild(secondChild);

        boolean isTooSmallForOneLine = totalWidth < firstChildWidth + minWidthForSecondChild;
        if (isTooSmallForOneLine) {
            setTwoLineLayout();
        } else {
            setSingleLineLayout();
        }
    }

    private void setTwoLineLayout() {
        if (isSingleLine) {
            super.setLayout(new GridLayout(1, false));
            updateLayoutOfParentAndGrandParent();
            isSingleLine = false;
        }
    }

    private void setSingleLineLayout() {
        if (!isSingleLine) {
            super.setLayout(new GridLayout(2, false));
            updateLayoutOfParentAndGrandParent();
            isSingleLine = true;
        }
    }

    private void setWidthHintForFirstChild(Control firstChild) {
        GridData firstGridData = new GridData();
        firstGridData.widthHint = widthHintForFirstChild;
        firstChild.setLayoutData(firstGridData);
    }

    private static void setGrapHorizontalSpaceForSecondChild(Control secondChild) {
        GridData secondGridData = new GridData(SWT.FILL, SWT.FILL, true, false);
        secondChild.setLayoutData(secondGridData);
    }

    private void updateLayoutOfParentAndGrandParent() {
        Composite parent = getParent();
        if (parent != null) {
            parent.layout(true);
            Composite grandParent = parent.getParent();
            if (grandParent != null) {
                grandParent.layout(true);
            }
        }
    }

    //#end region

    //#region ACCESSORS

    @Override
    public void setLayout(Layout layout) {
        throw new IllegalStateException("The layout of this composite must not be changed");
    }

    //#end region

}

使用示例

package org.treez.core.adaptable.composite;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.Section;

public class GrabbingRowCompositeDemo {

    public static void main(String[] args) {

        Shell shell = createShell();

        shell.setSize(500, 300);

        Section section = createSection(shell);

        Composite parentComposite = createParentComposite(section);

        createRow(parentComposite, "first");

        createRow(parentComposite, "second");

        createRow(parentComposite, "third");

        section.clientVerticalSpacing = 0;

        showUntilClosed(shell);

    }

    private static Shell createShell() {
        Display display = new Display();
        Shell shell = new Shell(display);

        GridLayout shellGridLayout = new GridLayout(1, false);
        shell.setLayout(shellGridLayout);
        return shell;
    }

    private static Section createSection(Shell shell) {
        Section section = new Section(
                shell,
                ExpandableComposite.TWISTIE | //
                        ExpandableComposite.EXPANDED | //
                        ExpandableComposite.TITLE_BAR | //
                        ExpandableComposite.CLIENT_INDENT);

        GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
        section.setLayoutData(gridData);
        return section;
    }

    private static Composite createParentComposite(Section section) {

        Composite parentComposite = new Composite(section, SWT.NONE);
        section.setClient(parentComposite);

        parentComposite.setBackground(new Color(null, 0, 0, 255));

        GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
        parentComposite.setLayoutData(gridData);

        GridLayout gridLayout = new GridLayout(1, false);
        parentComposite.setLayout(gridLayout);

        return parentComposite;
    }

    private static Composite createRow(Composite parent, String text) {

        GrabbingRowComposite row = new GrabbingRowComposite(parent);
        row.setBackground(new Color(null, 255, 255, 255));

        Label label = new Label(row, SWT.NONE);
        label.setText(text);

        Button checkBox = new Button(row, SWT.CHECK);
        checkBox.setBackground(new Color(null, 255, 0, 0));

        return row;

    }

    private static void showUntilClosed(Shell shell) {

        shell.open();
        Display display = Display.getCurrent();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }

}