Esame di PROGRAMMAZIONE ORIENTATA AGLI OGGETTI Appello del 4.9.2013 COGNOME.NOME. Matricola Tre classi, denominate Anemone, Fiordaliso e Viola devono assicurare la visualizzazione di un fiore stilizzato della corrispondente specie (con lo stelo disposto verso l'alto oppure verso il basso e inclinato verso destra oppure verso sinistra) sul pannello di una interfaccia grafica, a fronte del messaggio fiore.traccia( g ) in cui g rappresenta il contesto grafico usato. L'interfaccia grafica, denominata FioriGUI, contiene due pannelli: (1) un pannello di controllo dotato dei pulsanti Clear, Insert ed Erase configurati come in Fig.1; (2) un pannello di tracciatura, su cui riprodurre una composizione floreale. La composizione è ottenuta mediante ripetute pressioni del pulsante Insert, ognuna delle quali causa la generazione di un nuovo fiore. Per contro, la funzione del pulsante Erase è quella di rimuovere dal pannello l'ultimo fiore inserito in ordine di tempo, mentre scopo del pulsante Clear è di rimuovere tutti i profili floreali correntemente presenti sul pannello. Fig. 1 Distribuzione casuale della composizione floreale. La struttura della classe FioriGUI è sintetizzata nel seguito, in cui panfiori costituisce il pannello di visualizzazione dell'interfaccia: class FioriGUI extends JFrame { private PanFiori panfiori; private JPanel panctrl; private JButton btnclear, btninsert, btnerase; public FioriGUI (int hsize, int vsize) { setdefaultcloseoperation( JFrame.EXIT_ON_CLOSE );
settitle( getclass().getname() ); setsize( hsize, vsize ); Container cnt = getcontentpane(); cnt.setlayout( new BorderLayout() ); // Creazione del pannello di tracciatura panfiori panfiori = new PanFiori(); panfiori.setbackground( Color.yellow ); cnt.add( panfiori, BorderLayout.CENTER ); // Creazione del pannello di controllo panctrl = new JPanel(); panctrl.setlayout( new BoxLayout( panctrl, BoxLayout.Y_AXIS )); btninsert = new JButton( "Insert", new ImageIcon( "Fiore.jpg" )); btninsert.addactionlistener( new ActionListener() { panfiori.insertfiore(); ); panctrl.add( btninsert ); btnclear = new JButton( "Clear", new ImageIcon( "Fiori.jpg" )); btnclear.addactionlistener( new ActionListener() { panfiori.clearfiori(); ); panctrl.add( btnclear ); btnerase = new JButton( "Erase", new ImageIcon( "Fiore.jpg" )); btnerase.addactionlistener( new ActionListener() { panfiori.erasefiore(); ); panctrl.add( btnerase ); cnt.add( panctrl, BorderLayout.EAST ); setvisible( true ); Esercizio P1 (punti 12) In relazione agli oggetti fiore da visualizzare, si consideri che essi sono istanziabili dalle classi Anemone, Fiordaliso e Viola, la cui struttura è similare ed è schematizzabile come sotto indicato per la classe Anemone: class Anemone { public Anemone (int x, int y, int dir) {... public void traccia (Graphics g) { Graphics2D g2 = (Graphics2D) g; GeneralPath corolla = new GeneralPath(); // Punto di incardinamento e direzione
// Creazione della corolla corolla.closepath(); GeneralPath stelo = new GeneralPath(); // Creazione dello stelo stelo.closepath();............ Delineare l'organizzazione complessiva delle classi destinate alla modellazione degli oggetti fiore, completando con quanto ritenuto necessario (si escluda il codice relativo alla costruzione di corolla e stelo) il codice della classe Anemone e di sue eventuali sovraclassi e/o interfacce implementate. SOLUZIONE abstract class Fiore { protected int x, y; protected int dir = 1; // Coordinate punto di riferimento public Fiore( int x, int y, int dir ) { this.x = x; this.y = y; this.dir = dir; public abstract void traccia (Graphics g); class Anemone extends Fiore { public Anemone( int x, int y, int dir ) { super( x, y, dir ); public void traccia (Graphics g) { Graphics2D g2 = (Graphics2D) g; GeneralPath corolla = new GeneralPath(); // Costruzione della corolla corolla.closepath(); GeneralPath stelo = new GeneralPath(); // Costruzione dello stelo stelo.closepath(); g2.setcolor( Color.green ); g2.fill( stelo ); g2.setcolor( Color.red ); g2.fill( corolla );
Esercizio P2 (punti 21) Fornire il codice della classe PanFiori. In relazione al metodo insertfiore() di questa, si ricordi che la sua funzione è di creare un ulteriore fiore per ogni chiamata, procedendo all'inserimento dello stesso sul pannello dell'interfaccia nella posizione individuata da un click del mouse (deve quindi essere possibile sfruttare un solo click del mouse per ogni pressione del pulsante Insert ): la selezione del tipo di fiore, la collocazione dello stelo, supero o infero, e l'orientamento di quest'ultimo, inclinato verso destra o verso sinistra, devono essere casuali. SOLUZIONE class PanFiori extends JPanel { private Random rdn = new Random(); private int x, y; private Fiore fiore; private LinkedList<Fiore> fioridisponibili = new LinkedList<Fiore>(); private AscMouse ascmouse = new AscMouse(); private PanFiori panfiori; private static boolean ascadded = false; public PanFiori() { panfiori = this; public void paintcomponent (Graphics g) { super.paintcomponent( g ); Iterator<Fiore> iterator = fioridisponibili.iterator(); while (iterator.hasnext()) { fiore = iterator.next(); fiore.traccia( g ); class AscMouse extends MouseAdapter { public void mousepressed (MouseEvent ev) { x = ev.getx(); y = ev.gety(); int d = (rdn.nextint( 2 ) == 0)? -1 : 1; int k = rdn.nextint( 3 ); switch( k ) { case 0: fiore = new Anemone( x, y, d ); break; case 1: fiore = new Fiordaliso( x, y, d ); break; case 2: fiore = new Viola( x, y, d ); break; fioridisponibili.addlast( fiore ); panfiori.removemouselistener( this ); ascadded = false;
public void clearfiori() { fioridisponibili.clear(); public void insertfiore() { if (! ascadded) { panfiori.addmouselistener( ascmouse ); ascadded = true; public void erasefiore() { if (! fioridisponibili.isempty() ) { fioridisponibili.removelast();