Sezione: Upcast - downcast Upcast & downcast Coercion Una funzione può essere polimorfa senza essere stata disegnata tale intenzionalmente. Sia f una funzione che prende un argomento di tipo T, e S sia un tipo che può essere automaticamente convertito in T. Allora f può essere detta polimorfa respetto a S e T. float somma(float x, float y) accetta anche somma (3, 3.14) somma(2,3) (coercion di int a float) public class Test { public static void main(String a[]) { new Test(); } cast Test() { A a; B b = new B(); OK: upcast implicito a=b; a.f1(); NO: "method f2 not a.f2(); found in class A" class A { void f1() } (compiler) {System.out.println("f1");} } } class B extends A { void f2() {System.out.println("f2");} } class C extends B { void f3() {System.out.println("f3");} } public class Test { public static void main(String a[]) { new Test(); } cast Test() { A a; B b = new B(); OK: upcast implicito a=b; a.f1(); OK: downcast corretto ((B)a).f2(); class A { void f1() } {System.out.println("f1");} } } class B extends A { void f2() {System.out.println("f2");} } class C extends B { void f3() {System.out.println("f3");} } public class Test { public static void main(String a[]) { new Test(); } cast Test() { A a; B b = new B(); OK: upcast implicito a=b; a.f1(); NO: downcast illecito (runtime) ((C)a).f3(); java.lang.ClassCastException class A { void f1() } {System.out.println("f1");} } } class B extends A { void f2() {System.out.println("f2");} } class C extends B { void f3() {System.out.println("f3");} } Type conversion - cast Si può applicare cast SOLO all’interno di una gerarchia di ereditarietà È consigliabile usare l'operatore instanceof per verificare prima effettuare un downcast if (staff[1] instanceof Manager) { Manager n = (Manager)staff[1]; ... } Ancora sugli Eventi Gestione degli eventi Modello 1.1 Listener interface Component x AWTEvent Event is generated for a component Component has not registered for that event class Event is discarded Component has registered for that event class Component gets the event Event is consumed Component passes the Event to Listener Listener executes suitable method 9 multiListenerDemo package listenersdemo; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class MultiListener extends JPanel implements ActionListener { JTextArea topTextArea; JTextArea bottomTextArea; JButton button1, button2; JLabel l = null; final static String newline = "\n"; public static void main(String[] args) { createAndShowGUI(); } 10 multiListenerDemo private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("MultiListener"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new MultiListener(); frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); } 11 multiListenerDemo public MultiListener() { super(new FlowLayout()); l = new JLabel("Cosa sento io:"); add(l); topTextArea = new JTextArea(); topTextArea.setEditable(false); JScrollPane topScrollPane = new JScrollPane(topTextArea); Dimension preferredSize = new Dimension(200, 75); topScrollPane.setPreferredSize(preferredSize); add(topScrollPane); l = new JLabel("Cosa sente la spia:"); add(l); bottomTextArea = new JTextArea(); bottomTextArea.setEditable(false); 12 multiListenerDemo JScrollPane bottomScrollPane = new JScrollPane(bottomTextArea); bottomScrollPane.setPreferredSize(preferredSize); add(bottomScrollPane); button1 = new JButton("Fra Martino campanaro"); add(button1); button2 = new JButton("Dormi tu?"); add(button2); button1.addActionListener(this); button2.addActionListener(this); button2.addActionListener(new Spia(bottomTextArea)); setPreferredSize(new Dimension(400, 300)); } public void actionPerformed(ActionEvent e) { topTextArea.append(e.getActionCommand() + newline); } } topTextArea.setCaretPosition(topTextArea.getDocument().getLe ngth()); 13 multiListenerDemo class Spia implements ActionListener { JTextArea myTextArea; public Spia(JTextArea ta) { myTextArea = ta; } public void actionPerformed(ActionEvent e) { myTextArea.append(e.getActionCommand() + MultiListener.newline); } } myTextArea.setCaretPosition(myTextArea.getDocument().getLe ngth()); 14 Design considerations The most important rule to keep in mind about event listeners that they should execute very quickly. Because all drawing and eventlistening methods are executed in the same thread, a slow eventlistener method can make the program seem unresponsive and slow to repaint itself. You might choose to implement separate classes for different kinds of event listeners. This can be an easy architecture to maintain, but many classes can also mean reduced performance. When designing your program, you might want to implement your event listeners in a class that is not public, but somewhere more hidden. A private implementation is a more secure implementation. 15 Low-Level Events and Semantic Events Events can be divided into two groups: low-level events and semantic events. Low-level events represent window-system occurrences or low-level input. Everything else is a semantic event. Examples of low-level events include mouse and key events — both of which result directly from user input. Examples of semantic events include action and item events. Whenever possible, you should listen for semantic events rather than low-level events. That way, you can make your code as robust and portable as possible. For example, listening for action events on buttons, rather than mouse events, means that the button will react appropriately when the user tries to activate the button using a keyboard alternative or a look-and-feel-specific gesture. 16 Listeners/Adapters public class MyClass implements MouseListener { ... someObject.addMouseListener(this); ... /* Empty method definition. */ public void mousePressed(MouseEvent e) { } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { ...//Event listener implementation goes here... } } 17 Listeners/Adapters /* * An example of extending an adapter class instead of * directly implementing a listener interface. */ public class MyClass extends MouseAdapter { ... someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) { //Event ... } } listener implementation goes here 18 Inner classes //An example of using an inner class. public class MyClass extends JFrame { ... someObject.addMouseListener( new MyAdapter()); ... class MyAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e){ ...//Event listener implementation goes here... } } } 19 Anonymous Inner classes //An example of using an inner class. public class MyClass extends JFrame { ... someObject.addMouseListener( new MouseAdapter () { public void mouseClicked(MouseEvent e){ ...//Event listener implementation goes here... } } ); … } 20 Inner classes An instance of InnerClass can exist only within an instance of EnclosingClass and it has direct access to the instance variables and methods of its enclosing instance. 21 Anonymous Inner classes //An example of using an inner class. public class MyClass extends JFrame { ... someObject.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e){ ...//Event listener implementation goes here... } } }); ... } 22 Listeners supported by all Swing components component listener Listens for changes in the component's size, position, or visibility. focus listener Listens for whether the component gained or lost the ability to receive keyboard input. key listener Listens for key presses; key events are fired only by the component that has the current keyboard focus. mouse listener Listens for mouse clicks and mouse movement into or out of the component's drawing area. mouse-motion listener Listens for changes in the cursor's position over the component. mouse-wheel listener (introduced in 1.4) Listens for mouse wheel movement over the component. 23 Altri listeners action caret change document undoable edit item list selection window + Listeners speciali per componenti specifiche (treeNodeExpansion, ecc) Grafica di Java Introduzione alla costruzione di GUI Pluggable Look & Feel Pluggable Look&Feel Scelta del Look&Feel public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { } new SwingApplication(); //Create and show the GUI. } UIManager.getCrossPlatformLookAndFeelClassName() Returns the Java look and feel. UIManager.getSystemLookAndFeelClassName() Specifies the look and feel for the current platform. Scelta del Look&Feel public static void main(String[] args) { try { UIManager.setLookAndFeel( "com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); } catch (Exception e) { } new SwingApplication(); //Create and show the GUI. } UIManager.getSystemLookAndFeelClassName(String s) Specifies the look and feel for the platform described by “s”. Available Look&Feel "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" Specifies the GTK+ look and feel. Introduced in release 1.4.2. "javax.swing.plaf.metal.MetalLookAndFeel" Specifies the Java look and feel. "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" Specifies the Windows look and feel. Currently, you can use this look and feel only on Microsoft Windows systems. "com.sun.java.swing.plaf.motif.MotifLookAndFeel" Specifies the CDE/Motif look and feel. This look and feel can be used on any platform.