// by DAniele / MArco / DARio

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.event.*;
import java.util.*;
// per le immagini
import java.io.*;
import javax.imageio.*;
import java.awt.image.*;
import javax.swing.filechooser.FileFilter;
import java.awt.color.*;


// il frame principale
class myFrame extends JFrame {
    //dimensioni schermo
    Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize();
    //pannello pubblico
    public myPanel mainPanel;
   // costruttore
    public myFrame() {
        setTitle("Prova DaMaDar");
        setSize(dScreen.width/2, dScreen.height/2);
        //il pannello appare centrato
        setLocation((dScreen.width - getSize().width) / 2,
                    (dScreen.height - getSize().height) / 2);
        addWindowListener( new
            WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            }
        );
        // crea e inserisce pannello nel frame
        mainPanel = new myPanel();
        getContentPane().add(mainPanel);
        // inserisce menu nel frame
         new menuDaMaDar(this);
    }    
}

// pannello principale
class myPanel extends JPanel implements ChangeListener {
    //I pannelli:
    imagePanel pnlImmagine;
    sliderPanel pnlSlider;
    infoPanel pnlInfo;
    
    public myPanel() {
        super();
        setLayout(new GridLayout(1, 2, 10, 10));
        // prima colonna (2 pannelli verticali contenuti in groupPanel)
        JPanel groupPanel = new JPanel();
        groupPanel.setLayout(new GridLayout(2, 1, 10, 10));
        pnlSlider = new sliderPanel();
        pnlInfo = new infoPanel();
        groupPanel.add(pnlSlider);
        groupPanel.add(pnlInfo);
        add(groupPanel);
        //seconda colonna
        pnlImmagine = new imagePanel();
        add(new JScrollPane(pnlImmagine));
        // impostazione ascoltatore pannello x slider
        pnlSlider.slider.addChangeListener(this);
        pnlSlider.sliderTransparency.addChangeListener(this);
        pnlSlider.sliderLumin.addChangeListener(this);
    }        
    
    // scrive informazioni immagine sul pannello
    public void writeInfoInToInfoPanel() {
        pnlInfo.txtArea.setText(pnlImmagine.infoImage());
    }
    
    // setta valori min e max dello slider
    public void setSliderBounds() {
        int width = pnlImmagine.getDimensionImage().width;
        // setta slider ZOOM
        int min = 1 * (width * 2) / 100;
        int max = (width * 2);
        pnlSlider.slider.setEnabled(true);              // abilita slider
        pnlSlider.slider.setMinimum(min);               // minimo = 10% della larghezza
        pnlSlider.slider.setMaximum(max);               // massimo = 100% larhezza
        pnlSlider.slider.setValue(50*width*2/100);      // valore iniziale = 50% larghezza
        pnlSlider.slider.setMajorTickSpacing(width/20);
        pnlSlider.slider.setMinorTickSpacing(width/10);
        pnlSlider.slider.setPaintTicks(true);
        pnlSlider.slider.setSnapToTicks(true);
        Hashtable labelTb = new Hashtable();
        labelTb.put(new Integer(min), new JLabel("1%"));
        labelTb.put(new Integer(50*width*2/100), new JLabel("100%"));
        labelTb.put(new Integer(max), new JLabel("200%"));
        pnlSlider.slider.setLabelTable(labelTb);
        pnlSlider.slider.setPaintLabels(true);
        
        // setta slider TRASPARENZA
        pnlSlider.sliderTransparency.setEnabled(true);              // abilita slider
        pnlSlider.sliderTransparency.setMinimum(0);      
        pnlSlider.sliderTransparency.setMaximum(100);            
        pnlSlider.sliderTransparency.setValue(100);        
        pnlSlider.sliderTransparency.setMajorTickSpacing(10);
        pnlSlider.sliderTransparency.setMinorTickSpacing(25);
        pnlSlider.sliderTransparency.setPaintTicks(true);
        pnlSlider.sliderTransparency.setSnapToTicks(true);
        Hashtable labelTbTr = new Hashtable();
        labelTbTr.put(new Integer(0), new JLabel("Trasparente"));
        labelTbTr.put(new Integer(50), new JLabel("50%"));
        labelTbTr.put(new Integer(100), new JLabel("Opaca"));
        pnlSlider.sliderTransparency.setLabelTable(labelTbTr);
        pnlSlider.sliderTransparency.setPaintLabels(true);
        
        // setta slider LUMINOSITA'
        pnlSlider.sliderLumin.setEnabled(true);              // abilita slider
        pnlSlider.sliderLumin.setMinimum(0);      
        pnlSlider.sliderLumin.setMaximum(200);            
        pnlSlider.sliderLumin.setValue(100);        
        pnlSlider.sliderLumin.setMajorTickSpacing(10);
        pnlSlider.sliderLumin.setMinorTickSpacing(25);
        pnlSlider.sliderLumin.setPaintTicks(true);
        pnlSlider.sliderLumin.setSnapToTicks(true);
        Hashtable labelTbTr1 = new Hashtable();
        labelTbTr1.put(new Integer(0), new JLabel("Scuro"));
        labelTbTr1.put(new Integer(100), new JLabel("Normale"));
        labelTbTr1.put(new Integer(200), new JLabel("Chiaro"));
        pnlSlider.sliderLumin.setLabelTable(labelTbTr1);
        pnlSlider.sliderLumin.setPaintLabels(true);
    }
    
