Applicazioni grafiche
Finestre Frame
ƒ
ƒ
I programmi grafici scritti finora erano applet
Possiamo anche scrivere applicazioni grafiche
ƒ
ƒ
Costituite da varie finestre frame
Creiamo il frame all’interno del metodo main dell’applicazione
public class FrameTest
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
…
frame.show();
}
}
2
Frame
ƒ Un frame è una finestra indipendente dotata di
ƒ barra del titolo
ƒ pulsanti di ridimensionamento e chiusura
ƒ Per creare un frame si usa la classe
JFrame
JFrame frame = new JFrame();
ƒ Per creare il titolo si usa il metodo setTitle
frame.setTitle(“Titolo”);
3
Frame
ƒ Il metodo pack() assegna le dimensioni al frame
in modo che possa contenere tutti i suoi
componenti
frame.pack();
ƒ Il metodo show() mostra la finestra sullo schermo
(inizialmente è invisibile)
frame.show();
4
Finestre Frame
ƒ
Impostiamo l’operazione di chiusura predefinita:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ƒ
Aggiungiamo delle etichette (immagini, scritte) al frame
JLabel iconLabel = new JLabel(new ImageIcon("world.gif"));
JLabel textLabel = new JLabel("Hello, World!");
ƒ
Aggiungiamo i componenti ad un pannello e assegnamo
il pannello ai contenuti della finestra
JPanel panel = new JPanel();
panel.add(iconLabel);
panel.add(textLabel)
frame.setContentPane(panel);
5
Esempio
Scriviamo un programma che visualizza un
frame con un’immagine e un’etichetta di testo
6
File FrameTest.java
import
import
import
import
javax.swing.ImageIcon;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
/**
Questo programma visualizza un frame con un’immagine
e un’etichetta di testo
*/
public class FrameTest
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
7
JLabel iconLabel = new JLabel(new ImageIcon("world.gif"));
JLabel textLabel = new JLabel("Hello, World!");
JPanel panel = new JPanel();
panel.add(iconLabel);
panel.add(textLabel);
frame.setContentPane(panel);
frame.pack();
frame.show();
}
}
8
Esempio
Scriviamo un programma che
ƒ Mostra una finestra contenente un campo di testo per
l’inserimento del tasso di interesse
ƒ Mostra una finestra che visualizza la crescita di un
investimento
9
File TextAreaTest.java
import
import
import
import
import
import
import
import
import
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
javax.swing.JScrollPane;
javax.swing.JTextArea;
javax.swing.JTextField;
/**
Questo programma mostra un frame con un’area di
testo che visualizza la crescita di un investimento e
un frame con un’area di testo per l’inserimento del
tasso di interesse
*/
10
public class TextAreaTest
{
public static void main(String[] args)
{
// l’applicazione aggiunge l’interesse al conto
final BankAccount account = new
BankAccount(INITIAL_BALANCE);
// l’area di testo per visualizzare la crescita
dell’investimento
final JTextArea textArea = new JTextArea(10, 30);
textArea.setEditable(false);
JScrollPane scrollPane = new
JScrollPane(textArea);
11
// costruisce il frame che visualizza l’area di testo
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(scrollPane);
frame.pack();
frame.show();
// l’etichetta e il campo di testo per inserire il
tasso di interesse
JLabel rateLabel = new JLabel("Interest Rate: ");
final JTextField rateField = new JTextField(10);
rateField.setText("" + DEFAULT_RATE);
// il pulsante per innescare il calcolo
JButton calculateButton = new JButton("Add Interest");
12
class CalculateListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
double rate = Double.parseDouble(
rateField.getText());
double interest = account.getBalance()
* rate / 100;
account.deposit(interest);
textArea.append(account.getBalance() + "\n");
}
}
ActionListener listener = new CalculateListener();
calculateButton.addActionListener(listener);
13
// il pannello che contiene i componenti
JPanel controlPanel = new JPanel();
controlPanel.add(rateLabel);
controlPanel.add(rateField);
controlPanel.add(calculateButton);
// il frame che contiene il pannello
JFrame controlFrame = new JFrame();
controlFrame.setContentPane(controlPanel);
controlFrame.pack();
controlFrame.show();
}
private static final double DEFAULT_RATE = 10;
private static final double INITIAL_BALANCE = 1000;
}
14
Aggiungere la grafica ad
un’applicazione
„
In un applet, per aggiungere la grafica estendiamo la
classe Applet e sovrascriviamo il metodo paint
„
Questo approccio non funziona per le finestre frame,
sulla cui superficie non possiamo disegnare
direttamente
„
Per mostrare grafica, occorre disegnarla in un JPanel,
sovrascrivendone il metodo paintComponent
15
Aggiungere la grafica ad
un’applicazione
„
Importante: dobbiamo invocare il metodo paintComponent
della superclasse (per cancellare I vecchi contenuti del
pannello)
public class MyPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//istruzioni di disegno. . .
}
}
16
Aggiungere la grafica ad
un’applicazione
„
„
La dimensione predefinita del pannello è 0 x 0 pixel
Possiamo impostare le dimensioni nel costruttore:
public class MyPanel extends JPanel
{
public MyPanel()
{
setPreferredSize(
new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
. . .
}
private static final int PANEL_WIDTH = 300;
private static final int PANEL_HEIGHT = 300;
}
17
Trasformare un applet in
un’applicazione grafica
„
RectangleApplet disegnava un rettangolo nel punto di
pressione del tasto del mouse
„
Trasformiamolo in un’applicazione grafica:
‰
‰
„
Creiamo una classe RectanglePanel per creare un pannello e
impostiamone le dimensioni nel costruttore
Installiamo un ricevitore di eventi del mouse
Il risultato sarà identico all’applet, ma non avrà bisogno
di un file HTML nè di un visualizzatore di applet
18
Applicazione grafica
19
Applet Æ applicazione grafica
public class RectanglePanel extends JPanel
{
public RectanglePanel()
{
setPreferredSize(new Dimension(PANEL_WIDTH,
PANEL_HEIGHT));
// aggiungi un ricevitore per gli eventi del mouse
….
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
…
}
}
20
Trasformare un applet in
un’applicazione grafica
„
„
La classe di un pannello che traccia un disegno
dovrebbe memorizzare tutti i dati necessari per
ridisegnarsi
Nel nostro caso, si tratta di un rettangolo
21
Applet Æ applicazione
public class RectanglePanel extends JPanel
{
public RectanglePanel()
{
// il rettangolo disegnato dal metodo paint
box = new Rectangle(…);
….
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.draw(box);
}
private Rectangle box;
}
22
File RectanglePanel.java
import
import
Import
import
import
import
import
import
java.awt.event.MouseEvent;
java.awt.event.MouseListener;
java.awt.event.MouseAdapter;
java.awt.Dimension;
java.awt.Graphics;
java.awt.Graphics2D;
java.awt.Rectangle;
javax.swing.JPanel;
/**
Un pannello che visualizza un rettangolo che può
essere spostato dall’utente premendo il pulsante del
mouse.
*/
23
public class RectanglePanel extends JPanel
{
/**
Costruisce il pannello con il rettangolo in
posizione predefinita.
*/
public RectanglePanel()
{
setPreferredSize(new Dimension(PANEL_WIDTH,
PANEL_HEIGHT));
// il rettangolo disegnato dal metodo paint
box = new Rectangle(BOX_X, BOX_Y,
BOX_WIDTH, BOX_HEIGHT);
24
// aggiungi il ricevitore di eventi del mouse
class MousePressListener extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
int x = event.getX();
int y = event.getY();
box.setLocation(x, y);
repaint();
}
}
MouseListener listener = new MousePressListener();
addMouseListener(listener);
}
25
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.draw(box);
}
private Rectangle box;
private static final int BOX_X = 100;
private static final int BOX_Y = 100;
private static final int BOX_WIDTH = 20;
private static final int BOX_HEIGHT = 30;
private static final int PANEL_WIDTH = 300;
private static final int PANEL_HEIGHT = 300;
}
26
File RectangleTest.java
import
import
import
import
import
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
javax.swing.JTextField;
/**
Questo programma visualizza un frame contenente un
RectanglePanel.
*/
public class RectangleTest
{
public static void main(String[] args)
{
RectanglePanel rectPanel = new RectanglePanel();
27
JFrame appFrame = new JFrame();
appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
appFrame.setContentPane(rectPanel);
appFrame.pack();
appFrame.show();
}
}
28
Classi usate nell’applicazione
RectangleTest
29
Errori comuni
„
Bisogna sovrascrivere il metodo
paintComponent del pannello e non il metodo
paint!
‰
„
Altrimenti il contenuto del pannello sarà imprevedibile
Bisogna invocare il metodo paintComponent
della superclasse per disegnare nel pannello
‰
Altrimenti lo sfondo del pannello non sarà cancellato
30
Uso dell’ereditarietà per
personalizzare i frame
„
„
Per creare un frame complesso conviene usare
l’ereditarietà, definendo una sottoclasse di
JFrame
Aggiungiamo i componenti dell’interfaccia utente
nel costruttore
‰
‰
Se sono troppi, è preferibile usare un metodo
separato
I componenti che devono essere condivisi tra questi
metodi vanno trasformati in variabili istanza della
classe
31
Uso dell’ereditarietà per
personalizzare i frame
„
Utilizziamo tre classi:
‰
‰
‰
RectangleFrame, per creare il
frame contenente il pannello
per i componenti
dell’interfaccia utente
RectanglePanel, per creare il
pannello che disegna il
rettangolo
RectangleTest, per
visualizzare il frame
32
Uso dell’ereditarietà per
personalizzare i frame
33
Uso dell’ereditarietà per
personalizzare i frame
public class RectangleFrame extends JFrame
{
public RectangleFrame()
{
//il pannello che disegna il rettangolo
rectPanel = new RectanglePanel();
getContentPane().add(rectPanel,
BorderLayout.CENTER);
createControlPanel();
pack();
}
34
private void createControlPanel()
{
//campi di testo per le coordinate x e y
final JTextField xField = new JTextField(5);
final JTextField yField = new JTextField(5);
class MoveButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
int x = Integer.parseInt(xField.getText());
int y = Integer.parseInt(yField.getText());
rectPanel.setLocation(x, y);
}
}
35
//crea un pulsante e associa un ricevitore
JButton moveButton = new JButton("Move");
ActionListener listener = new MoveButtonListener();
moveButton.addActionListener(listener);
// il pannello per i componenti
JPanel controlPanel = new JPanel();
//aggiunta dei componenti al pannello
…
getContentPane().add(controlPanel,
BorderLayout.SOUTH);
}
private RectanglePanel rectPanel;
}
36
Visualizzare il frame
„
Creiamo una classe di test separata
public class RectangleTest
{
public static void main(String[] args)
{
JFrame appFrame = new RectangleFrame();
appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
appFrame.show();
}
}
37
Problema
„
Il ricevitore di eventi del pulsante Move non ha accesso diretto al
rettangolo che si trova nell’oggetto di tipo RectanglePanel…
„
Bisogna aggiungere alla classe RectanglePanel un metodo che
consenta ad altri di impostare la posizione del rettangolo
class RectanglePanel extends JPanel
{
. . .
public void setLocation(int x, int y)
{
box.setLocation(x, y);
repaint();
}
}
38
File RectangleTest.java
import javax.swing.JFrame;
/**
Questo programma collauda la classe RectangleFrame
public class RectangleTest
{
public static void main(String[] args)
{
JFrame appFrame = new RectangleFrame();
appFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
appFrame.show();
}
}
39
File RectangleFrame.java
import
import
import
import
import
import
import
import
java.awt.BorderLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
javax.swing.JTextField;
/**
Questo frame contiene un pannello che mostra un
rettangolo e un pannello di campi di testo per
specificare la posizione del rettangolo
*/
40
public class RectangleFrame extends JFrame
{
/**
Costruisce il frame.
*/
public RectangleFrame()
{
// il pannello che disegna il rettangolo
rectPanel = new RectanglePanel();
// aggiungi il pannello al pannello dei contenuti
getContentPane().add(rectPanel, BorderLayout.CENTER);
createControlPanel();
pack();
}
41
/**
Crea il pannello di controllo con i campi di testo
nella parte bassa del frame.
*/
private void createControlPanel()
{
// i campi di testo per x e y
final JTextField xField = new JTextField(5);
final JTextField yField = new JTextField(5);;
// il bottone per muovere il rettangolo
JButton moveButton = new JButton("Move");
42
class MoveButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
int x = Integer.parseInt(xField.getText());
int y = Integer.parseInt(yField.getText());
rectPanel.setLocation(x, y);
}
}
ActionListener listener = new MoveButtonListener();
moveButton.addActionListener(listener);
// le etichette per i campi di testo
JLabel xLabel = new JLabel("x = ");
JLabel yLabel = new JLabel("y = ");
43
// il pannello per le componenti
JPanel controlPanel = new JPanel();
controlPanel.add(xLabel);
controlPanel.add(xField);
controlPanel.add(yLabel);
controlPanel.add(yField);
controlPanel.add(moveButton);
getContentPane().add(controlPanel,
BorderLayout.SOUTH);
}
private RectanglePanel rectPanel;
}
44
File RectanglePanel.java
import
import
import
import
import
java.awt.Dimension;
java.awt.Graphics;
java.awt.Graphics2D;
java.awt.Rectangle;
javax.swing.JPanel;
/**
Questo pannello visualizza un rettangolo.
*/
public class RectanglePanel extends JPanel
{
/**
Costruisce un pannello con un rettangolo in posizione
predefinita
*/
45
public RectanglePanel()
{
setPreferredSize(new Dimension(PANEL_WIDTH,
PANEL_HEIGHT));
// the rectangle that the paint method draws
box = new Rectangle(BOX_X, BOX_Y,
BOX_WIDTH, BOX_HEIGHT);
}
/**
Imposta la posizione del rettangolo e ridisegna il
pannello.
@param x la coord x dell’angolo sup. sx
@param y la coord y dell’angolo sup. sx
*/
46
public void setLocation(int x, int y)
{
box.setLocation(x, y);
repaint();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.draw(box);
}
47
private Rectangle
private static
private static
private static
private static
box;
final
final
final
final
int
int
int
int
BOX_X = 100;
BOX_Y = 100;
BOX_WIDTH = 20;
BOX_HEIGHT = 30;
private static final int PANEL_WIDTH = 300;
private static final int PANEL_HEIGHT = 300;
}
48
49
Le classi usate nell’applicazione
RectangleFrame
50
Convertire un frame in un applet
„
Il pacchetto javax.swing ha una classe JApplet
simile a JFrame
‰
„
Un oggetto di tipo JApplet ha anche un pannello dei contenuti
con gestore di layout
Per convertire un frame in un applet:
‰
‰
‰
‰
Eliminare la classe che contiene il metodo main
Ereditare da JApplet invece che da JFrame
Eliminare l’invocazione a setSize e impostare la dimensione
della finestra nella pagina HTML
Eliminare l’invocazione a setTitle e inserire il titolo nella pagina
HTML
51
Un frame complesso per gestire le
scelte
52
File ChoiceFrame.java
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.BorderLayout;
java.awt.Container;
java.awt.Font;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.WindowAdapter;
java.awt.event.WindowEvent;
javax.swing.ButtonGroup;
javax.swing.JButton;
javax.swing.JCheckBox;
javax.swing.JComboBox;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
53
import javax.swing.JRadioButton;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
/**
Questo frame contiene un campo di testo e un pannello
di controllo per cambiare il font del testo
*/
public class ChoiceFrame extends JFrame
{
// Costruisce il frame.
public ChoiceFrame()
{
// costruisce il testo dimostrativo
sampleField = new JLabel("Big Java");
getContentPane().add(sampleField,
BorderLayout.CENTER);
54
// ascoltatore condiviso tra tutti i componenti
class ChoiceListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
setSampleFont();
}
}
listener = new ChoiceListener();
createControlPanel();
setSampleFont();
pack();
}
55
//Crea il pannello di controllo
public void createControlPanel()
{
JPanel facenamePanel = createComboBox();
JPanel sizeGroupPanel = createCheckBoxes();
JPanel styleGroupPanel = createRadioButtons();
// allinea i pannelli
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new GridLayout(3, 1));
controlPanel.add(facenamePanel);
controlPanel.add(sizeGroupPanel);
controlPanel.add(styleGroupPanel);
// aggiunge i pannelli al pannello dei contenuti
getContentPane().add(controlPanel, BorderLayout.SOUTH);
}
56
/**
Crea la casella combinata per la scelta dello
stile del font.
@return il pannello che contiene la casella
combinata
*/
public JPanel createComboBox()
{
facenameCombo = new JComboBox();
facenameCombo.addItem("Serif");
facenameCombo.addItem("SansSerif");
facenameCombo.addItem("Monospaced");
facenameCombo.setEditable(true);
facenameCombo.addActionListener(listener);
JPanel panel = new JPanel();
panel.add(facenameCombo);
return panel;
}
57
/**
Crea le caselle di controllo
@return il pannello contenente le caselle
*/
public JPanel createCheckBoxes()
{
italicCheckBox = new JCheckBox("Italic");
italicCheckBox.addActionListener(listener);
boldCheckBox = new JCheckBox("Bold");
boldCheckBox.addActionListener(listener);
JPanel panel = new JPanel();
panel.add(italicCheckBox);
panel.add(boldCheckBox);
panel.setBorder
(new TitledBorder(new EtchedBorder(), "Style"));
return panel;
}
58
/**
Crea i bottoni radio
@return il pannello contenentei bottoni radio
*/
public JPanel createRadioButtons()
{
smallButton = new JRadioButton("Small");
smallButton.addActionListener(listener);
mediumButton = new JRadioButton("Medium");
mediumButton.addActionListener(listener);
largeButton = new JRadioButton("Large");
largeButton.addActionListener(listener);
largeButton.setSelected(true);
// aggiunge i bottoni radio al gruppo di pulsanti
ButtonGroup group = new ButtonGroup();
group.add(smallButton);
group.add(mediumButton);
group.add(largeButton);
59
JPanel panel = new JPanel();
panel.add(smallButton);
panel.add(mediumButton);
panel.add(largeButton);
panel.setBorder
(new TitledBorder(new EtchedBorder(), "Size"));
return panel;
}
// Acquisisce le scelte dell’utente.
public void setSampleFont()
{ // acquisisce il nome del font
String facename
= (String)facenameCombo.getSelectedItem();
// acquisisce lo stile del font
int style = 0;
60
if (italicCheckBox.isSelected())
style = style + Font.ITALIC;
if (boldCheckBox.isSelected())
style = style + Font.BOLD;
// acquisisce la dimensione del font
int size = 0;
final int SMALL_SIZE = 24;
final int MEDIUM_SIZE = 36;
final int LARGE_SIZE = 48;
if (smallButton.isSelected())
size = SMALL_SIZE;
else if (mediumButton.isSelected())
size = MEDIUM_SIZE;
else if (largeButton.isSelected())
size = LARGE_SIZE;
61
// imposta il font
sampleField.setFont(new Font(facename, style, size));
sampleField.repaint();
}
private
private
private
private
private
private
private
private
JLabel sampleField;
JCheckBox italicCheckBox;
JCheckBox boldCheckBox;
JRadioButton smallButton;
JRadioButton mediumButton;
JRadioButton largeButton;
JComboBox facenameCombo;
ActionListener listener;
}
62
File ChoiceTest.java
import javax.swing.JFrame;
/**
Testa la classe ChoiceFrame.
*/
public class ChoiceTest
{
public static void main(String[] args)
{
JFrame frame = new ChoiceFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
63
Classi nel programma ChoiceTest
64
Barra dei menu
ƒ Una barra dei menu è costituita da un gruppo di
menu lungo il margine superiore di una finestra
65
Barra dei menu
ƒ Per creare una barra dei menu si usa la classe
JMenuBar
JMenuBar menuBar = new JMenuBar();
ƒ La barra dei menu deve essere associata a un
oggetto
di
tipo
Frame
con
il
metodo
setJmenuBar()
setJMenuBar(menuBar);
66
Menu
ƒ Per creare un menu si usa la classe
JMenu
JMenu fileMenu = new JMenu(“File”);
ƒ I menu vengono aggiunti alla barra dei menu
mediante il metodo add()
menuBar.add(fileMenu);
67
Menu
ƒ All’interno dei menu si aggiungono le voci di menu
ƒ Per creare una voce di menu si usa la classe
JMenuItem
JMenuItem fileNewMenuItem = new
JMenuItem(“New”);
filemenu.add(fileNewMenuItem);
68
Menu
ƒ Quando una voce di menu viene selezionata, invia un
evento di azione
ƒ Per riceverlo, è necessario installare un ricevitore di
azioni (classe che implementa l’interfaccia ActionListener)
class MenuItemListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{ … }
}
ActionListener listener = new menuItemListener();
fileNewMenuItem.addActionListener(listener);
69
File MenuFrame.java
import
import
import
import
import
import
import
import
java.awt.BorderLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.util.Random;
javax.swing.JFrame;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
/**
Questo frame ha un menu con comandi per impostare
la posizione di un rettangolo.
*/
70
class MenuFrame extends JFrame
{
// Costruisce il frame
public MenuFrame()
{
generator = new Random();
// aggiunge al pannello dei contenuti un pannello
per disegnare
panel = new RectanglePanel();
getContentPane().add(panel, BorderLayout.CENTER);
pack();
71
// costruisce il menu
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
menuBar.add(createFileMenu());
menuBar.add(createEditMenu());
}
/**
Crea il menu File.
@return il menu
*/
public JMenu createFileMenu()
{
JMenu menu = new JMenu("File");
menu.add(createFileNewItem());
menu.add(createFileExitItem());
return menu;
}
72
/**
Crea il menu Edit.
@return il menu
*/
public JMenu createEditMenu()
{
JMenu menu = new JMenu("Edit");
menu.add(createMoveMenu());
menu.add(createEditRandomizeItem());
return menu;
}
73
/**
Crea il sottomenu Move.
@return il menu
*/
public JMenu createMoveMenu()
{
JMenu menu = new JMenu("Move");
menu.add(createMoveItem("Up", 0, -1));
menu.add(createMoveItem("Down", 0, 1));
menu.add(createMoveItem("Left", -1, 0));
menu.add(createMoveItem("Right", 1, 0));
return menu;
}
74
/**
Crea la voce di menu File->New menu e imposta il
ricevitore.
@return la voce di menu
*/
public JMenuItem createFileNewItem()
{
JMenuItem item = new JMenuItem("New");
class MenuItemListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
panel.reset();
}
}
ActionListener listener = new MenuItemListener();
item.addActionListener(listener);
return item;
}
75
/**
Crea la voce di menu File->Exit e imposta il
ricevitore.
@return la voce di menu
*/
public JMenuItem createFileExitItem()
{
JMenuItem item = new JMenuItem("Exit");
class MenuItemListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
}
ActionListener listener = new MenuItemListener();
item.addActionListener(listener);
return item;
}
76
/**
Crea la voce di menu che sposta il rettangolo e
imposta il ricevitore.
@param label l’etichetta del menu
@param dx l’ammonstare dello spostamento in direz. x
@param dy l’ammontare dello spostamento in direz. y
@return la voce di menu
*/
public JMenuItem createMoveItem(String label,
final int dx, final int dy)
{
JMenuItem item = new JMenuItem(label);
77
class MenuItemListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
panel.moveRectangle(dx, dy);
}
}
ActionListener listener = new MenuItemListener();
item.addActionListener(listener);
return item;
}
78
/**
Crea la voce di menu Edit->Randomize e imposta il
ricevitore.
@return la voce di menu
*/
public JMenuItem createEditRandomizeItem()
{
JMenuItem item = new JMenuItem("Randomize");
class MenuItemListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
int width = panel.getWidth();
int height = panel.getHeight();
int dx = -1 + generator.nextInt(2);
int dy = -1 + generator.nextInt(2);
panel.moveRectangle(dx, dy);
}
}
79
ActionListener listener = new MenuItemListener();
item.addActionListener(listener);
return item;
}
private RectanglePanel panel;
private Random generator;
}
80
File MenuTest.java
import javax.swing.JFrame;
/**
Testa la classe MenuFrame.
*/
public class MenuTest
{
public static void main(String[] args)
{
JFrame frame = new MenuFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
81
File RectanglePanel.java
import
import
import
import
import
java.awt.Dimension;
java.awt.Graphics;
java.awt.Graphics2D;
java.awt.Rectangle;
javax.swing.JPanel;
// Questo pannello visualizza un rettangolo.
class RectanglePanel extends JPanel
{
/**
Costruisce un pannello con un rettangolo in
posizione predefinita.
*/
82
public RectanglePanel()
{
setPreferredSize(new Dimension(PANEL_WIDTH,
PANEL_HEIGHT));
// il rettangolo disegnato dal metodo paint
box = new Rectangle(0, 0, BOX_WIDTH, BOX_HEIGHT);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.draw(box);
}
83
// Riporta il rettangolo nell’angolo superiore sx.
public void reset()
{
box.setLocation(0, 0);
repaint();
}
/**
Muove il rettangolo per multipli di larghezza e
altezza e lo ridisegna.
@param dx le unità di larghezza
@param dy le unità di altezza
*/
public void moveRectangle(int dx, int dy)
{
box.translate(dx * BOX_WIDTH, dy * BOX_HEIGHT);
repaint();
}
84
private
private
private
private
private
Rectangle box;
static final int
static final int
static final int
static final int
BOX_WIDTH = 20;
BOX_HEIGHT = 30;
PANEL_WIDTH = 300;
PANEL_HEIGHT = 300;
}
85
86
Consultare la documentazione
di Swing
ƒ Vogliamo creare un’applicazione grafica in cui
l’utente crea un nuovo colore spostando dei
cursori per i colori primari
ƒ Come creare un cursore?
ƒ Come sapere se l’utente lo sposta?
ƒ Come conoscerne il valore?
87
Consultare la documentazione
di Swing
ƒ Consultiamo la documentazione della classe
JSlider: ci sono 6 costruttori…
ƒ JSlider()
ƒ Crea un cursore orizzontale tra 0 e 100 con valore iniziale 50
ƒ JSlider(int min, int max, int value)
ƒ Crea un cursore orizzontale usando i valori specificati
ƒ …
ƒ …
88
Consultare la documentazione
di Swing
ƒ Quali eventi genera un cursore?
ƒ Può subire una modifica, relativa allo spostamento
ƒ Per
intercettare
la
modifica,
una
classe
deve
implementare l’interfaccia ChangeListener, che ha un solo
metodo
public interface ChangeListener
{
void stateChanged(ChangeEvent event);
}
89
Consultare la documentazione
di Swing
ƒ Per calcolare il valore attuale del cursore usiamo il metodo
getValue()
ƒ Possiamo aggiungere lo stesso ricevitore di eventi a tutti e
tre i cursori
90
File SliderFrame.java
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.BorderLayout;
java.awt.Color;
java.awt.Container;
java.awt.Dimension;
java.awt.GridLayout;
java.awt.event.WindowAdapter;
java.awt.event.WindowEvent;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JPanel;
javax.swing.JSlider;
javax.swing.SwingConstants;
javax.swing.event.ChangeListener;
javax.swing.event.ChangeEvent;
91
class SliderFrame extends JFrame
{
public SliderFrame()
{
colorPanel = new JPanel();
colorPanel.setPreferredSize(new
Dimension(PANEL_WIDTH, PANEL_HEIGHT));
getContentPane().add(colorPanel,
BorderLayout.CENTER);
createControlPanel();
setSampleColor();
pack();
}
92
public void createControlPanel()
{
class ColorListener implements ChangeListener
{
public void stateChanged(ChangeEvent event)
{
setSampleColor();
}
}
93
ChangeListener listener = new ColorListener();
redSlider = new JSlider(0, 100, 100);
redSlider.addChangeListener(listener);
greenSlider = new JSlider(0, 100, 70);
greenSlider.addChangeListener(listener);
blueSlider = new JSlider(0, 100, 70);
blueSlider.addChangeListener(listener);
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new GridLayout(3, 2));
controlPanel.add(new JLabel("Red”, SwingConstants.RIGHT));
controlPanel.add(redSlider);
94
controlPanel.add(new JLabel("Green", SwingConstants.RIGHT));
controlPanel.add(greenSlider);
controlPanel.add(new JLabel("Blue", SwingConstants.RIGHT));
controlPanel.add(blueSlider);
getContentPane().add(controlPanel, BorderLayout.SOUTH);
}
/**
Legge I valori del cursore e imposta il pannello sul
colore selezionato.
*/
public void setSampleColor()
{ // legge I valori del cursore
float red = 0.01F * redSlider.getValue();
float green = 0.01F * greenSlider.getValue();
float blue = 0.01F * blueSlider.getValue();
95
// imposta lo sfondo del pannello sul colore selezionato
colorPanel.setBackground(new Color(red, green, blue));
colorPanel.repaint();
}
private
private
private
private
JPanel colorPanel;
JSlider redSlider;
JSlider greenSlider;
JSlider blueSlider;
private static final int PANEL_WIDTH = 300;
private static final int PANEL_HEIGHT = 300;
}
96
File SliderTest.java
import javax.swing.JFrame;
public class SliderTest
{
public static void main(String[] args)
{
SliderFrame frame = new SliderFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
97
Le Componenti di SliderFrame
98
Le Classi di SliderTest
99