2014-01-29 8 views
1

Я создаю автономное приложение Java SWT с расширителем в прокручиваемом виде. В какой-то момент я добавлю поле в один из компонентов. Следовательно, размер элемента будет расти. Во-первых я уничтожить все существующие элементы внутри expandbar:Изменение размера expandbar SWT в ScrolledComposite

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

Тогда я буду readd их все снова (я есть композиты, хранящиеся где-то еще). И я пересчитывать высоту каждого элемента:

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

    } 

И когда я делаю все это, то прокручивается композит не будет прокручиваться дальше вниз (часть expandbar теперь вне клиентской области 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 

UPDATE

Я сделал лучший пример моей проблемы. Этот код работает и генерировать ту же ошибку, для меня:

(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. Надеюсь, кто-то может мне помочь!

+0

Вы, вероятно, придется обновить MinSize в 'ScrolledComposite':' scrolled.setMinSize (bar.computeSize (SWT.DEFAULT, SWT.DEFAULT)); '. – Baz

+0

Я пробовал это, но потом ничего не происходит. Также попытался сделать обычное изменение размера scrolled.setSize (bar.computeSize (SWT.DEFAULT, SWT.DEFAULT)) нет удачи там – user1997322

+0

Можете ли вы создать [Минимальный, полный, проверенный и читаемый пример] (http: // stackoverflow. ком/помощь/mcve)? Всегда сложно понять, что происходит, если у вас нет кода для тестирования. – Baz

ответ

0

Хорошо, я нашел обходное решение. Это не решение, которое устраняет проблему, а скорее то, что позволяет избежать этого.

Ваша проблема связана с задержкой, возникающей при расширении 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); 
     } 
    }); 
} 
+0

Для людей, испытывающих ошибку со scoll, которую она не прокрутила после добавления expandItem, это также решит ее! Спасибо, Баз! – user1997322

+0

@ user1997322 Рад, что я мог помочь! – Baz

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)); 
       } 
      }); 
     } 
    });