    // eventi generati dallo slider
    public void stateChanged(ChangeEvent e) {
        if (e.getSource() == pnlSlider.slider)
            // ZOOM immagine
            pnlImmagine.transformRescale(((JSlider)e.getSource()).getValue());
        else if (e.getSource() == pnlSlider.sliderTransparency)
            // TRASPARENZA immagine
            pnlImmagine.transformTrasparenza(((JSlider)e.getSource()).getValue());
        else if (e.getSource() == pnlSlider.sliderLumin)
            // Luminosità immagine
            pnlImmagine.transformLuminanza(((JSlider)e.getSource()).getValue(), false);
    }
    
}

// classe che carica e visualizza l'immagine
class imagePanel extends JPanel {
    private JLabel label;               //label destinata a contenere l'immagine
    private JFileChooser fileChooser;   //finestra di dialogo per aprire i file    
    private File fileImage;             //contiene l'informazioni sul file aperto
    private BufferedImage mybuffer;     //contiene il buffer immagine corrente

    //costruttore
    public imagePanel() {
        super();
        setBackground(Color.black);
        fileChooser = new JFileChooser();
        //Disabilito al visualizzazione di tutti i tipi di file
        fileChooser.setAcceptAllFileFilterUsed(false);
        //Abilito la visualizzazione dei file di tipo jpg, gif e png
        fileChooser.setFileFilter(new GIFFilter());           
        fileChooser.setFileFilter(new PNGFilter());    
        fileChooser.setFileFilter(new JPGFilter());            
        // Imposto la directory iniziale
        fileChooser.setCurrentDirectory(new File("e:\\Immagini/FotoSilvio/Etna"));      
        //Inserisco una Label vuota (conterrà l'immagine caricata)
        setLayout(new FlowLayout(FlowLayout.LEFT));
        label = new JLabel();
        //aggiungo la label al pannello
        add(label);
    }
    
    /*  ************************************************************
        ***************** interfaccia pubblica**********************
        ************************************************************ */
    
    //apre una immagine e ne restituisce il buffer
    public BufferedImage openImage() {
        //Imposto il titolo della finestra
        fileChooser.setDialogTitle("Apri file");
        //Visualizzo la finestra di dialogo
        int risposta = fileChooser.showOpenDialog(this);
        //Se ho premuto il tasto apri...
        if (risposta == fileChooser.APPROVE_OPTION)  {  
          //Recupero il file selezionato
          fileImage = fileChooser.getSelectedFile();
          try {
                BufferedImage buff = ImageIO.read(fileImage);
                //recupero le dimensioni dell'immagine
                int w=buff.getWidth();
                int h=buff.getHeight();
                //Creo un'immagine nuova delle stesse dimensioni
                mybuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
                /*
                  Disegno l'immagine caricata sulla nuova immagine.
                  Questa operazione va fatta per essere sicuro che l'immagine su cui lavoro
                  è di tipo TYPE_INT_ARGB
                */
                Graphics2D g2 = mybuffer.createGraphics();
                g2.drawImage(buff, 0, 0, null);
                g2.dispose();                          
          }
          catch (Exception ex) {}
        }
        return mybuffer;
    }
    
