【问题标题】:Resize expandbar SWT in ScrolledComposite在 ScrolledComposite 中调整展开栏 SWT 的大小
【发布时间】:2014-02-21 02:11:52
【问题描述】:

我正在构建一个 java SWT 独立应用程序,其中包含一个滚动复合材料内的扩展栏。在某些时候,我将向其中一个组件添加一个字段。因此,项目的大小将增长。首先我销毁扩展栏中的所有当前项目:

 public void closeAll(){
    for(int a = bar.getItemCount()-1; a>=0; a--){
        bar.getItem(a).getControl().dispose();
        bar.getItem(a).dispose();
    }
}

然后我将再次阅读它们(我将复合材料存储在其他地方)。我重新计算每个项目的高度:

for(int a = 0; a<bar.getItemCount(); a++){
        bar.getItem(a).setHeight(bar.getItem(a).getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);

    }

当我完成所有这些操作时,滚动复合不会进一步向下滚动(扩展栏的一部分现在位于 ScrolledComposite 的客户区域之外)。

当我调整窗口本身的大小时,所有问题都解决了。那么我如何才能在没有代码的情况下强制执行通常与调整窗口大小相关的更新呢?

提前谢谢大家!

//编辑

我已经添加了我正在谈论的课程:

public class InputPanel extends Panel implements Refresh{

private Editor parent;
private ExpandBar expandBar;

private ArrayList<InputBlock> blocks;
public ScrolledComposite scroll;



public InputPanel(Editor parent, Composite panel) {
    super(panel);
    this.parent = parent;
    setGridLayout(0,0,1);
    blocks = new ArrayList<InputBlock>();
    init();
}
private void init(){
    //two pannels first button pannel
    Panel buttonPanel = new Panel(new Composite(panel, SWT.BORDER));
    buttonPanel.setGridLayout(0, 0, 3);
    buttonPanel.fillGridData();

    Composite barComp = new Composite(panel, SWT.BORDER);

    barComp.setLayout(new FillLayout());
    GridData data1 = new GridData();
    data1.grabExcessHorizontalSpace = true;
    data1.horizontalAlignment = SWT.FILL;
    data1.verticalAlignment = SWT.FILL;
    barComp.setLayoutData(data1);

    scroll = new ScrolledComposite(barComp, SWT.V_SCROLL);
    expandBar = new ExpandBar(scroll, SWT.None);
    GridData data = new GridData();
    data.grabExcessHorizontalSpace = true;
    data.grabExcessVerticalSpace = true;
    data.horizontalAlignment = SWT.FILL;
    data.verticalAlignment = SWT.TOP;

    scroll.setContent(expandBar);
    scroll.setExpandVertical(true);
    scroll.setExpandHorizontal(true);
    scroll.setAlwaysShowScrollBars(true);
    for(int a = 0; a<Main.database.size(); a++){
        Composite composite = new Composite(expandBar, SWT.BORDER);
        blocks.add(new InputBlock(this, composite, Main.database.get(a)));
        addItem(composite, Main.database.get(a).name);
    }
    refreshHeights();
    scroll.setMinSize(expandBar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    scroll.layout(true);
}
public void addItem(Composite composite, String tabName){
    ExpandItem expandItem = new ExpandItem(expandBar, SWT.None);
    expandItem.setText(tabName);
    expandItem.setControl(composite);
    expandItem.setExpanded(true);
    composite.setVisible(true);
}
public void refreshHeights(){
    for(int a = 0; a<expandBar.getItemCount(); a++){
        expandBar.getItem(a).setHeight(expandBar.getItem(a).getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
    }

}
public void closeAll(){
    ExpandItem[] items = expandBar.getItems();
    System.out.println(items.length);

    for(int a = items.length-1; a>=0; a--){
        items[a].getControl().dispose();
        items[a].dispose();
    }
}


public void refresh(){
    closeAll();
    blocks = new ArrayList<InputBlock>();
    for(int a = 0; a<Main.database.size(); a++){
        Composite composite = new Composite(expandBar, SWT.BORDER);
        blocks.add(new InputBlock(this, composite, Main.database.get(a)));
        addItem(composite, Main.database.get(a).name);
    }
    refreshHeights();
    scroll.setMinSize(expandBar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    scroll.layout(true);
}

public Editor getParent(){
    return parent;
}


public void setEditorMenu(boolean show){
    for(int a = 0; a<blocks.size(); a++){
        blocks.get(a).setEditorMenu(show);
    }
}



public ArrayList<InputBlock> getBlocks(){
    return blocks;
}
public boolean setValue(DatabaseField field, String value){
    value = value.trim();
    for(int a = 0; a<blocks.size(); a++){
        if(blocks.get(a).setValue(field, value)){
            return true;
        }
    }
    return false;
}

}

我试图做一个例子,但是这个例子是开箱即用的。我看不出有什么区别。 InputBlocks 是保存有关组合中所需字段的数据的类,如果调用它们将产生组合。

持有 ScrolledComposite 的复合材料目前以 SashForm 形式存在,我不知道这是否会有所不同?

我收到此错误(仅在 Linux 上),但在我尝试的示例中没有:

SWT:12455): Gtk-CRITICAL **: IA__gtk_widget_map: assertion `gtk_widget_get_visible (widget)' failed
(SWT:12455): Gtk-CRITICAL **: IA__gtk_widget_map: assertion `gtk_widget_get_visible (widget)' failed
(SWT:12455): Gtk-CRITICAL **: IA__gtk_widget_map: assertion `gtk_widget_get_visible (widget)' failed

更新

我为我的问题做了一个更好的例子。此代码正在运行并为我生成相同的错误:

(SWT:6765): Gtk-CRITICAL **: IA__gtk_widget_map: assertion `gtk_widget_get_visible (widget)' failed

我用过这段代码:

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
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.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;


 public class ExpandBarExample implements SelectionListener{



public static void main(String[] args){
    Display display = new Display();
    Shell shell = new Shell(display);
    new ExpandBarExample(shell);
    shell.setMaximized(true);
    shell.setLayout(new FillLayout());
    shell.open();

    while(!shell.isDisposed()){
        if(!display.readAndDispatch()){
            display.sleep();
        }
    }
    display.dispose();
}

private  ExpandBar bar;
private  ScrolledComposite scroll;
private  Composite composite;
private SashForm sash;
private CTabFolder folder;
private Button button;

public ExpandBarExample(Composite composite){
    this.composite = composite;

    init();
}
public void init(){


    composite.setLayout(new FillLayout());
    sash = new SashForm(composite, SWT.VERTICAL);

    folder = new CTabFolder(sash, SWT.None);


    scroll = new ScrolledComposite(folder, SWT.V_SCROLL);
    GridData data = new GridData();
    data.grabExcessHorizontalSpace = true;
    data.grabExcessVerticalSpace = true;

    bar = new ExpandBar(scroll, SWT.NONE);
    scroll.setContent(bar);
    scroll.setExpandVertical(true);
    scroll.setExpandHorizontal(true);
    scroll.setAlwaysShowScrollBars(true);



    CTabItem tab = new CTabItem(folder, SWT.None);
    tab.setControl(scroll);
    tab.setText("TEST");

    Composite sashFill = new Composite(sash, SWT.BORDER);
    sashFill.setLayout(new FillLayout());
    button = new Button(sashFill, SWT.PUSH);
    button.addSelectionListener(this);
    button.setText("Add block");

    sash.setWeights(new int[]{3,1});

    for(int a = 0; a<10; a++){
        Composite composite = new Composite(bar, SWT.BORDER);

        composite.setLayout(new GridLayout(2, false));

        for(int b = 0; b<10; b++){
            Label label = new Label(composite, SWT.BORDER);
            label.setText("TEST");
        }

        addItem(composite, "Item " + a);
    }
    computeHeights();
    scroll.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    scroll.layout(true);



    //delete old panels
    removeAll();
    //trying to add more panels

    for(int a = 0; a<10; a++){
        Composite composite = new Composite(bar, SWT.BORDER);


        composite.setLayout(new GridLayout(2, false));

        for(int b = 0; b<20; b++){
            Label label = new Label(composite, SWT.BORDER);
            label.setText("TEST");
        }

        addItem(composite, "Item " + a);
    }


    computeHeights();
    scroll.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    scroll.layout(true);

}
public void refresh(){

}
public void removeAll(){
    ExpandItem[] items = bar.getItems();
    System.out.println(items.length);

    for(int a = items.length-1; a>=0; a--){
        items[a].getControl().dispose();
        items[a].dispose();
    }
}
public void addItem(Composite composite, String tabName){
    ExpandItem expandItem = new ExpandItem(bar, SWT.None);
    expandItem.setText(tabName);
    expandItem.setControl(composite);
    expandItem.setExpanded(true);
}
public void computeHeights(){
    for(int a = 0; a<bar.getItemCount(); a++){
        bar.getItem(a).setHeight(bar.getItem(a).getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
    }
}
@Override
public void widgetSelected(SelectionEvent e) {
    if(e.getSource() == button){
        Composite comp = new Composite(bar, SWT.BORDER);
        comp.setLayout(new GridLayout(2, false));
        for(int a = 0; a<10; a++){
            Label label = new Label(comp, SWT.BORDER);
            label.setText("TEST");
        }
        comp.layout(true);
        addItem(comp, "ADDED");
        computeHeights();

        scroll.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));

        scroll.layout(true, true);
    }

}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
    // TODO Auto-generated method stub

}

}

