Java - SWT - problem z dopasowaniem wyglądu okna

0

O ile wykorzystując AWT i BorderLayout sobie jakoś poradziłam, to z SWT nie mogę dostosować sobie odpowiednio wyświetlania programu..

Aktualnie mam taki konstruktor:

 
public exSWT() {
		Display display = new Display();
		Shell sShell = new Shell(display);

		Composite composite = new Composite(sShell, SWT.EMBEDDED);
		FillLayout fillLayout = new FillLayout();
		fillLayout.type = SWT.VERTICAL;
		sShell.setLayout(fillLayout);
		sShell.setSize(650, 500);
		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();
}

i główne okno jest dzielony na dwie części... I z tego co się doczytałem jest to dobrze wykonane, tylko w takim przypadku mój button jest na połowe całego okna :| a wystarczy mi tylko mały button w kształcie paska (20px) na dole tej ramki...reszte moze byc canvas...

Jak uzyskać taki efet? (szukałam po różnych przykładach np. z rowlayout itp ale jakoś nie mogę nic tutaj dopasować..)

Jako osoba początkująca, gine! :(

Prosze o pomoc,
Pozdrawiam, M.

0

Pierwszy i zaraz ostatni raz podbijam ten temat.. bo nie wiem o czym może świadczyć brak odpowiedzi.. czy rozwiązanie mojego problemu jest aż tak trudne czy mozne na tyle żenujące, że nikt nie chce odpowiedziec... ;> (mimo wszystko ja sie nie pogniewam jak ktos zdecyduje się pomóc ;) )

0

Umm niewiem ale może layout na panelu powinien być null? Przynajmniej tak się eliminuje ten problem w awt.

0

@PolishCivil - powiem Ci, że nie wiem jak ma wyglądać twa wskazówka w praktyce.. :|

0
marialenna napisał(a):

@PolishCivil - powiem Ci, że nie wiem jak ma wyglądać twa wskazówka w praktyce.. :|

frame.setLayout(null)

0

To zagranie tutaj nie przechodzi, niestety ..

0

Wklej jakiś działający kod, a nie sam konstruktor. Swoją droga nazwa konstruktora wskazuje, że nazwa klasa zaczyna się od małej litery - nie trzymasz się konwencji. Nie wiem skąd się to wzięło, dlaczego tak, a nie inaczej i co to ma niby robić:

canvas = getCanvas(100, 80);
frame.add(canvas);
getButton(sShell, frame);

0

Proszę... można teraz zobaczyć sobie w czym rzecz..

 
package gui;

import java.awt.*;
import java.awt.event.*;

import javax.swing.JComponent;

//import org.eclipse.swt.*;
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;

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

		Composite composite = new Composite(sShell, SWT.EMBEDDED);
		FillLayout fillLayout = new FillLayout();
		fillLayout.type = SWT.VERTICAL;
		sShell.setLayout(fillLayout);
		sShell.setSize(650, 500);
		
		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();
		}


	/**
	 * Metoda obslugująca rysowanie x - pozycja x y - pozycja y
	 * 
	 */
	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); // 75, 50
					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;
	}

	/**
	 * Przycisk rysowania/czyszczenia
	 * 
	 */
	public Button getButton(Shell shell, final Frame frame) {
		final Button button = new Button(shell, SWT.PUSH);
		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");
				}
				// odswiezenie
				Rectangle rect = frame.getBounds();
				canvas.repaint(rect.x, rect.y, rect.width, rect.height);
			}
		}
		);
		return button;
	}

}

0

Czy musisz korzystać z AWT + SWT? Nie wystarczy Ci samo SWT? Bo tak na szybko nie widzę w tym kodzie powodu by to łączyć.

Czy wiesz, że layout FillLayout ma obecnie tylko sShell? W sShell znajdują się dwa kolejne komponenty composite i button. composite nie ma żadnego ustawionego layout'u (będąc jednak precyzyjnym to ma layout absolute - czyli taki w którym co do piksela trzeba określić położenie i rozmiar komponentu - jest to mało elastyczne i niewygodne, ale czasem przydatne).

0

Akurat to ćwiczenie wymagało użycia AWT + SWT...

Ogólnie to ten przykład był robiony w ramach zadań na laboratorium powiedzmy z podstaw Javy..

Co do ustawień layoutów to zapewne masz racje.. Ja nie jestem na tyle wtajemniczona w te rzeczy bo jak pisałam poznajemy podstawy... w związku z tym szukam jakiegoś rozwiązania typu copy/paste (od osoby znającej temat) bo samemu za dużo czasu mi to zajmie.. A inne zadania czekają w kolejce..

0

W/g mnie jednym z najbardziej elastycznych layout'ów w SWT jest FormLayout. Poprawiłem Twój przykład poniżej:

package gui;
 
import java.awt.*;
import java.awt.event.*;
 
import javax.swing.JComponent;
 
//import org.eclipse.swt.*;
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();
                }
 
 
        /**
         * Metoda obslugująca rysowanie x - pozycja x y - pozycja y
         * 
         */
        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); // 75, 50
                                        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;
        }
 
        /**
         * Przycisk rysowania/czyszczenia
         * 
         */
        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");
                                }
                                // odswiezenie
                                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:

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.

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.

0

Po pierwsze - dzięki za zainteresowanie :)
Po drugie - button niby jest mniejszy, ale wygląda to trochę na oszukanie sprawy :P,
tzn. wygląda to u mnie tak jakby część buttonu była schowana pod warstwą canvas'a.. bo np. teraz nie widać napisu Rysuj <-> Czyść..

user image

0

Nic nie jest oszukane. Coś ci się po prostu rozjechało. Dlaczego frame.getBounds(), a nie canvas.getBounds()? Frame nie musi mieć takich samych rozmiarów jak canvas. Może na sztywno ustawiasz/pobierasz jakieś rozmiary?

A tak w ogóle w composite masz layout absolute. W composite umieszczasz komponent frame. Frame ma z kolei layout BorderLayout (z AWT). Nastepnie we frame masz dopiero komponent canvas.

Daj więcej kodu, żeby można było coś uruchomić. Ja nie wiem co ty masz np. w metodzie main.

0

To jest praktycznie caly kod.. Ogólnie to w main mam tylko utworzenie obiektu klasy exSWT, czyli exSWT obiekt = exSWT(); (cała reszta kodu jest tutaj na forum).

0

Po co stosujesz konstrukcje ze Swinga? Np. frame.add(canvas) lub public void paint(Graphics g)?

0

Kod canvas oraz kod button'a był dostarczony do zadania przez belfra.. (nie było to zależne ode mnie..) (ok, jeśli jest z tą przeróbką tyle problemów to może odpuśćmy..)

1 użytkowników online, w tym zalogowanych: 0, gości: 1