    // salva immagine così come si trova nell'icona
    public void saveImage() {
        //Imposto il titolo della finestra
        fileChooser.setDialogTitle("Salva file");
        //Recupero l'immagine da salvare
        BufferedImage image = (BufferedImage)((ImageIcon)label.getIcon()).getImage();
        if (image == null) {
          JOptionPane.showMessageDialog(label, "Nessuna immagine disponibile",
                                        "Errore", JOptionPane.ERROR_MESSAGE);
          return;
        }
        int risposta2 = JOptionPane.NO_OPTION;
        File f = null;
        String ext = null;
        while (risposta2 == JOptionPane.NO_OPTION) {
          //Visualizzo la finestra di dialogo
          int risposta = fileChooser.showSaveDialog(label);
          if (risposta == fileChooser.APPROVE_OPTION) {
              // e' stato premuto "Salva"
            try {
              //Recupero il file selezionato
              f = fileChooser.getSelectedFile();
              //Recupero l'estensione del file
              ext = fileChooser.getFileFilter().toString();
              //Recupero il path del file
              String str = f.getCanonicalPath();
              //Se il nome del file non contiene l'estensione, la aggiungo io a mano
              if (!str.toLowerCase().endsWith("." + ext)) f = new File(str + "." + ext);
              //Se il file esiste chiedo se lo voglio sovrascrivere
              if (f.exists())
                    risposta2 = JOptionPane.showConfirmDialog(label,
                              "Il file esiste già,\nlo vuoi sovrascrivere?",
                              "Sovrascrittura",
                              JOptionPane.YES_NO_CANCEL_OPTION,
                              JOptionPane.QUESTION_MESSAGE);
              else
                    risposta2 = JOptionPane.YES_OPTION;
            }
            catch (Exception ex) {}
          }
          else
            risposta2 = JOptionPane.CANCEL_OPTION;
        }
        if (risposta2 == JOptionPane.YES_OPTION) {
          try {
            //Provo a salvare l'immagine
            ImageIO.write(image, ext, f);
          }
          catch (Exception ex) {}
        }
    }

    // nuova area disegno
    public void nuovo(int w, int h) {
        //Creo una nuova immagine
        mybuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        //Creo il contesto grafico dell'immagine
        Graphics2D g2 = mybuffer.createGraphics();
        //Imposto il colore a bianco
        g2.setColor(Color.white);
        //Disegno un rettangolo grande quanto tutto l'immagine
        g2.fillRect(0, 0, mybuffer.getWidth(), mybuffer.getHeight());
        //Rilascio le risorse del contesto grafico
        g2.dispose();
        //Ridisegno l'immagine
        refreshImage();
    }