我尝试在 Ubuntu 和 OpenSuse 上运行它,都给出了相同的 Gtk 错误。我希望有人可以帮助我!

【问题讨论】:

  • 你可能需要更新ScrolledComposite的最小尺寸:scrolled.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
  • 我试过这个,但没有任何反应。还尝试进行正常的调整大小 scrolled.setSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT)) 没有运气
  • 你能不能创建一个Minimal, Complete, Tested and Readable example?如果没有代码来测试它,总是很难弄清楚发生了什么。
  • 我认为您需要同时拨打scrolled.setMinSizescrolled.layout(true)
  • 您能解释一下您在新代码中看到的除了 GTK 错误之外的问题吗?

标签: java swt scrolledcomposite


【解决方案1】:

其实 1 毫秒就足够了!

expandBar.addExpandListener(new ExpandAdapter() {
        @Override
        public void itemExpanded(ExpandEvent e) {
            resetScrolledCompositeMinSize();
        }
        @Override
        public void itemCollapsed(ExpandEvent e) {
            resetScrolledCompositeMinSize();
        }
        private void resetScrolledCompositeMinSize() {
            Display.getDefault().timerExec(1, new Runnable() //1 ms is more than enough!!
            {
                @Override
                public void run()
                {
                    scrolledComposite.setMinSize(expandBar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
                }
            });
        }
    });

【讨论】:

    【解决方案2】:

    好的,我找到了解决方法。这并不是真正解决问题的解决方案,而是避免问题的解决方案。

    您的问题似乎是由扩展ExpandItem 时发生的延迟引起的。因此,更新 minSize 的代码使用未扩展的大小。在设置 minSize 之前添加延迟可以解决您的问题。尝试使用延迟值,但 300 毫秒似乎工作得很好,并且不会真正影响可用性:

    public static void main(String[] args)
    {
        Display display = new Display();
        Shell shell = new Shell(display);
        new ExpandBarExample(shell);
        shell.setMaximized(true);
        shell.setLayout(new FillLayout());
        shell.open();
    
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
            {
                display.sleep();
            }
        }
        display.dispose();
    }
    
    private ExpandBar           bar;
    private ScrolledComposite   scroll;
    private Composite           composite;
    private SashForm            sash;
    private CTabFolder          folder;
    private Button              button;
    
    public ExpandBarExample(Composite composite)
    {
        this.composite = composite;
    
        init();
    }
    
    public void init()
    {
    
        composite.setLayout(new FillLayout());
        sash = new SashForm(composite, SWT.VERTICAL);
    
        folder = new CTabFolder(sash, SWT.None);
    
        scroll = new ScrolledComposite(folder, SWT.V_SCROLL);
        GridData data = new GridData();
        data.grabExcessHorizontalSpace = true;
        data.grabExcessVerticalSpace = true;
    
        bar = new ExpandBar(scroll, SWT.NONE);
        scroll.setContent(bar);
        scroll.setExpandVertical(true);
        scroll.setExpandHorizontal(true);
        scroll.setAlwaysShowScrollBars(true);
    
        CTabItem tab = new CTabItem(folder, SWT.None);
        tab.setControl(scroll);
        tab.setText("TEST");
    
        Composite sashFill = new Composite(sash, SWT.BORDER);
        sashFill.setLayout(new FillLayout());
        button = new Button(sashFill, SWT.PUSH);
        button.addListener(SWT.Selection, new Listener()
        {
            @Override
            public void handleEvent(Event arg0)
            {
                Composite comp = new Composite(bar, SWT.BORDER);
                comp.setLayout(new GridLayout(2, false));
                for (int a = 0; a < 10; a++)
                {
                    Label label = new Label(comp, SWT.BORDER);
                    label.setText("TEST");
                }
                comp.layout(true);
                addItem(comp, "ADDED");
    
                scroll.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
                scroll.layout(true, true);
            }
        });
        button.setText("Add block");
    
        sash.setWeights(new int[] { 3, 1 });
    
        scroll.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
        scroll.layout(true);
    }
    
    public void refresh()
    {
    
    }
    
    public void removeAll()
    {
        ExpandItem[] items = bar.getItems();
        System.out.println(items.length);
    
        for (int a = items.length - 1; a >= 0; a--)
        {
            items[a].getControl().dispose();
            items[a].dispose();
        }
    }
    
    public void addItem(Composite composite, String tabName)
    {
        final ExpandItem expandItem = new ExpandItem(bar, SWT.None);
        expandItem.setText(tabName);
        expandItem.setControl(composite);
        expandItem.setExpanded(true);
        expandItem.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
    
        Display.getDefault().timerExec(300, new Runnable()
        {
            @Override
            public void run()
            {
                scroll.setMinSize(bar.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
                scroll.layout(true, true);
            }
        });
    }
    

    【讨论】:

    • 对于遇到 scoll 错误的人,在添加 expandItem 后它没有滚动,这也将解决它!谢谢巴兹!
    • @user1997322 很高兴我能帮上忙!
    猜你喜欢
    • 2020-04-26
    • 2017-04-08
    • 2023-04-08
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多