School of Computing and Mathematical Sciences msc Computing and Information Systems java programming Week 3 February 2003



Дата27.03.2017
Размер166.15 Kb.
School of Computing and Mathematical Sciences

MSc Computing and Information Systems

JAVA Programming Week 3 February 2003

Разполагане на елементите и прихващане на събития
Тази седмицаще бъдат разгледани две различни теми: Първо - Разполагане (Layouts), чрез което се контролира как компонентите да се появяват в аплета. Второ – ще бъде разгледан изключително важният въпрос как да бъдат програмирани компонентите, така че да реагират подходящо на събитията.
Разполагане

Java управлява начина на разполагане на елементите на екрана използвайки група от специални обекти наречени layoutmanagers. Има пет от тях:


FlowLayout, BorderLayout, GridLayout, CardLayout, GridBagLayout
По подразбиране е FlowLayout при който компонентите се вмъкват по същия начин като думите на страницата т.е. отгоре надолу,отляво надясно, но се използва центриране за всеки ред. Точният резултат очевидно ще зависи от размера на монитора на хоста, от резолюцията, от размера на прозореца и т.н. различните компоненти ще бъдат оразмерени автоматично например бутона ще бъде толкова голям, че да се събере заглавието му. За да бъде поставен бутона в аплета, след ...extends Applet{ трябва да бъде написано следното

Button buttonName = new Button("caption");

И
следният ред трябва да се добави в init() метода. (Това винаги е първият метод, който се извиква след зареждане на аплета в браузъра).

add(buttonName);


Ако не е необходимо да се зададе име на бутона, вмъкването може да се съкрати до следния ред

add(new Button("caption"));



Ex 3.1
//MyFlowLayout

//Демонстрира Flow Layout

//който е по подразбиране

class


import java.awt.*;

import java.applet.*;

public class MyFlowLayout extends Applet{

public void init(){

myaddButtons();

} // край на init

public void myaddButtons(){

add(new Button(""));

add(new Button("Short"));

add(new Button("Medium size"));

add(new Button("this is a Really really long one"));

add(new Button("Short"));

add(new Button("Short"));

} // край на myaddButtons

} // край на MyFlowLayout
Подравняването може да се смени в ляво или дясно с помощта на

SetLayout(new FlowLayout(FlowLayout.LEFT));


BorderLayout може да бъде използван за просто оформяне, но има някои ограничения. Разделя областта на аплета на пет области: NORTH,EAST,CENTER,WEST,SOUTH. NORTH и SOUTH областите покриват цялата ширина на аплета (която е зададена в HTML етикета). EAST и WEST ще бъдат направени достатъчно широки за да се събера тяхното съдържание и CENTER заема каквото остане.

З
а да се зададе BorderLayout трябва да се направи

setBorderLayout (new BorderLayout())
Ex 3.2

//BorderDemo.java

//Демонстрира Border Layout

import java.awt.*;

import java.applet.*;
public class BorderDemo extends Applet {

//създава компонентите

Button btnNorth = new Button("North");

Button btnSouth = new Button("South");

Button btnEast = new Button("East");

Button btnWest = new Button("West");


public void init(){

this.setLayout(new BorderLayout());

add(btnNorth, BorderLayout.NORTH);

add(btnSouth, BorderLayout.SOUTH);

add(btnEast, BorderLayout.EAST);

add(btnWest, BorderLayout.WEST);

} // край на init

} // край на BorderDemo


При това подреждане са необходими два параметъра в add() метода.

GridLayout дава по-голяма възможност за управление. Задава се броят на редовете и колоните компонентите се вмъкват в реда, по който са описани в сорс кода, отляво надясно и отгоре надолу. Цялата мрежа се разпъва до размера на аплета независимо от съдържанието на компонентите. За да се остави празно място трябва да се добави празен етикет в мрежата add(new Label()); (този трик не работи при BorderLayout или FlowLayout)
Ex 3.3

//GridDemo.java

/
/Демонстрира Grid Layout

//с мрежа 2 * 3


import java.awt.*;

import java.applet.*;


public class GridDemo extends Applet {
public void init(){

this.setLayout(new GridLayout(2,3));

MyaddButtons();

} // край на init


public void MyaddButtons(){

add(new Button("1"));

add(new Button("2"));

add(new Button("3"));

add(new Button("4"));

add(new Button("5"));

add(new Button("6"));

} // край на MyaddButtons

} // край на GridDemo
Може да се създаде празно пространство между компонентите в мрежата с помощта на друг конструктор за GridLayout - GridLayout(rows,cols,hgap,vgap).

CardLayout подрежда компонентите един върху друг като тесте карти. Така само един компонент е видим, но това подреждане се различава от останалите по това, че предоставя група методи даващи възможност за движение между компонентите. (Ще бъде разгледано по-късно).

GridBagLayout дава по-голяма гъвкавост, но е доста сложно, така че няма да бъде разглеждано.

Null Layout


Ако трябва компонентите да бъдат поставени на точно определено място трябва разполагането да се установи като Null, в такъв случай трябва да бъдат точно дефинирани размера и разположението на всеки един компонент. Добавя се this.setLayout(null); в init() за да се установи layout manager на аплета null и се използват

componentName.setLocation(x,y);

componentName.setSize(width, height);

Трябва да се отбележи, че при това разполагане layout manager не взема под внимание промените в размера на прозореца на аплета и това е неудобство. Но ако е известно как аплета ще бъде използван, в какъв браузър при каква резолюция, и това,че няма да бъде променян размерът му, тогава това разполагане дава максимално ниво на контрол.


Панели(Panels)


Панелите са невидими компоненти, които подпомагат структурирането на изображението. Основната им функция е да държат елементите заедно. Например, ако има два бутона, които трябва винаги да са заедно, независимо от размера на прозореца на аплета, те се вмъкват в панела. Могат да бъдат вмъквани панели в разполаганията и разполагания в панелите. Класът Panel произлиза от класа Container. Панелът може да бъде създаван също като бутоните и етикетите. Панелите са полезни защото могат да се използват за комбиниране на различни типове разполагане (layout managers) в един аплет.

За да се добави панел трябва първо да се декларира Panel panelname;

След това в init() се прави

Panel panelname= new Panel(); //за създаване

add(panelname); //за да се вмъкне в аплета
за да се добавят компоненти в панела се използва тяхното име, например

panelname.add(new Label("this is in panelname"));

В пример Ex 3.4 в централната част се вмъква панел с Gridlayout.
E
x 3.4

//CombinDemo.java

//Демонстрира използването на панел за //комбиниране на разполагания


import java.awt.*;

import java.applet.*;


public class CombinDemo extends Applet {

//създаване на компонентите

Button btnNorth = new Button("North");

Button btnSouth = new Button("South");

Button btnEast = new Button("East");

Button btnWest = new Button("West");

Panel mypanel = new Panel();

public void init(){

this.setFont(new Font("Sans",0,18));

// промяна на шрифта за по-лесно четене

this.setLayout(new BorderLayout());

add(btnNorth, BorderLayout.NORTH);

add(btnSouth, BorderLayout.SOUTH);

add(btnEast, BorderLayout.EAST);

add(btnWest, BorderLayout.WEST);

mypanel.setLayout(new GridLayout(2,3));

mypanel.add(new Button("1"));

mypanel.add(new Button("2"));

mypanel.add(new Button("3"));

mypanel.add(new Button("4"));

mypanel.add(new Button("5"));

mypanel.add(new Button("6"));

//панелът е създаден

// вмъква се в аплета

add(mypanel,BorderLayout.CENTER);

} // край на init

} // край на CombinDemo
Цветни панели

В стандартния си вид панелите са невидими, но те разполагат с метода setBackground(), който наследяват от родителския клас Container. Той може да бъде използван за тяхното оцветяване.



Ex 3.5
import java.awt.*;

import java.applet.*;


public class BorderLayout2 extends Applet {

B
utton myUp = new Button("UP HERE");

Button myDown = new Button("DOWN UNDER");

Button myLeft = new Button("LEFT");

Button myRight = new Button("RIGHT");

Button myCentre = new Button("MIDDLE");

Panel myTop = new Panel();

Panel myBottom = new Panel();

Panel myLeftSide = new Panel();

Panel myRightSide = new Panel();

Panel myMiddle = new Panel();
public void init() {

setLayout(new BorderLayout());

myTop.setBackground(Color.blue);

myTop.setLayout(new FlowLayout());

myTop.add(myUp);

add("North", myTop);

// алтернатива на add(myTop,BorderLayout.NORTH);

myBottom.setBackground(Color.red);

myBottom.setLayout(new FlowLayout());

myBottom.add(myDown);

add("South", myBottom);
myLeftSide.setBackground(Color.green);

myLeftSide.setLayout(new FlowLayout());

myLeftSide.add(myLeft);

add("West", myLeftSide);


myRightSide.setBackground(Color.yellow);

myRightSide.add(myRight);

add("East", myRightSide);

myMiddle.add(myCentre);

add("Center", myMiddle);

}

}


Добавяне и разширяване на собствени класове



Ex 3.6
//MyClone

//Демонстрира клониране на съществуващ клас

//Преви копие на MyFlowLayout
import MyFlowLayout;
public class MyClone extends MyFlowLayout{
//без код!!

}
След като вече е бил създаден класа MyFlowLayout, той може да бъде добавен. Винаги може да бъде добавен собствен клас, а също така и предифинирани класове. MyFlowLayout е родителски на класа MyClone's. Не е необходимо да бъдат добавяни awt и applet пакетите и там няма никакъв код. Така че този пример на прави нищо, освен да повтаря Ex 3.1., хо може да бъде добавен допълнителен код за да му се добавят нови функции, т.е. да се разшири класа MyFlowLayout. Трябва да се помни, че класа MyClone ще наследи всичко което неговият родитески клас притежава. Когато се разширява клас новият клас започва точно като родителския, но неговите наследени методи могат да бъдат пренаписани, така че при наследника да работят по нов начин.


Пренаписване


Между Ex3.3 и Ex3.1 има много малка разлика в същинския код, само реда

this.setLayout(new GridLayout(2,3));и заглавията на шестте бутона. Вместо да бъде писан наново Ex3.3 може просто да бъде включен Ex3.1 (MyFlowLayout class) и да се пренапишат init() и myaddButtons() методите. Пренаписаният метод ще промени стария наследен от MyFlowLayout.


Алтернативна версия на Ex 3.3


//MynewEx3.3

//Демонстрира разширяване на съществуващ клас

// и пренаписва някои от методите му

import java.awt.*;

import MyFlowLayout; //добавя класа
public class MynewEx3.3 extends MyFlowLayout{
public void init(){ // пренаписва метода init()

setLayout(new GridLayout(2,3));

myaddButtons();

} // край на init


public void myaddButtons(){

// пренаписва предишния метод myaddButtons

add(new Button("1"));

add(new Button("2"));

add(new Button("3"));

add(new Button("4"));

add(new Button("5"));

add(new Button("6"));

} // край на myaddButtons
}
java.awt.* трябва да бъде добавена, тъй като ще се използва метода add() за написването на новия метод myaddButtons().

Ако по някаква причина се наложи използването в аплета на новия и стария метод едновременно, то това е възможно с вмъкването на ключовата дума super в началото на името на метода. Дори когато метода е пренаписан, тя дава възможност да се извика оригиналния метод, например super.init() казва “стартирай init() от родителския клас ”.


Прихващане на събития


Приложенията за web често изискват събитийно програмиране, където системата или потребителя използват определени събития, като натискане на бутон на мишката, и програмата е проектирана да отговаря на тези събития. В същност програмата не прави нищо, а чака действие от потребителя (като натискане на бутон) и тогава отговаря.

Java предоставя редица класове за да подпомогне прихващането на събития. Те са в java.awt.event пакета и във всеки аплет, включващ потребителска реакция, трябва да бъде добавен този пакет. Класовете в Java могат да имат само един родител, но също така могат да са свързани с редица псевдо-класове наречени interfaces, чиято цел е да “слушат” за събития. Пример за такъв интерфейс е ActionListener, чиято единствена работа се състои в т това да слуша за натискане на бутон. Когато това се случи, незабавно подава ActionEvent обекта на метод наречен actionPerformed().ActionEvent обекта носи информация за събитието което току що се е случило, като например кой бутон е бил натиснат. Метода actionPerformed()го приема като входен параметър. Какво става после с него се указва в програмата.

За да работи всичко това е небходимо:


  • Добавяне на java.awt.event пакета

  • Изпълнение на интерфейса ActionListener

  • Свързване на бутона с ActionListener

  • Написване на кода в метода actionperformed()

Ето един прост пример със само един бутон. В отговор на натискането на бутона се променя надписа на етикета.
Ex 3.7
//MyClick.java

//Демонстрира просто прихващане на събитие





import java.awt.*;

import java.applet.*;

import java.awt.event.*;


public class MyClick extends Applet implements ActionListener{
//Създава няколко обекта

Label mylbl = new Label("Don't click the button");

Button mybtn = new Button("Don't click me!");
public void init(){

//установява шрифт по подразбиране за аплета

this.setFont(new Font("Helvetica", Font.BOLD, 20));
//вмъква обектите

add(mylbl);

add(mybtn);
mylbl.setAlignment(Label.CENTER);

mylbl.setBackground(Color.cyan);

//свързва бутона с //actionListener

mybtn.addActionListener(this);

} // край на init

public void actionPerformed(ActionEvent e){

mylbl.setText("I told you not to click me!!!");

} // край на actionPerformed


} // край на class
Трябва да се отбележи как бутонът е свързан с ActionListener и това, че на трябва да бъде дадено някакво име на ActionEvent (e е най често използваното), въпреки че в този пример всъщност то не се използва.

В следващия пример се взема ActionEvent и му се добавя getActionCommand(). Така се прихваща надписа на натиснатия бутон (причина за събитието). След това той се поставя като нов надпис на етикета.



Ex 3.8

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class MyButts extends Applet implements ActionListener{



//Създаване на обекти

Label mylabel = new Label("Which button was pressed?");

Button mybtnOne = new Button("One");

Button mybtnTwo = new Button("Two");
public void init(){

//установяване на Grid Layout с една колона,

//толкова редове колкото са необходими

setLayout(new GridLayout(0,1));


//добавяне на обектите

add(mylabel);

add(mybtnOne);

add(mybtnTwo);


//установява шрифт по подразбиране за аплета

this.setFont(new Font("SansSerif", Font.BOLD, 20));


//настройка на етикета

mylabel.setAlignment(Label.CENTER);

mylabel.setBackground(Color.yellow);
//свързване на бутоните с ActionListener

mybtnOne.addActionListener(this);

mybtnTwo.addActionListener(this);

} // край на init

public void actionPerformed(ActionEvent e){

mylabel.setText(e.getActionCommand());

//промяна на надписа на етикета с този на натиснатия бутон

} // край на actionPerformed


} // край на class
Ex 3.8 може да бъде направен с използване на израза if. Ето прост пример, но с повече бутони.
Ex 3.9

import java.awt.*;

import java.applet.*;

import java.awt.event.*;


public class MyCount extends Applet implements ActionListener{

//Създаване на обекти

Panel mypanel = new Panel();

Panel mybuttns = new Panel();

Label mylabel = new Label("Counting is easier in Welsh");

Button mybtnOne = new Button("1");

Button mybtnTwo = new Button("2");

Button mybtnThree = new Button("3");

Button mybtnFour = new Button("4");

Button mybtnFive = new Button("5");

Button mybtnSix = new Button("6");

public void init(){

//установяване на Grid Layout с два реда, три колони

mybuttns.setLayout(new GridLayout(2,3));

//добавяне на обектите

m
ypanel.add(mylabel);

add(mypanel);

mybuttns.add(mybtnOne);

mybuttns.add(mybtnTwo);

mybuttns.add(mybtnThree);

mybuttns.add(mybtnFour);

mybuttns.add(mybtnFive);

mybuttns.add(mybtnSix);

add(mybuttns);

//установява шрифт по подразбиране

this.setFont(new Font("SansSerif", Font.BOLD, 24));

//настройка на етикета

mylabel.setAlignment(Label.CENTER);

mylabel.setBackground(Color.yellow);
//свързване на бутоните с ActionListener

mybtnOne.addActionListener(this);

mybtnTwo.addActionListener(this);

mybtnThree.addActionListener(this);

mybtnFour.addActionListener(this);

mybtnFive.addActionListener(this);

mybtnSix.addActionListener(this);

} // край на init


public void actionPerformed(ActionEvent e){

if(e.getActionCommand()=="1")mylabel.setText("un");

if(e.getActionCommand()=="2")mylabel.setText("dau");

if(e.getActionCommand()=="3")mylabel.setText("tri");

if(e.getActionCommand()=="4")mylabel.setText("pedwar");

if(e.getActionCommand()=="5")mylabel.setText("pump");

if(e.getActionCommand()=="6")mylabel.setText("chwech");

} // край на actionPerformed

} // край на class
Трябва да се отбележи, че за целия аплет по подразбиране е FlowLayout. Създават се два панела в аплета. Първият съдържа етикета, а вторият - разположените с GridLayout бутони.

CardLayout

Този Layout Manager бе оставен за допълнително разглеждане, тъй като е по-различен от останалите. Не е много използваем, но може да бъде алтернатива на отрупването на екрана с много прозорци. С CardLayout могат да се добавят редица от панели на едно и също място на екрана и да се използват бутони за движение между тях (само един панел е видим). Трябва да се създадат собствени бутони и да бъдат програмирани. Трябва да



  • implement ActionListener

  • свързване на бутоните с addActionListener(this)

  • програмиране на метода actionPerformed()

  • next()

  • previous()

  • first()

  • last()

  • show(cardname)

За да се създаде Cardlayout се прави CardLayout name = new CardLayout;

Ако се направи setLayout(name) ще се зададе разполагане за целия аплет, но за да са видими бутоните през цялото време е по добре да се сложат два панела, един за картите и един за бутоните за движение между картите. Това е направено в следващия прост пример. Името на CardLayout е stack и е вмъкнато в панел с име pnlCards. Картите в случая са етикети, но могат да бъдат и панели с множество компоненти в тях.
Ex3.10
//CardDemo

//Демонстрира CardLayout Manager


import java.awt.*;

import java.applet.*;

import java.awt.event.*;
public class CardDemo extends Applet implements ActionListener{



//Компоненти на контролния панел

Panel pnlControls = new Panel();

Button btnFirst = new Button("|<<");

Button btnPrev = new Button("<==");

Button btnC = new Button("C");

Button btnNext = new Button("==>");

Button btnLast = new Button(">>|");

//Картите

Panel pnlCards = new Panel();

CardLayout stack = new CardLayout();

Label lblA = new Label("A");

Label lblB = new Label("B");

Label lblC = new Label("C");

Label lblD = new Label("D");

Label lblE = new Label("E");


public void init(){

//установяване на главната страница

this.setLayout(new BorderLayout());

this.add(pnlControls, BorderLayout.SOUTH);

this.add(pnlCards, BorderLayout.CENTER);
//установяване на контролния панел

pnlControls.setFont(new Font("SansSerif", Font.BOLD, 20));

pnlControls.setLayout(new FlowLayout());

pnlControls.add(btnFirst);

pnlControls.add(btnPrev);

pnlControls.add(btnC);

pnlControls.add(btnNext);

pnlControls.add(btnLast);


//свързване с actionListeners

btnFirst.addActionListener(this);

btnPrev.addActionListener(this);

btnC.addActionListener(this);

btnNext.addActionListener(this);

btnLast.addActionListener(this);


//установяване на панела с карти

pnlCards.setLayout(stack);

pnlCards.setFont(new Font("SansSerif", Font.BOLD, 60));

pnlCards.add(lblA, "cardA");// the first parameter is what you put on

// вторият параметър е името на картата

pnlCards.add(lblB, "cardB ");

pnlCards.add(lblC, "cardC");

pnlCards.add(lblD, "cardD");

pnlCards.add(lblE, "cardE");
//центриране на етикетите

lblA.setAlignment(Label.CENTER);

lblB.setAlignment(Label.CENTER);

lblC.setAlignment(Label.CENTER);

lblD.setAlignment(Label.CENTER);

lblE.setAlignment(Label.CENTER);

} // край на init
public void actionPerformed(ActionEvent e){

String theCommand = e.getActionCommand();

if (theCommand.equals("|<<")){

stack.first(pnlCards);

} else if (theCommand.equals("<==")){

stack.previous(pnlCards);

} else if (theCommand.equals("C")){

stack.show(pnlCards, "cardC");

} else if (theCommand.equals("==>")){

stack.next(pnlCards);

} else if (theCommand.equals(">>|")){

stack.last(pnlCards);

} // край на if

//не прави нищо за сега

} // край на actionPerformed

} // край на CardDemo





Програмиране на Java 3



База данных защищена авторским правом ©obuch.info 2016
отнасят до администрацията

    Начална страница