    // negativo dell'immagine
    public void transformToNegativo() {
        // ottengo un contesto grafico
        Graphics2D g2 = mybuffer.createGraphics();
        //Imposto come colore il bianco
        g2.setColor(Color.white);
        //Imposto la modalità XOR e come colore XOR il nero
        g2.setXORMode(Color.black);
        //Riempio l'immagine con un rettangolo grande quando l'immagine,
        g2.fillRect(0, 0, mybuffer.getWidth(), mybuffer.getHeight());
        //Rilascio le risorse
        g2.dispose();        
        //Ridisegno l'immagine
        refreshImage();
    }

    
    public void transformToGrigio() {
        //Creo una nuova immagine buffer
        BufferedImage buff = new BufferedImage(mybuffer.getWidth(), mybuffer.getHeight(),
                                 BufferedImage.TYPE_INT_ARGB);
        //Ottengo lo spazio dei colori per i toni di grigio
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        //Creo il filtro ci conversione dei colori
        ColorConvertOp op = new ColorConvertOp(cs, null);
        //Eseguo il filtro
        op.filter(mybuffer, buff);
        //Ricopio il risultato sull'immagine originale
        Graphics2D g2 = mybuffer.createGraphics();
        g2.drawImage(buff, 0, 0, null);
        //Rilascio le risorse
        g2.dispose();
        //Ridisegno il pannello
        refreshImage();
      }
    
    
    public void transformRuota(double angle) {
        //Creao una traslazione
        AffineTransform txTrasla = AffineTransform.getTranslateInstance(
                                 Math.sin((angle)) * mybuffer.getWidth() ,0);
        //Creo una rotazione
        AffineTransform txRuota = AffineTransform.getRotateInstance(angle);
        //Concateno le due trasformazioni affini
        txTrasla.concatenate(txRuota);
        //Creo un'operazione di trasformazione affine
        AffineTransformOp op = new AffineTransformOp(txTrasla, AffineTransformOp.TYPE_BILINEAR);
        //Applico il filtro di trasformazione
        mybuffer = op.filter(mybuffer, null);
        //Ridisegno il pannello
        refreshImage();
    }
    
    
    public void transformSoglia(int valore) {
        //Creo una nuova immagine buffer
        BufferedImage buff = new BufferedImage(mybuffer.getWidth(), mybuffer.getHeight(),
                                 BufferedImage.TYPE_INT_ARGB);
        //Creo una LUT
        short[][] data = new short[4][256];
        for (int i = 0; i < 256; i++) {
          /*
          data[0][i] = (short)(i / 128 * 255);  //Red
          data[1][i] = (short)(i / 128 * 255);  //Green
          data[2][i] = (short)(i / 128 * 255);  //Blue
          data[3][i] = 255;                     //Alpha
         */

          data[0][i] = (short)((i < valore)? 0 : i);  //Red
          data[1][i] = (short)((i < valore)? 0 : i);  //Green
          data[2][i] = (short)((i < valore)? 0 : i);  //Blue
          data[3][i] = (short)(255);                     //Alpha
            
          /*
          data[0][i] = (short)i;  //Red
          data[1][i] = (short)i;  //Green
          data[2][i] = (short)i;  //Blue
          data[3][i] = (short)(128);                     //Alpha
          */  
        }
        ShortLookupTable table = new ShortLookupTable(0, data);
        //Creo un filtro LUT
        LookupOp filtro = new LookupOp(table, null);
        //Eseguo la LUT
        filtro.filter(mybuffer, buff);
        //Ricopio il risultato sull'immagine originale
        Graphics2D g2 = mybuffer.createGraphics();
        g2.drawImage(buff, 0, 0, null);
        //Rilascio le risorse
        g2.dispose();
        //Ridisegno il pannello
        refreshImage();
    }

    public void transformLuminanza(int percentuale, boolean saved) {
        float convToRatio = (((float)percentuale / 100) * 1);
        //Creo una nuova immagine buffer
        BufferedImage buff = new BufferedImage(mybuffer.getWidth(), mybuffer.getHeight(),
                                 BufferedImage.TYPE_INT_ARGB);
        //Creo una LUT
        short[][] data = new short[4][256];
        float value;
        for (int i = 0; i < 256; i++) {
            value = i * convToRatio;
            if (value > 255) value = 255;
            if (value < 0) value = 0;
            data[0][i] = (short)value;  //Red
            data[1][i] = (short)value;  //Green
            data[2][i] = (short)value;  //Blue
            data[3][i] = (short)(255);  //Alpha
        }
        ShortLookupTable table = new ShortLookupTable(0, data);
        //Creo un filtro LUT
        LookupOp filtro = new LookupOp(table, null);
        //Eseguo la LUT
        filtro.filter(mybuffer, buff);
        if (!saved)
            label.setIcon(new ImageIcon(buff));
        else {
            Graphics2D g2 = mybuffer.createGraphics();
            g2.drawImage(buff, 0, 0, null);
            //Rilascio le risorse
            g2.dispose();
            //Ridisegno il pannello
            refreshImage();
        }
    }
    
    public void transformTrasparenza(int percentuale) {
        int convTo255 = (int)(((float)percentuale / 100) * 255);
        //Per tutti i pixel dell'immagine
        for (int x = 0; x < mybuffer.getWidth(); x++)
          for (int y = 0; y < mybuffer.getHeight(); y++) {
            //Recupero le componenti RGB del pixel
            int colore = mybuffer.getRGB(x, y);
            int a = (colore&0xFF000000) >> 24;
            int r = (colore&0x00FF0000) >> 16;
            int g = (colore&0x0000FF00) >> 8;
            int b = colore&0x000000FF;
            a = convTo255;
            colore = (a << 24) | (r << 16) | (g << 8) | b;
            mybuffer.setRGB(x, y, colore);
          }
        //Ridisegno il pannello
        refreshImage();          
    }

