GUI programmering i Java SWT
och Lab 1
DVGA11
Översikt
JAVA SWT/JFace
Lab 1
Översikt till SWT
Hemsida
−
http://www.eclipse.org/swt
Tutorials online
−
http://www.cs.umanitoba.ca/~eclipse/
http://www.cs.umanitoba.ca/~eclipse/2-Basic.pdf
Javadoc
−
http://help.eclipse.org/stable/nftopic/org.eclipse.platform.
doc.isv/reference/api/overview-summary.html
Översikt till SWT
Standard Widget Toolkit (SWT)
−
Använder native widgets via JNI
−
Emulerar widgets som inte finns på host
plattformen
−
Tillhandahåller MVC genom JFace.
−
Flexibilitet (traditionell eller MVC
programmering)
−
Open source
−
kompilerar till native körbar fil med gcj
SWT Hello World
1.
import org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
2.
import org.eclipse.swt.widgets.Shell;
org.eclipse.swt.widgets.Shell;
3.
public class HelloWorld {
4.
public static void main(String[] args)
args) {
5.
Display display = new Display();
6.
Shell shell = new Shell(display);
7.
shell.setText("Hello World");
8.
shell.setSize(250, 100);
9.
10.
shell.open();
11.
12.
while (!shell.isDisposed
()) {
(!shell.isDisposed())
13.
if (!display.readAndDispatch
()) {
(!display.readAndDispatch())
14.
display.sleep();
15.
}
16.
}
17.
display.dispose();
18.
19.
}
}
SWT Hello World (fortsätt.)
shell och display
Shell objekt (rad 6) kan sägas motsvara JFrame i
Swing, dvs topp nivå container som innehåller alla
andra widgets (knappar, labels etc.)
−
Shell måste hållas öppet genom att lyssna efter event med
en while loop (rad 12-16).
Till skillnad mot swing
−
−
Så måste man skapa ett Display objekt (rad 5), som
representerar det underliggand fönsterhanteringssystemet.
Eftersom man hanterar operativssystems objekt så fungerar
inte heller garabage collectorn utan man måste själv se till
att rensa upp (rad 17).
Tar man bort föräldern tas dock alla barnen bort så vanligtvis är detta
allt som krävs
SWT Hello World (fortsätt.)
SWTUtil
• Känns det obekant att inte kunna
använda garbage collectorn kan
man skapa en SWTUtil klass (se
höger)
•SWTUtil.java
import org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
public class SWTUtil {
private static Display display = new Display();
public static Shell getShell()
getShell() {
Hellow World som använder SWTUtil class
Shell shell = new Shell(display);
return shell;
}
import org.eclipse.swt.widgets.*;
public static void openShell(Shell shell) {
public class HelloWorld {
shell.open();
public static void main(String[] args) {
Shell shell = SWTUtil.getShell();
// This loop keeps the shell open constantly listening for events
events
while (!shell.isDisposed
()) {
(!shell.isDisposed())
shell.setText(“Still Hello World");
if (!display.readAndDispatch
()) {
(!display.readAndDispatch())
display.sleep();
shell.setSize(250, 100);
}
}
SWTUtil.openShell(shell);
display.dispose();
}
}
}
}
SWT Display
org.eclipse.swt.widgets.Display
Instanser av den här klassen sköter koppling
mellan SWT och det underliggande
operativsystemet.
Den tillhandahåller även olika metoder för att
komma åt information om operativsystemet
och de resurser som allokeras av SWT
I SWT så är det den tråd som skapar en
instans av Display som anses vara UI tråden
(för den displayen).
SWT Shell
org.eclipse.swt.widgets.Shell
Shell klassen representerar “fönstret" som hanteras
av fönsterhanteraren.
Typer:
−
−
“Top level shell” är ett shell som inte har någon förälder
(de är skapade av konstruktorn som tar en Display som
argument)
Shell som har föräldrar anges som sekundära
(secondary) eller dialog shells.
Tillstånd:
−
−
−
Maximerad (Maximized)
Minimerad (Minimized)
Normal
SWT Shell
org.eclipse.swt.widgets.Shell
Styles (specifika för varje klass):
−
BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL,
APPLICATION_MODAL, MODELESS, PRIMARY_MODAL,
SYSTEM_MODAL
−
Om man vill använda mer än en style kan man använde dem genom bitvis or
operator “|” (ex. CLOSE | TITLE | MIN).
−
Vill man inte ha någon specifik style använd SWT.NONE.
−
Style är bara ett förslag, kan inte det underliggande operativsystemet visa en
style så använder den en default
Fördefinerade konstanter:
−
SHELL_TRIM
−
En sammanslagning av styles (CLOSE | TITLE | MIN | MAX | RESIZE) för att
skapa ett typiskt applikations fönster.
DIALOG_TRIM
En sammanslagning av styles (TITLE | CLOSE | BORDER) för att skapa ett typiskt
dialog ruta.
SWT Widget
org.eclipse.swt.widgets.Widget
Widget klassen är den
abstrakta superklassen för alla
interface objekt
En widget skapas genom att
både specificera en förälder
och en style
En förälder är den container
som widgeten är skapade inuti
(ex. Shell).
Style beror på vilken widget
det är se
−
http://www.eclipse.org/swt/widge
ts/
org.eclipse.swt.widgets.Label
SWT Label
Ej editerbar och ej valbar text
SWT.VERTICAL eller
SWT.HORIZONTAL kan
användas tillsammans med
SWT.SEPARATOR för att skapa
horisontella/vertikala separatorer
LabelWorld.java
1.import
org.eclipse.swt.SWT;
org.eclipse.swt.SWT;
2.import
org.eclipse.swt.layout.GridLayout;
org.eclipse.swt.layout.GridLayout;
3.import
org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
4.public
class LabelWorld {
5.
public static void main(String[] args)
args) {
6.
Shell shell = SWTUtil.getShell();
SWTUtil.getShell();
7.
shell.setText("Label World");
8.
shell.setLayout(new GridLayout());
GridLayout());
9.
// Create labels
10.
new Label(shell, SWT.NONE).setText("Regular label");
11.
new Label(shell, SWT.SEPARATOR);
new Label(shell,
SWT.SEPARATOR|SWT.HORIZONTAL);
12.
13.
14.
// pack and show
15.
shell.pack();
16.
SWTUtil.openShell(shell);
SWTUtil.openShell(shell);
17.
18.}
}
SWT Button
org.eclipse.swt.widgets.Button
Alla typer av knappar skapas genom att använda Button klassen.
−
Klickbar widget, skickar en notifikation när den är klickad på.
−
Styles: ARROW, CHECK, PUSH, RADIO, TOGGLE, FLAT, UP, DOWN, LEFT,
RIGHT, CENTER
9.
ButtonWorld.java
10.
new Button(shell, SWT.PUSH | SWT.FLAT).setText("Flat Push Button");
11.
new Button(shell, SWT.CHECK).setText("Check Button");
12.
new Button(shell, SWT.TOGGLE).setText("Toggle Button");
13.
new Button(shell, SWT.RADIO).setText("Radio Button");
1.import
org.eclipse.swt.SWT;
org.eclipse.swt.SWT;
2.import
org.eclipse.swt.layout.GridLayout;
org.eclipse.swt.layout.GridLayout; 14.
3.import
org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
4.public
5.
class ButtonWorld {
public static void main(String[] args)
args) {
6.
Shell shell = SWTUtil.getShell();
SWTUtil.getShell();
7.
shell.setText("Button World");
shell.setLayout(new GridLayout(2,
true));
8.
15.
// pack and show
16.
shell.pack();
17.
SWTUtil.openShell(shell);
SWTUtil.openShell(shell);
}
18.
19.
}
SWT Text
org.eclipse.swt.widgets.Text
Textruta där användaren kan skriva in text och ändra text
−
Styles: CENTER, LEFT, MULTI, PASSWORD, SINGLE, RIGHT, READ_ONLY,
WRAP
TextWorld.java
10.
new Text(shell, SWT.NONE).setText("Missing something ...");
1.
import org.eclipse.swt.SWT;
org.eclipse.swt.SWT;
11.
new Text(shell, SWT.BORDER); // regular textfield
2.
import org.eclipse.swt.layout.GridLayout;
org.eclipse.swt.layout.GridLayout;
12.
new Text(shell, SWT.PASSWORD | SWT.BORDER).setText("password");
SWT.BORDER).setText("password");
3.
import org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
13.
new Text(shell, SWT.READ_ONLY | SWT.BORDER).setText("Can't type inside");
14.
new Text(shell, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP
4.
5.
public class TextWorld {
public static void main(String[] args)
args) {
| SWT.BORDER).setText("\
SWT.BORDER).setText("\n\n\n");
15.
16.
6.
Shell shell = SWTUtil.getShell();
SWTUtil.getShell();
17.
// pack and show
7.
shell.setText("Text World");
18.
shell.pack();
8.
shell.setLayout(new GridLayout());
GridLayout());
19.
SWTUtil.openShell(shell);
SWTUtil.openShell(shell);
9.
20.
21.
}
}
SWT Combo
org.eclipse.swt.widgets.Combo
Välj ifrån en lista/meny – enkel eller multival möjligt
−
Styles: DROP_DOWN, READ_ONLY, SIMPLE
ComboWorld.java
1.
import org.eclipse.swt.SWT;
org.eclipse.swt.SWT;
2.
import org.eclipse.swt.layout.GridLayout;
org.eclipse.swt.layout.GridLayout;
3.
import org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
4.
5.
public class ComboWorld {
public static void main(String[] args)
args) {
14.
two.setItems(items);
two.setItems(items);
15.
Combo three = new Combo(shell, SWT.SIMPLE);
16.
three.setItems(items);
three.setItems(items);
17.
18.
// pack and show
19.
shell.pack();
20.
SWTUtil.openShell(shell);
SWTUtil.openShell(shell);
}
21.
6.
Shell shell = SWTUtil.getShell();
SWTUtil.getShell();
7.
shell.setText("Combo World");
8.
shell.setLayout(new GridLayout(3, true));
9.
String[] items = "One Two Three Four Five Six".split(" ");
10.
Combo one = new Combo(shell, SWT.DROP_DOWN);
11.
one.setItems(items);
one.setItems(items);
12.
13.
22.
Combo two = new Combo(shell, SWT.DROP_DOWN |
SWT.READ_ONLY);
}
SWT Composites
org.eclipse.swt.widgets.Composite
Instanser av den här
klassen är en widget som
kan innehålla andra widgets
(knappar etc).
Widget w = new Widget(composite,
SWT.NONE);
...
public class CompositeExample {
...
public CompositeExample() {
...
// Build the components
Composite c1 = new Composite( shell, SWT.NULL );
c1.setLayout( new FillLayout() );
Button b1 = new Button( c1, SWT.PUSH );
b1.setText( "Button on Composite 1" );
Composite c2 = new Composite( shell, SWT.NULL );
c2.setLayout( new FillLayout() );
Button b2 = new Button( c2, SWT.PUSH );
b2.setText( "Button on Composite 2" );
...
}
...
}
SWT Layouts
org.eclipse.swt.widgets.Layout
En layout bestämmer position och storlek på en
composite widget
SWT har 5 layouter:
−
FillLayout
−
RowLayout
−
StackLayout
−
GridLayout
−
FormLayout
Man applicerar en layout genom att anropa
setLayout()
http://www.eclipse.org/articles/Article-Understanding-Layouts/Understanding-Layouts.htm
SWT Layouts (forts.)
org.eclipse.swt.layout.FillLayout
Placerar alla widgets in en kolumn eller rad
−
FillLayout
SWT.VERTICAL eller SWT.HORIZONTAL
Alla widgets får samma storlek
SWT Layouts (forts.)
RowLayout
org.eclipse.swt.layout.RowLayout
Liknar Filllayout men tvingar inte alla widgets
att vara lika stora
Byter rad om inte alla widgets får plats
SWT Layouts (forts.)
GridLayout
org.eclipse.swt.layout.GridLayout
Som namnet antyder läggs widgets ut i en grid.
6 attributes (defaults är definerade):
−
boolean makeColumnsEqualWidth – alla kolumner får samma vidd
−
int numColumns – antal kolumner
−
int marginWidth, int marginHeight, int horizontalSpacing, int
verticalSpacing
Bestämmer avstånd till andra objekt och avstånd mellan celler
GridLayout(int numColumns, boolean makeColumnsEqualWidth)
För ytterliggare kontroll använd GridData objekts
−
OBS ett gridData objekt skall inte återanvändas för flera layouter.
SWT Layouts (forts.)
GridData
org.eclipse.swt.layout.GridData
GridData är det layout data objekt som man assoscierar
med GridLayout.
För att aktivera ett GridData objekt för en widget så
använder man widget.setLayoutData(Object) metoden.
Det finns 2 sätt att skapa specifika GridData objekt. Första
sättet är att sätta attributen:
−
GridData gridData = new GridData();
−
gridData.horizontalAlignment = GridData.FILL;
−
gridData.grabExcessHorizontalSpace = true;
−
button1.setLayoutData(gridData);
Det andra är att använda fördefinerade “style bits”:
−
button1.setLayoutData(new
GridData(GridData.HORIZONTAL_ALIGN_FILL |
GridData.GRAB_HORIZONTAL));
SWT Layouts (forts.)
GridLayout exempel
org.eclipse.swt.layout.GridLayout
17.
1.
import org.eclipse.swt.SWT;
org.eclipse.swt.SWT;
18.
2.
import org.eclipse.swt.layout.*;
org.eclipse.swt.layout.*;
19.
3.
import org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
// Password
new Label(shell,
SWT.RIGHT).setText("Password:");
SWT.RIGHT).setText("Password:");
new Text(shell,SWT.BORDER| SWT.PASSWORD)
20.
.GridData(GridData.FILL_HORIZONTAL));
GridData(GridData.FILL_HORIZONTAL));
4.
5.
public class GridLayoutExample {
public static void main(String[] args)
args) {
21.
// Login Button
22.
6.
Shell shell = SWTUtil.getShell();
SWTUtil.getShell();
23.
Button loginButton = new Button(shell, SWT.PUSH | SWT.FLAT);
shell.setText("GridLayoutExample");
shell.setText("GridLayoutExample");
24.
7.
loginButton.setText("Proceed to your account");
25.
GridData data = new GridData(GridData.FILL_HORIZONTAL);
GridData(GridData.FILL_HORIZONTAL);
8.
shell.setLayout(new GridLayout(2, false)); // 2 columns, same width
26.
data.horizontalSpan = 2; // span 2 columns
27.
loginButton.setLayoutData(data);
9.
10.
// Username
11.
new Label(shell, SWT.RIGHT).setText("Username:");
SWT.RIGHT).setText("Username:");
12.
Combo cmbUsername = new Combo(shell, SWT.DROP_DOWN);
13.
cmbUsername.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
GridData(GridData.FILL_HORIZONTAL));
14.
cmbUsername.setItems(new String[]{"Howard", "Admin", "Kalman
"});
"Kalman"});
15.
cmbUsername.setText("Admin");
cmbUsername.setText("Admin");
16.
28.
shell.pack();
29.
SWTUtil.openShell(shell);
SWTUtil.openShell(shell);
}
30.
31.
}
Events
org.eclipse.swt.events
SWT widgets kan lyssna efter events
−
−
För att kunna lyssna på ett event så måste en lyssnare
(listener) läggas till widgeten
Ibland så kan en lyssnare lyssna på för många olika saker
Då använder man en adapter.
Några popolära lyssnare/adaptrar
−
−
−
−
−
−
FocusListener/FocusAdapter – fokus event
KeyListener/KeyAdapter – tangenttryckningar
ModifyListener(1 method) – textändringar
VerifyListener – lyssnare efter och fångar upp textändringar
MouseListener/MouseAdapter – mustryck/klick
SelectionListener/SelectionAdapter – selection events
(liknande ActionListener i Swing)
Events (EventHandling.java)
1.
import org.eclipse.swt.SWT;
org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
org.eclipse.swt.events.*;
29.
2.
Button btnAllow = new Button(shell, SWT.CHECK);
3.
import org.eclipse.swt.layout.*;
org.eclipse.swt.layout.*;
30.
btnAllow.setText("Allow numbers only");
4.
import org.eclipse.swt.widgets.*;
org.eclipse.swt.widgets.*;
31.
5.
public class EventHandling {
32.
data.horizontalSpan = 2;
33.
btnAllow.setLayoutData(data);
btnAllow.setLayoutData(data);
6.
private static boolean numbersOnly;
numbersOnly;
7.
public static void main(String[] args)
args) {
8.
Shell shell = SWTUtil.getShell();
SWTUtil.getShell();
9.
shell.setText("EventHandling");
shell.setText("EventHandling");
10.
shell.setLayout(new GridLayout(2, false));
11.
12.
// input
13.
Label lblInput = new Label(shell, SWT.RIGHT);
14.
lblInput.setText("Type in here:");
15.
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END);
GridData(GridData.HORIZONTAL_ALIGN_END);
16.
34.
data = new
GridData(GridData.HORIZONTAL_ALIGN_CENTER);
GridData(GridData.HORIZONTAL_ALIGN_CENTER);
btnAllow.addSelectionListener(new
SelectionAdapter()
SelectionAdapter() {
35.
public void widgetSelected(SelectionEvent selectionEvent)
selectionEvent)
{
36.
numbersOnly = ((Button)(selectionEvent.widget)).getSelection
();
((Button)(selectionEvent.widget)).getSelection();
}
37.
38.
});
lblInput.setLayoutData(data);
lblInput.setLayoutData(data);
39.
shell.pack();
17.
Text input = new Text(shell, SWT.BORDER);
40.
SWTUtil.openShell(shell);
SWTUtil.openShell(shell);
18.
input.addVerifyListener(new VerifyListener()
VerifyListener() {
19.
20.
vEvent.doit = false; // don't allow anything but numbers
21.
if(!numbersOnly || vEvent.character == '\
'\b') {
vEvent.doit = true;
22.
23.
}
24.
else if(Character.isDigit(vEvent.character)
if(Character.isDigit(vEvent.character) && numbersOnly)
numbersOnly) {
vEvent.doit = true;
25.
}
26.
}
27.
28.
});
}
41.
public void verifyText(VerifyEvent vEvent)
vEvent) {
42.
}
syncExec() / asyncExec()
org.eclipse.swt.events
Man skall endast uppdatera UIet ifrån UI tråden
−
För att uppdatera en Label i UI (huvud) tråden ifrån en
annan tråd så kan man INTE anropa label.setText(Värde)
ifrån den andra tråden.
För att uppdatera så anropar man (på Displayen):
−
syncExec(Runnable) om den anropande tråden kräver svar
eller måste veta att UI tråden är klar innan den fortsätter.
−
asyncExec(Runnable) om man skall göra en UI operation
som inte kräver nått svar eller är oavhängigt av den
anropande trådens exekvering
syncExec() / asyncExec()
Exempel kod för att uppdater en Label ungefär 1 gång i sekunden ifrån en annan tråd
1.
new Thread(new Runnable()
Runnable() {
2.
public void run() {
3.
Display display = shell.getDisplay();
shell.getDisplay();
4.
while(!shell.isDisposed())
while(!shell.isDisposed()) { //kontrollera
//kontrollera så att shellet inte har kastats
5.
try {
display.asyncExec(new Runnable()
Runnable() {
6.
public void run() {
7.
clock.setText((new Date()).toString());
Date()).toString());
8.
}
9.
}); //slut parantes ifrå
ifrån 6
10.
Thread.sleep(1000);
11.
12.
}
13.
catch (InterruptedException
(InterruptedException e) {
e.printStackTrace();
e.printStackTrace();
14.
}
15.
}
16.
17.
18.
}
}).start(); //slut parantes ifrå
ifrån 1
JFace
org.eclipse.jface.*
Bild och font register för att hantera OS resurser
Dialoger och wizards
Progress bars
Action mekanism
−
Action mekanismen separerar användarkommandon från
var de hände i UI. En action representerar ett
användarkommando (event).
−
Viewers och editors
Model-baserade adapters för några SWT widgets som JFace
tillhandahåller hög-nivå semantik för.
http://download.eclipse.org/eclipse/downloads/documentation/2.0/html/plugins/org.eclipse.platform.doc.isv/reference/a
pi/overview-summary.html
JFace exempel 1/3
1.
/**
2.
* Represents a category of items.
items.
3.
*
4.
*/
5.
class Category {
6.
private String name;
name;
7.
private Vector subCategories;
subCategories;
8.
private Category parent;
parent;
9.
public Category(String name,
name, Category parent)
parent) {
10.
11.
this.name = name;
name;
12.
this.parent = parent;
parent;
13.
if(parent != null)
null)
parent.addSubCategory(this);
parent.addSubCategory(this);
14.
15.
}
16.
public Vector getSubCategories()
getSubCategories() {
return subCategories;
subCategories;
17.
18.
}
19.
private void addSubCategory(Category subcategory)
subcategory) {
if(subCategories == null)
null)
20.
Vector categories = new Vector();
2.
Category category = new Category(“
Category(“Java libraries”
libraries”, null);
3.
categories.add(category);
categories.add(category);
4.
category = new Category(“
Category(“UI Toolkits”
Toolkits”, category);
5.
new Category(“
Category(“AWT”
AWT”, category);
6.
new Category(“
Category(“Swing”
Swing”, category);
7.
new Category(“
Category(“SWT/JFace”
SWT/JFace”, category);
8.
category = new Category(“
Category(“Java IDEs”
IDEs”, null);
9.
categories.add(category);
categories.add(category);
10.
new Category(“
Category(“Eclipse”
Eclipse”, category);
11.
new Category(“
Category(“JBuilder”
JBuilder”, category);
subCategories = new Vector();
Vector();
21.
if(!
if(! subCategories.contains(subcategory))
subCategories.contains(subcategory))
22.
subCategories.add(subcategory);
subCategories.add(subcategory);
23.
24.
}
25.
public String getName()
getName() {
return name;
name;
26.
27.
}
28.
public Category getParent()
getParent() {
return parent;
parent;
29.
}
30.
31.
1.
}
http://media.wiley.com/product_data/excerpt/91/04700945/0470094591.pdf
JFace exempel 2/3
På ”traditionellt sätt” utan MVC
final Tree tree = new Tree(shell,
Tree(shell, SWT.BORDER);
12.
1.
/**
/**
13.
2.
* Adds a category to the tree (recursively).
recursively).
* Builds up the tree with traditional approach.
14.
3.
* @param
@param parentItem
*
15.
4.
* @param
@param category
*/
16.
5.
*/
public void traditional()
traditional() {
17.
private void addCategory(TreeItem parentItem,
parentItem, Category category)
category) {
6.
for(int i=0; categories != null && i < categories.size();
categories.size(); i++) {
7.
Category category = (Category)categories.elementAt(i
);
(Category)categories.elementAt(i);
19.
8.
addCategory(null,
addCategory(null, category);
category);
20.
9.
}
10.
11.
}
TreeItem item = null;
null;
18.
if(parentItem == null)
null)
item = new TreeItem(tree,
TreeItem(tree, SWT.NONE);
else
21.
item = new TreeItem(parentItem,
TreeItem(parentItem, SWT.NONE);
22.
23.
item.setText(category.getName());
item.setText(category.getName());
24.
Vector subs = category.getSubCategories();
category.getSubCategories();
25.
for(int i=0; subs != null && i < subs.size();
subs.size(); i++)
addCategory(item,
));
addCategory(item, (Category)subs.elementAt(i
(Category)subs.elementAt(i));
26.
27.
}
http://media.wiley.com/product_data/excerpt/91/04700945/0470094591.pdf
JFace exempel 3/3
Med MVC
1.
final Tree tree = new Tree(shell,
Tree(shell, SWT.BORDER);
20.
public Object[]
Object[] getElements(Object inputElement)
inputElement) {
if(inputElement != null && inputElement instanceof Vector)
Vector) {
21.
2.
/**
3.
* Builds up the tree with the MVC approach.
4.
return ((Vector)inputElement).toArray
();
((Vector)inputElement).toArray();
22.
}
23.
return new Object[0];
24.
*
}
25.
5.
*/
6.
public void MVC() {
public void dispose()
dispose() {
26.
7.
8.
9.
TreeViewer treeViewer = new TreeViewer(tree);
TreeViewer(tree);
28.
}
29.
public void inputChanged(Viewer viewer,
viewer, Object oldInput,
oldInput, Object newInput)
newInput) {
treeViewer.setContentProvider(new ITreeContentProvider()
ITreeContentProvider() {
public Object[]
Object[] getChildren(Object parentElement)
parentElement) {
Vector subcats = ((Category)parentElement).getSubCategories
();
((Category)parentElement).getSubCategories();
10.
return subcats == null ? new Object[0] : subcats.toArray();
subcats.toArray();
11.
12.
//
27.
}
//
30.
}
31.
32.
});
33.
treeViewer.setLabelProvider(new LabelProvider()
LabelProvider() {
13.
public Object getParent(Object element) {
14.
return ((Category)element).getParent
();
((Category)element).getParent();
15.
16.
public String getText(Object element) {
34.
return ((Category)element).getName
();
((Category)element).getName();
35.
}
}
36.
17.
public boolean hasChildren(Object element) {
return ((Category)element).getSubCategories
() != null;
((Category)element).getSubCategories()
null;
18.
19.
});
37.
}
treeViewer.setInput(categories);
treeViewer.setInput(categories);
38.
39.
}
http://media.wiley.com/product_data/excerpt/91/04700945/0470094591.pdf
Lab 1
Luffarschak (Tic-Tac-Toe)
Uppgift: Skriv ett luffarschack spel som går att
spela (ingen AI).
−
Krav (grundläggande)
−
−
Språk : Java SWT
Programmet skall kunna köras utan eclipse med
kommandot java -jar programnamn.jar
Programmet skall använda SWT (ev. JFace)
Frivillig Extra uppgift
−
Lösningen skall vara implementerad med MVC
mönstret
Lab 1
Arbetsgång
Indentifiera problem
−
Vad är Luffaschack
−
Ett spel bestående av 3x3 rutor där varje spelare (X och O)
försöker få 3 i rad (horisontellt vertikalt eller diagonalt (de turas
om att spela).
Hur representerar jag detta
Som ett rutnät på 3x3 med en knapp i varje ruta.
Varje knapp skriver in X el O beroende på vilkens drag det var
när man klickade på den
−
−
”sätter sig” sedan i disabled läge så man inte kan trycka på den
igen.
Problem
Hur kan man veta vilkens tur det är?
Hur veta när någon vunnit?
Hur vet när spelet är slut (om ingen vunnit före detta)?
Lab 1
Lab 1
Arbetsgång
Layout problem
−
Nyckelord :
Knapp problem (storlek)
−
Nyckelord :
shell
setLayout
GridLayout
setLayoutData
GridData
GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL
Event problem
−
Nyckelord :
addSelectionListener
SelectionAdapter
widgetSelected
Lab 1
Arbetsgång
Hur kan man få reda på vems tur det är
−
−
Man kan ha en variabel som alternerar mellan
2 värden
Modulo 2 på en räknare som räknar antal drag
(resten blir 0 varannan gång)
Hur kan man veta att spelet är slut (om
ingen vunnit)
−
−
Alla knapparna är “disabled”
Räkna hur många drag som gjorts (9 rutor, ett
klick per ruta)
Lab 1
Arbetsgång
Hur veta om någon har vunnit
−
Finns bara ett fixt antal sätt att vinna på
−
Kolla alla möjliga vinstkombinationer med if
satser
Lab 1
Arbetsgång
Hur veta om någon har vunnit
−
Skapa en matris med “vinstkombinationer”
−
Loopa över knapparna och kolla mot matrisen
http://forum.codecall.net/java-tutorials/2141-java-tutorial-tic-tac-toe.html