Impedir que o SWT ScrolledComposite coma parte de seus filhos
Pergunta
O que eu fiz errado?
Aqui está um trecho do meu código:
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
ScrolledComposite scrollBox = new ScrolledComposite(parent, SWT.V_SCROLL);
scrollBox.setExpandHorizontal(true);
mParent = new Composite(scrollBox, SWT.NONE);
scrollBox.setContent(mParent);
FormLayout layout = new FormLayout();
mParent.setLayout(layout);
// Adds a bunch of controls here
mParent.layout();
mParent.setSize(mParent.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
}
... mas corta o último botão:
irmão mais velho82:Isso não funcionou.
SCdF:Tentei sua sugestão e agora as barras de rolagem desapareceram.Preciso trabalhar um pouco mais nisso.
Solução
Este é um obstáculo comum ao usar ScrolledComposite
.Quando fica tão pequeno que a barra de rolagem precisa ser mostrada, o controle do cliente precisa encolher horizontalmente para liberar espaço para a barra de rolagem.Isso tem o efeito colateral de fazer alguns rótulos quebrarem as linhas, o que moveu os controles seguintes mais para baixo, o que aumentou a altura mínima necessária para a composição do conteúdo.
Você precisa ouvir as alterações de largura no conteúdo composto (mParent
), calcule a altura mínima novamente dada a nova largura do conteúdo e chame setMinHeight()
no composto rolado com nova altura.
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
ScrolledComposite scrollBox = new ScrolledComposite(parent, SWT.V_SCROLL);
scrollBox.setExpandHorizontal(true);
scrollBox.setExpandVertical(true);
// Using 0 here ensures the horizontal scroll bar will never appear. If
// you want the horizontal bar to appear at some threshold (say 100
// pixels) then send that value instead.
scrollBox.setMinWidth(0);
mParent = new Composite(scrollBox, SWT.NONE);
FormLayout layout = new FormLayout();
mParent.setLayout(layout);
// Adds a bunch of controls here
mParent.addListener(SWT.Resize, new Listener() {
int width = -1;
public void handleEvent(Event e) {
int newWidth = mParent.getSize().x;
if (newWidth != width) {
scrollBox.setMinHeight(mParent.computeSize(newWidth, SWT.DEFAULT).y);
width = newWidth;
}
}
}
// Wait until here to set content pane. This way the resize listener will
// fire when the scrolled composite first resizes mParent, which in turn
// computes the minimum height and calls setMinHeight()
scrollBox.setContent(mParent);
}
Ao ouvir as alterações de tamanho, observe que ignoramos quaisquer eventos de redimensionamento em que a largura permanece a mesma.Isso ocorre porque as alterações na altura do conteúdo não afetam o mínimo altura do conteúdo, desde que a largura seja a mesma.
Outras dicas
Se não me engano você precisa trocar o
mParent.layout();
e
mParent.setSize(mParent.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
para que você tenha:
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
ScrolledComposite scrollBox = new ScrolledComposite(parent, SWT.V_SCROLL);
scrollBox.setExpandHorizontal(true);
mParent = new Composite(scrollBox, SWT.NONE);
scrollBox.setContent(mParent);
FormLayout layout = new FormLayout();
mParent.setLayout(layout);
// Adds a bunch of controls here
mParent.setSize(mParent.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
mParent.layout();
}
Você não precisa recalcular o tamanho do scrollBox após o layout?
Tente definir .setMinWidth e .setMinHeight no ScrolledComposite assim que o layout estiver pronto, passando para ele o tamanho do composto principal.