    public void transformRescale(int scaleX) {
        // ZOOM immagine
        float ratio = (float)mybuffer.getWidth() / mybuffer.getHeight();
        int height = (int)(scaleX / ratio);
        // creo un nuovo buffer di immagine, con grandezza pari alla nuova immagine
        BufferedImage rescaleBuffer = new BufferedImage(scaleX, height, BufferedImage.TYPE_INT_ARGB);
        // ottengo dal nuovo buffer un contesto grafico
        Graphics g2 = rescaleBuffer.createGraphics();
        // disegno l'immagine "scalata" sul contesto grafico del nuovo buffer
        g2.drawImage(mybuffer, 0, 0, scaleX, height, null);
        // rilascio le risorse del contesto grafico
        g2.dispose();
        label.setIcon(new ImageIcon(rescaleBuffer));
    }
    
    private void transformWithKernel(float[] data) {
        //Creo una nuova immagine buffer
        BufferedImage buff = new BufferedImage(mybuffer.getWidth(), mybuffer.getHeight(),
                                 BufferedImage.TYPE_INT_RGB);
        //creo il kernel
        Kernel k = new Kernel(3, 3, data);
        //Creo il filtro convolutivo
        ConvolveOp op = new ConvolveOp(k);
        //Eseguo il filtro
        op.filter(mybuffer, buff);
        //Ricopio il risultato sull'immagine originale
        Graphics2D g2 = mybuffer.createGraphics();
        g2.drawImage(buff, 0, 0, null);
        //Rilascio le risorse
        g2.dispose();
        //Ridisegno il pannello
        refreshImage();
    }
    
    public void transformSfuma() {
        //Creo la matrice del kernel
        float[] dataKernel = new float[] {
          0.111F, 0.111F, 0.111F,         // 1/9
          0.111F, 0.111F, 0.111F,
          0.111F, 0.111F, 0.111F
        };
        transformWithKernel(dataKernel);
    }
    
    public void transformEsaltaBordi() {
        //Creo la matrice del kernel
        float[] dataKernel = new float[] {
           0F,-1F, 0F,
          -1F, 5F,-1F,
           0F,-1F, 0F
        };
        transformWithKernel(dataKernel);
    }

    public void transformEstraiBordi() {
        //Creo la matrice del kernel
        float[] dataKernel = new float[] {
           0F,-1F, 0F,
          -1F, 4F,-1F,
           0F,-1F, 0F            
        };
        transformWithKernel(dataKernel);
    }
    
    public void transformDerivataX() {
        //Creo la matrice del kernel
        float[] dataKernel = new float[] {
          -1F, 0F, 1F,
          -1F, 0F, 1F,
          -1F, 0F, 1F        
        };
        transformWithKernel(dataKernel);
    }

    public void transformDerivataY() {
        //Creo la matrice del kernel
        float[] dataKernel = new float[] {
          -1F,-1F,-1F,
           0F, 0F, 0F,
           1F, 1F, 1F        
        };
        transformWithKernel(dataKernel);
    }
    
    
    public void transformSchizzo() {
        transformEstraiBordi();
        transformToNegativo();
        
    }
    
    // restituisce una stringa di informazioni sull'immagine corrente
    public String infoImage() {
        String info = "";
        if (mybuffer != null) {
            info = "Informazioni immagine:\n" +
                "\n Nome File: " + fileImage.getName() +
                "\n Dimensioni: " + mybuffer.getWidth() + " x " + mybuffer.getHeight() + " pixel" +
                "\n Lunghezza: " + (fileImage.length() / 1000) + " Kbytes";
        }        
        return info;
    }
    
    // preleva dimensioni immagine
    public Dimension getDimensionImage() {
        return new Dimension(mybuffer.getWidth(), mybuffer.getHeight());
    }
    
    
    // restituisce il buffer immagine corrente
    public BufferedImage getCurrentBufferedImage() {
        return mybuffer;
    }
    
    // restituisce l'oggetto label destinato a contenere l'immagine
    public JLabel getCurrentLabel() {
        return label;
    }
    
    // ridisegna immagine del buffer nell'icona
    public void refreshImage() {
        label.setIcon(new ImageIcon(mybuffer));
        label.validate();
    }
}

// Pannello informazioni immagine
class infoPanel extends JPanel{
    JTextArea txtArea;
    public infoPanel() {
        super();
        // griglia di 1 x 1 = unica cella
        setLayout(new GridLayout(1, 1));
        // crea area testo
        txtArea = new JTextArea();
        // disabilita editazione
        txtArea.setEditable(false);
        txtArea.setFont(new Font("Verdana", Font.PLAIN, 11));
        // inserisce casella di testo in un pannello con barre di scorrimento
        JScrollPane txt = new JScrollPane(txtArea);
        add(txt);
    }
}

