Construire fereastră aplicaţie
Componenta List şi componenta JScrollPane
Interfeţele grafice (Graphical User Interfaces) reprezintă
ferestre ce conţin elemente grafice ce permit interacţiunea dintre
aplicaţie şi utilizator. Limbajul java pune la dispoziţia
programatorului două biblioteci pentru realizarea interfeţelor grafice:
java.awt şi java.swing.
Diagrama din figura 1 prezintă cele mai importante clase din cadrul pachetelor java.awt
şi java.swing.
Figura 1. Clase swing
şi awt.
Pentru a construi o fereastră grafică principală în java
trebuie extinsă clasa JFrame. Programul
următor exemplifică o aplicaţie ce construieşte o
fereastră grafică şi o afişează pe ecran.
import javax.swing.JFrame;
public class SimpleApp extends JFrame{
SimpleApp(){
setTitle("Titlul ferestrei");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,500);
setVisible(true);
}
public static void
main(String[] args) {
SimpleApp
a = new SimpleApp();
}
}
Aplicaţiile următoare vor exemplifica modul în care în cadrul
unei ferestre grafice pot fi adăugate componente grafice prin intermediul
cărora utilizatorul poate interacţiona cu
aplicaţia (butoane, căsuţe de dialogm
meniuri, etc.).
Butoanele sunt elemente de control care, prin apăsare, pot genera o
acţiune. Despre modul cum se asociază la un buton o acţiune se
va vorbi în capitolul „Captarea evenimentelor”.
Pentru a construi un buton se foloseşte clasa JButton.
Căsuţele de text sunt zone pe unu sau mai multe rânduri în
care utilizatorul poate adăuga un text.
Pentru a construi o căsuţă de text se poate folosi clasa JTextField (ce pemrite construirea unei căsuţe de text cu un
singur rând) sau clasa JTextArea
(ce permite construirea unei căsuţe de text pe mai multe rânduri.
Pentru a construi un text static ce nu poate fi modificat se
foloseşte clasa JLabel.
import java.awt.FlowLayout;
import javax.swing.*;
import java.util.*;
public class ButtonAndTextField extends JFrame{
HashMap
accounts = new HashMap();
JLabel
user,pwd;
JTextField
tUser,tPwd;
JButton
bLoghin;
ButtonAndTextField(){
accounts.put("user1", "pwd1");
accounts.put("user2", "pwd2");
accounts.put("user3", "pwd3");
setTitle("Test login");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
setSize(200,250);
setVisible(true);
}
public void init(){
this.setLayout(null);
int width=80;int height =
20;
user = new JLabel("User
");
user.setBounds(10, 50, width, height);
pwd = new JLabel("Pasword ");
pwd.setBounds(10, 100,width, height);
tUser = new JTextField();
tUser.setBounds(70,50,width, height);
tPwd = new JTextField();
tPwd.setBounds(70,100,width, height);
bLoghin = new JButton("Loghin");
bLoghin.setBounds(10,150,width, height);
add(user);add(pwd);add(tUser);add(tPwd);add(bLoghin);
}
public static void
main(String[] args) {
new ButtonAndTextField();
}
}
Componentele pot fi aşezate în cadrul unei ferestre folosind clase
speciale responsabile cu poziţionarea componentelor pe ecran numite clase
de tip layout manager sau relativ la colţul din
stânga sus al ferestrei. Modul de folosire a claselor de tip layout manager este acoperit în cadrul
capitolului „Capturarea evenimentelor”.
În programul anterior elementele grafice (butoane, căsuţe de
text, etichete) sunt poziţionate pe ecran folosind metoda setBounds(x,y,width,hight). Pentru ca acest mod de poziţionare a
componentelor să poată fi realizat trebuie ca componenta layout manager să fie dezactivată
folosind metoda setLayout(null)
.
Comunicarea dintre utilizator şi aplicaţie prin intermediul
interfeţei grafice se realizează printr-un mecanism bazat pe
evenimente. Orice acţiune a utilizatorului în cadrul interfeţei
grafice (apăsarea unui buton, mişcarea mouse-ului,
selectarea unui buton de selecţie) determină generarea unui eveniment
de către componentă. Evenimentele generate de componente ca urmare a
acţiunii utilizatorului pot fi
captate de către aplicaţie şi gestionate corespunzător.
Aşadar, pentru a scrie cod care sa se execute în momentul în care utilizatorul interacţionează
cu o componenta grafica trebuiesc realizaţi următorii paşi:
Evenimentele sunt modelate şi ele prin intermediul claselor. Pentru
fiecare tip de eveniment există o clasă care descrie acest eveniment.
Clasele ce descriu evenimente sunt definite în cadrul pachetului java.awt.event.
Event Listener |
Listener Methods |
Registered on |
ActionListener |
actionPerformed() |
AbstractButton, Button, ButtonModel, ComboBoxEditor, JComboBox, JFileChooser, JTextField, List, MenuItem, TextField, Timer |
AdjustmentListener |
adjustmentValue- |
Adjustable, |
|
Changed() |
JScrollBar, Scrollbar |
ComponentListener |
componentHidden(), componentMoved(), componentResized(), componentShown() |
Component |
ContainerListener |
componentAdded(), componentRemoved() |
Container |
FocusListener |
focusGained(), focusLost() |
Component |
ItemListener |
itemStateChanged() |
AbstractButton, ButtonModel, Checkbox, CheckboxMenuItem, Choice, ItemSelectable, JComboBox, List |
KeyListener |
keyPressed(), keyReleased(), keyTyped() |
Component |
MouseListener |
mouseClicked(), mouseEntered(), mouseExited(), mousePressed(), mouseReleased() |
Component |
MouseMotionListener |
mouseDragged(), mouseMoved() |
Component |
TextListener |
textValueChanged() |
TextComponent |
WindowListener |
windowActivated(), windowClosed(), windowClosing(), windowDeactivated(), windowDeiconified(), windowIconified(), windowOpened() |
Window |
În continuare este prezentată aplicaţia din capitolul anterior
modificată astfel încât să capteze şi să trateze
evenimentele generate de componenta de tip buton în momentul apăsării
acestuia.
package isp.grafic.fereastra;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.*;
public class ButtonAndTextField2 extends JFrame{
HashMap
accounts = new HashMap();
JLabel
user,pwd;
JTextField
tUser,tPwd;
JTextArea
tArea;
JButton
bLoghin;
ButtonAndTextField2(){
accounts.put("user1", "pwd1");
accounts.put("user2", "pwd2");
accounts.put("user3", "pwd3");
setTitle("Test login");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
setSize(200,300);
setVisible(true);
}
public void init(){
this.setLayout(null);
int width=80;int height =
20;
user = new JLabel("User
");
user.setBounds(10, 50, width, height);
pwd = new JLabel("Pasword ");
pwd.setBounds(10, 100,width, height);
tUser = new JTextField();
tUser.setBounds(70,50,width, height);
tPwd = new JTextField();
tPwd.setBounds(70,100,width, height);
bLoghin = new JButton("Loghin");
bLoghin.setBounds(10,150,width, height);
bLoghin.addActionListener(new TratareButonLoghin());
tArea = new JTextArea();
tArea.setBounds(10,180,150,80);
add(user);add(pwd);add(tUser);add(tPwd);add(bLoghin);
add(tArea);
}
public static void
main(String[] args) {
new ButtonAndTextField2();
}
class TratareButonLoghin
implements ActionListener{
public void actionPerformed(ActionEvent e) {
String usr = ButtonAndTextField2.this.tUser.getText();
String pwd = ButtonAndTextField2.this.tPwd.getText();
if(ButtonAndTextField2.this.accounts.containsKey(usr)){
String correctPwd = (String)ButtonAndTextField2.this.accounts.get(usr);
if(correctPwd.equals(pwd)){
//user and password correct
ButtonAndTextField2.this.tArea.append("Valid loghin\n");
}
else{
//invalid password
ButtonAndTextField2.this.tArea.append("Invalid password\n");
}
}else{
//user not found
ButtonAndTextField2.this.tArea.append("User not found\n");
}
}
}
}
Spre deosebire de celelalte obiecte grafice, care deriva din clasa Component, componentele unui meniu reprezintă
instanţe ale unor clase derivate din superclasa
abstracta MenuComponent.
Ierarhia de clase folosită în lucrul cu meniuri este
prezentată mai jos.
Figura 2. Ierarhia de clase pentru lucrul cu meniuri.
Aplicaţia următoare exemplifică modul în care meniurile
pot fi integrate în cadrul unei aplicaţii.
package isp.grafic.menu;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class Editor extends JFrame
{
MenuBar
mb;
Menu f;
Menu t;
MenuItem
s,o,e;
JTextArea
ta;
Editor()
{
mb = new MenuBar();
f = new Menu("File");
s = new MenuItem("Save");
o = new MenuItem("Open");
e = new MenuItem("Exit");
s.addActionListener(new A());
o.addActionListener(new A());
e.addActionListener(new A());
mb.add(f);
f.add(s);
f.add(o);
f.add(e);
setMenuBar(mb);
ta = new JTextArea();
add(ta);
setSize(500,400);
setVisible(true);
}
void save(String f)
{
try
{
PrintWriter
pw = new PrintWriter(
new FileWriter(new File(f)));
pw.println(ta.getText());
pw.close();
}catch(Exception e)
{
}
}
void open(String f)
{
try
{
ta.setText("");
BufferedReader
bf =
new BufferedReader(
new FileReader(new File(f)));
String l = "";
l = bf.readLine();
while (l!=null)
{
ta.append(l+"\n");
l = bf.readLine();
}
}catch(Exception e){}
}
class A implements ActionListener
{
public void actionPerformed(ActionEvent
e)
{
String t = ((MenuItem)e.getSource()).getLabel();
if(t.equals("Save")){
FileDialog d = new FileDialog(Editor.this,"Incarca f",FileDialog.SAVE);
d.setVisible(true);
save(d.getDirectory()+d.getFile());
}
if (t.equals("Open"))
{
FileDialog d = new FileDialog(Editor.this,"Incarca f",FileDialog.LOAD);
d.setVisible(true);
open(d.getDirectory()+d.getFile());
}
}
}
public static void
main(String args[])
{
new Editor();
}
}
Un checkbox reprezintă un obiect ce poate avea două
stări: selectat sau deselctat. Utilizatorul
poate acţiona acest comutator si selecta una dintre cele două
stări.
package isp.grafic.componente;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class CheckboxTest extends JFrame implements ItemListener {
private Label label1, label2;
private Checkbox cbx1, cbx2, cbx3;
public CheckboxTest(String
titlu) {
super(titlu);
initializare();
setVisible(true);
}
public void initializare() {
setLayout(new GridLayout(5,
1));
label1 = new Label("Componente
:", Label.CENTER);
label1.setBackground(Color.orange);
label2 = new Label("");
label2.setBackground(Color.lightGray);
cbx1 = new Checkbox("componenta
1");
cbx2 = new Checkbox("componenta
2");
cbx3 = new Checkbox("componenta
3");
add(label1);
add(label2);
add(cbx1);
add(cbx2);
add(cbx3);
pack();
setSize(200,
200);
cbx1.addItemListener(this);
cbx2.addItemListener(this);
cbx3.addItemListener(this);
}
//metoda interfetei ItemListener
public void itemStateChanged(ItemEvent
e) {
StringBuffer
ingrediente = new StringBuffer();
if (cbx1.getState() == true)
ingrediente.append(" componenta 1");
if (cbx2.getState() == true)
ingrediente.append(" componenta 2 ");
if (cbx3.getState() == true)
ingrediente.append(" componenta 3 ");
label2.setText(ingrediente.toString());
}
public static void
main(String[] args) {
new CheckboxTest("titlu");
}
}
Componenta Choice defineşte o listă de opţiuni dintre
care utilizatorul poate selecta una. Doar opţiunea selectată este
vizibilă.
package isp.grafic.componente;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ChoiceTest extends JFrame implements ItemListener {
private Label label;
private Choice culori;
public ChoiceTest(String
titlu) {
super(titlu);
initializare();
setVisible(true);
}
public void initializare() {
setLayout(new GridLayout(4,
1));
label = new Label("Alegeti culoarea");
label.setBackground(Color.red);
culori = new
Choice();
culori.add("Rosu");
culori.add("Verde");
culori.add("Albastru");
culori.select("Rosu");
add(label);
add(culori);
pack();
setSize(200,
100);
culori.addItemListener(this);
}
//metoda interfetei ItemListener
public void itemStateChanged(ItemEvent
e) {
switch (culori.getSelectedIndex()) {
case 0:
label.setBackground(Color.red);
break;
case 1:
label.setBackground(Color.green);
break;
case 2:
label.setBackground(Color.blue);
}
}
public static void
main(String[] args) {
new ChoiceTest("test");
}
}
Componenta List conţine o listă de opţiuni dintre care
utilizatorul poate selecta una sau mai multe. Toate opţiunile listei sunt
vizibile.
Componenta ScrollPane
permite ataşarea unor bare de defilare orizontale şi / sau verticale
componentelor grafice care nu au implementată funcţionalitatea de
defilare automată.
package isp.grafic.componente;
package isp.grafic.componente;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.*;
import javax.swing.event.*;
public class ListTest extends JFrame implements ListSelectionListener{
//JFrame frame = new JFrame("Selecting
JList");
String labels[] = { "Chardonnay", "Sauvignon", "Riesling", "Cabernet",
"Zinfandel", "Merlot", "Pinot Noir", "Sauvignon Blanc",
"Syrah", "Gewurztraminer" };
JList
jlist = new JList(labels);
final JTextArea textArea = new JTextArea();
ListTest(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
JScrollPane
scrollPane1 = new JScrollPane(jlist);
add(scrollPane1, BorderLayout.WEST);
textArea.setEditable(false);
JScrollPane
scrollPane2 = new JScrollPane(textArea);
add(scrollPane2, BorderLayout.CENTER);
jlist.addListSelectionListener(this);
jlist.addMouseListener(new MyMouseListener());
setSize(350, 200);
setVisible(true);
}
public void valueChanged(ListSelectionEvent
listSelectionEvent) {
StringWriter
sw = new StringWriter();
PrintWriter
pw = new PrintWriter(sw);
pw.print("First index: " + listSelectionEvent.getFirstIndex());
pw.print(", Last index: " + listSelectionEvent.getLastIndex());
boolean adjust = listSelectionEvent.getValueIsAdjusting();
pw.println(", Adjusting? " + adjust);
if (!adjust) {
JList
list = (JList) listSelectionEvent.getSource();
int selections[] = list.getSelectedIndices();
Object selectionValues[] = list.getSelectedValues();
for (int i = 0, n = selections.length; i < n; i++) {
if (i == 0) {
pw.print(" Selections: ");
}
pw
.print(selections[i] + "/" + selectionValues[i]
+ " ");
}
pw.println();
}
textArea.append(sw.toString());
}
class MyMouseListener
extends MouseAdapter{
public void mouseClicked(MouseEvent
mouseEvent) {
JList theList = (JList) mouseEvent.getSource();
if (mouseEvent.getClickCount() == 2) {
int index = theList.locationToIndex(mouseEvent.getPoint());
if (index >= 0) {
Object o = theList.getModel().getElementAt(index);
textArea.append("Double-clicked on: " + o.toString());
textArea.append(System.getProperty("line.separator"));
}
}
}
}
public static void
main(String args[]) {
new ListTest();
}
}