W/g mnie jednym z najbardziej elastycznych layout'ów w SWT jest FormLayout. Poprawiłem Twój przykład poniżej:
Kopiuj
package gui;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JComponent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormAttachment;
public class exSWT {
Canvas canvas = null;
boolean selected = false;
Shell sShell;
Composite composite;
Frame frame;
Display display;
Button okButton;
public exSWT() {
Display display = new Display();
Shell sShell = new Shell(display);
FormLayout fl_sShell = new FormLayout();
fl_sShell.spacing = 2;
fl_sShell.marginWidth = 2;
fl_sShell.marginTop = 2;
fl_sShell.marginRight = 2;
fl_sShell.marginLeft = 2;
fl_sShell.marginHeight = 2;
fl_sShell.marginBottom = 2;
sShell.setLayout(fl_sShell);
Composite composite = new Composite(sShell, SWT.EMBEDDED);
FormData fd_composite = new FormData();
fd_composite.bottom = new FormAttachment(90);
fd_composite.right = new FormAttachment(100);
fd_composite.top = new FormAttachment(0);
fd_composite.left = new FormAttachment(0);
composite.setLayoutData(fd_composite);
sShell.setSize(570, 367);
Frame frame = SWT_AWT.new_Frame(composite);
canvas = getCanvas(100, 80);
frame.add(canvas);
getButton(sShell, frame);
sShell.open();
while (!sShell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public Canvas getCanvas(final int x, final int y) {
Canvas canvas = new Canvas() {
private static final long serialVersionUID = 1L;
public void paint(Graphics g) {
Dimension d = getSize();
g.drawLine(0, 0, d.width, d.height);
g.drawLine(d.width, 0, 0, d.height);
if (selected) {
setBackground(new Color(50, 100, 150));
g.drawString("Test Środowiska GUI", x, y);
g.setColor(Color.blue);
g.fillOval(x + 35, y + 20, 50, 50);
g.setColor(Color.red);
g.drawRoundRect(x - 10, y - 20, 140, 30, 20, 20);
} else
setBackground(new Color(255, 255, 255));
}
};
return canvas;
}
public Button getButton(Shell shell, final Frame frame) {
final Button button = new Button(shell, SWT.PUSH);
FormData fd_button = new FormData();
fd_button.top = new FormAttachment(composite);
fd_button.bottom = new FormAttachment(100);
fd_button.right = new FormAttachment(100);
fd_button.left = new FormAttachment(0);
button.setLayoutData(fd_button);
button.setText("Rysuj");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (selected == false) {
selected = true;
button.setText("Czyść");
} else {
selected = false;
button.setText("Rysuj");
}
Rectangle rect = frame.getBounds();
canvas.repaint(rect.x, rect.y, rect.width, rect.height);
}
}
);
return button;
}
}
Akurat w tym przypadku pozycjonowanie kontrolek za pomocą FormAttachment'ów jest dość proste. Odbywa się ono na osiach X i Y. Omówię to na poniższym kodzie:
Kopiuj
fd_composite.top = new FormAttachment(0);
fd_composite.bottom = new FormAttachment(90);
fd_composite.left = new FormAttachment(0);
fd_composite.right = new FormAttachment(100);
top -> bottom to oś Y. W powyższym przypadku kontrolka ma dla siebie od 0 do 90% osi Y (począwszy od zera) czyli wysokości layout'u.
left -> right to oś X. Zatem w powyższym fragmencie kontrolka zajmie dla siebie od 0 do 100% osi X czyli szerokości layout'u.
Kopiuj
fd_button.top = new FormAttachment(composite);
Powyższy fragment kodu oznacza, że pozycjonujemy do kontrolki. W tym przypadku do komponentu composite, który jest nad kontrolką button.
Oczywiście to nie wyczerpuje tematu layoutu FormLayout. Jego możliwości pozycjonowania są znacznie większe np. offsety, marginesy, itp. Ja tylko dałem punkt zaczepienia.