class sliderPanel extends JPanel {
    JSlider slider, sliderTransparency, sliderLumin;
    public sliderPanel() {
        super();
        setLayout(new GridLayout(6,1));
        //zoom
        add(new JLabel("Zoom", SwingConstants.CENTER));
        slider = new JSlider();
        add(slider);
        slider.setEnabled(false);
        //trasparenza
        add(new JLabel("Trasparenza", SwingConstants.CENTER));
        sliderTransparency = new JSlider();
        add(sliderTransparency);
        sliderTransparency.setEnabled(false);
        //luminosità
        add(new JLabel("Luminosità", SwingConstants.CENTER));
        sliderLumin = new JSlider();
        add(sliderLumin);
        sliderLumin.setEnabled(false);
    }
}


// il menu del frame principale
class menuDaMaDar implements ActionListener {
    //variabile di istanza
    private myFrame frame;
    // le scelte di menu
    JMenuItem menu1_1, menu1_2, menu1_2a, menu1_3, menu2_1, menu3_1, menu3_2,
              menu3_3, menu3_4, menu3_5, menu3_6, menu3_7, menu3_8, menu3_9,
              menu3_10, menu3_11, menu3_12, menu3_13;
    //costruttore
    public menuDaMaDar(myFrame f) {
        //creazione barra menù
        JMenuBar menuBar = new JMenuBar();
        f.setJMenuBar(menuBar);
        //menu1
        JMenu menu1 = new JMenu("File");
        menu1_1 = menu1.add("Nuovo...");
        menu1_2 = menu1.add("Apri...");
        menu1_2a = menu1.add("Salva...");
        menu1.addSeparator();
        menu1_3 = menu1.add("Esci");
        //menu2
        JMenu menu2 = new JMenu("?");
        menu2_1 = menu2.add("Informazioni...");
        //menu Strumenti
        JMenu menu3 = new JMenu("Strumenti");
        menu3_1 = menu3.add("Negativo");
        menu3_2 = menu3.add("Toni di grigio");
        menu3_3 = menu3.add("Ruota a Dx di 90°");
        menu3_4 = menu3.add("Soglia");
        menu3_5 = menu3.add("Sfocatura");
        menu3_6 = menu3.add("Aumenta Contrasto");
        menu3_7 = menu3.add("Estrai Bordi");
        menu3_8 = menu3.add("Schizzo");
        menu3_9 = menu3.add("Derivata X");
        menu3_10 = menu3.add("Derivata Y");        
        menu3_11 = menu3.add("Rendi Trasparente al 50%");        
        menu3_12 = menu3.add("Luminosita (+15%)");        
        menu3_13 = menu3.add("Luminosita (-15%)");        

        //inserimento menu nella barra del menu
        menuBar.add(menu1);
        menuBar.add(menu3);
        menuBar.add(menu2);
        // ascoltatore degli eventi: questa stessa classe
        menu1_1.addActionListener(this);  menu1_2.addActionListener(this);
        menu1_2a.addActionListener(this); menu1_3.addActionListener(this);
        menu2_1.addActionListener(this);  menu3_1.addActionListener(this);
        menu3_2.addActionListener(this);  menu3_3.addActionListener(this);
        menu3_4.addActionListener(this);  menu3_5.addActionListener(this);
        menu3_6.addActionListener(this);  menu3_7.addActionListener(this);
        menu3_8.addActionListener(this);  menu3_9.addActionListener(this);  
        menu3_10.addActionListener(this); menu3_11.addActionListener(this);
        menu3_12.addActionListener(this); menu3_13.addActionListener(this);
        // passo il frame al fine di controllare i pannelli dagli eventi del menù.
        frame = f;
        
    }
    
    public void actionPerformed(ActionEvent e) {
        imagePanel p = frame.mainPanel.pnlImmagine;
        // Nuovo...
        if (e.getSource().equals(menu1_1)) p.nuovo(100, 100);
        // Apri...
        if (e.getSource().equals(menu1_2)) {
            // apre l'immagine
            frame.mainPanel.pnlImmagine.openImage();
            // setta lo slider
            frame.mainPanel.setSliderBounds();
            // scrive infopanel le informazioni sull'immagine
            frame.mainPanel.writeInfoInToInfoPanel();
        }
        //Salva...
        if (e.getSource().equals(menu1_2a)) p.saveImage();
        // Negativo
        if (e.getSource().equals(menu3_1)) p.transformToNegativo();
        // Toni di grigio
        if (e.getSource().equals(menu3_2)) p.transformToGrigio();
        // Ruota di 90°
        if (e.getSource().equals(menu3_3)) p.transformRuota(Math.PI/2);
        // Soglia
        if (e.getSource().equals(menu3_4)) p.transformSoglia(128);
        // Sfuma
        if (e.getSource().equals(menu3_5)) p.transformSfuma();
        // Esalta Bordi
        if (e.getSource().equals(menu3_6)) p.transformEsaltaBordi();
        // Estrai Bordi
        if (e.getSource().equals(menu3_7)) p.transformEstraiBordi();
        // Schizzo
        if (e.getSource().equals(menu3_8)) p.transformSchizzo();
        // Derivata X
        if (e.getSource().equals(menu3_9)) p.transformDerivataX();
        // Derivata Y
        if (e.getSource().equals(menu3_10)) p.transformDerivataY();    
        // Trasparenza
        if (e.getSource().equals(menu3_11)) p.transformTrasparenza(50);    
        // Luminanza + /-
        if (e.getSource().equals(menu3_12)) p.transformLuminanza(115, true);    
        if (e.getSource().equals(menu3_13)) p.transformLuminanza(85, true);    
        // Informazioni...
        if (e.getSource().equals(menu2_1)) {
            JDialog informazioni = new dialogInfo(frame);
            informazioni.show();
        }
        // Uscita
        if (e.getSource().equals(menu1_3)) System.exit(0);
    }

}

// Filtro per le immagini JPG
class JPGFilter extends FileFilter {
  // file da accettare: jpg o jpeg (oppure sono cartelle)
  public boolean accept(File f) {
    String str = f.getName().toLowerCase();
    return str.endsWith(".jpg")||str.endsWith(".jpeg")||f.isDirectory();
  }
  
  // descrizione del filtro
  public String getDescription() {
    return "Immagine JPG";
  }
  
  public String toString() {
      return "jpg";
  }
}


// Filtro per le immagini GIF
class GIFFilter extends FileFilter {
  // file da accettare: gif (oppure sono cartelle)
  public boolean accept(File f) {
    String str = f.getName().toLowerCase();
    return str.endsWith(".gif")||f.isDirectory();
  }
  
  // descrizione del filtro
  public String getDescription() {
    return "Immagine GIF";
  }
  
  public String toString() {
      return "gif";
  }
}

// Filtro per le immagini PNG
class PNGFilter extends FileFilter {
  // file da accettare: png (oppure sono cartelle)
  public boolean accept(File f) {
    String str = f.getName().toLowerCase();
    return str.endsWith(".png")||f.isDirectory();
  }
  
  // descrizione del filtro
  public String getDescription() {
    return "Immagine PNG";
  }
  
  public String toString() {
      return "png";
  }
}

// Finestra di dialogo
class dialogInfo extends JDialog {
    Dimension dScr = Toolkit.getDefaultToolkit().getScreenSize();
    public dialogInfo(JFrame owner) {
        super(owner, "Finestra Informazioni", true);
        Container contentPane = getContentPane();
        contentPane.add(new JLabel(
            "<html><h2 align=center style='color:red'>Studio dei filtri applicati alle immagini</h2>" +
            "<div align=center style='font-family:Verdana; font-size:10pt'>Programma realizzato da " +
            "Dario Rizzo (<i>Dalubar</i>).", JLabel.CENTER), BorderLayout.CENTER
        );
        //Bottone
        JButton btClose = new JButton("Chiudi");
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createRaisedBevelBorder());
        panel.add(btClose);
        contentPane.add(panel, BorderLayout.SOUTH);
        btClose.addActionListener( new
            ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                }
            }
        );
        // imposta dimensione finestra
        setSize(300, 160);
        setLocation((dScr.width - getSize().width) / 2,
                    (dScr.height - getSize().height) / 2);
        // finestra non ridimensionabile
        setResizable(false);
    }
}

// classe principale
public class provaDaMaDar {
public static void main(String[] args) {
     // applico stile in base alla piattaforma
     try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
     } catch (Exception e) {}
     JFrame f = new myFrame();
     f.show();
  }
}