2012-04-15 14 views
8

Estoy intentando desarrollar una característica similar a Toast (Android) en mi aplicación Swing. Como independiente, funciona perfectamente. Pero cuando se integra en la aplicación, plantea problemas.Android como Toast en Swing

el archivo de clase es:

import java.awt.*; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.awt.geom.RoundRectangle2D; 
import javax.swing.ImageIcon; 
import javax.swing.JDialog; 
import javax.swing.JLabel; 
import net.mindcrew.utils.LayoutHelper.Packer; 

public class Toast extends JDialog { 

    String text; 

    public Toast(String text) { 
     this.text = text; 
     initComponents(); 
    } 

    private void initComponents(){ 
     setLayout(new GridBagLayout()); 
     addComponentListener(new ComponentAdapter() { 
      // Give the window an rounded rect shape. LOOKS GOOD 
      // If the window is resized, the shape is recalculated here. 
      @Override 
      public void componentResized(ComponentEvent e) { 
       setShape(new RoundRectangle2D.Double(0,0,getWidth(),getHeight(),50,50)); 
      } 
     }); 

     setUndecorated(true); 
     setSize(300,100); 
     setLocationRelativeTo(null); 
     getContentPane().setBackground(Color.BLACK); 

     // Determine what the GraphicsDevice can support. 
     GraphicsEnvironment ge = 
      GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     GraphicsDevice gd = ge.getDefaultScreenDevice(); 
     final boolean isTranslucencySupported = 
      gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT); 

     //If shaped windows aren't supported, exit. 
     if (!gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)) { 
      System.err.println("Shaped windows are not supported"); 
     } 

     //If translucent windows aren't supported, 
     //create an opaque window. 
     if (!isTranslucencySupported) { 
      System.out.println(
       "Translucency is not supported, creating an opaque window"); 
     } 

     // Set the window to 70% translucency, if supported. 
     if (isTranslucencySupported) { 
      setOpacity(0.9f); 
     } 

     ImageIcon loading = new ImageIcon(Toast.class.getResource("/net/mindcrew/utils/userinterface/resources/loading-photo.gif")); 

     JLabel label = new JLabel(text); 
     label.setForeground(Color.WHITE); 
     label.setIcon(loading); 
     Packer packer = new Packer(this); 
     packer.pack(label).fillboth().west().inset(0, 50, 0, 20); 
    } 

    public static Toast showDailog(String textToDisplay){ 
     final Toast toast = new Toast(textToDisplay); 
     // Display the window. 
     Thread thread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       toast.setVisible(true); 
      } 
     }); 
     thread.start(); 
     return toast; 
    } 

    @Override 
    public void hide(){ 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       setVisible(false); 
       dispose(); 
      } 
     }); 
    } 

    public static void main(String... args){ 
     Toast toast = Toast.showDailog("Display"); 
     try{ 
      Thread.sleep(5000); 
     } 
     catch (Exception e){} 
     toast.hide(); 
    } 

} 

Puede haber algunos errores de implementación, pero esto es lo básico.

Esto funciona bien. Pero cuando trato de ponerlo en el camino de una operación intensiva en recursos, se dispara. Como en la animación GIF no aparece, lo que creo implica que está estancado.

El uso es:

Toast toast = Toast.showDailog("Generating PDF"); 

//resource intensive operation. Takes about 3-5seconds to execute 

    toast.hide(); 

Para añadir a mi miseria, incluso después de la "tostada" se ha dispuesto, la aplicación se está volviendo terriblemente lento. Estoy bastante seguro de que la ralentización no se debe a la operación en cuestión, ya que está funcionando perfectamente si elimino el "Toast".

¿Alguien puede indicar qué está mal aquí?

Fui a través de this question. Pero las cosas allí son demasiado complicadas de lo que estoy buscando. Lo que estoy buscando es un diálogo simple. No es un cuadro completo que necesita acomodar varios componentes.

+0

* Saludos Binaek Sarkar Fundación HTTC: //www.foundation.....in/* No incluya sigs. o tarjetas de visita en publicaciones. Si la información es importante para usted, colóquela en [su perfil] (http://stackoverflow.com/users/951243/binaek-sarkar). –

+0

¡Uy! Lo recordará la próxima vez. Gracias por señalar. –

+0

Lo eliminé antes de comentar. –

Respuesta

0

¿Puede ser JOptionPane es lo que necesitas?

+0

No realmente. Estoy tratando de crear un cuadro de diálogo personalizado. Lo que estoy tratando de encontrar es una versión de escritorio de Android Toast y/o iOS Growl. –

0

Creo que se puede resolver su problema por no reemplazando el método ocultar en Dialog y modificar el método showDialog a ser algo como esto:

public static void showDailog(String textToDisplay){ 
    final Toast toast = new Toast(textToDisplay); 
    // Display the window. 
    Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try{ 
       toast.setVisible(true); 
       Thread.sleep(5000); 
       toast.setVisible(false); 
       toast.dispose(); 
      } 
      catch(Exception ex){ 
       ex.printStackTrace(); 
      } 
     } 
    }); 
    thread.start(); 
} 
0

he hecho algunos cambios que funciona para mí, espero que esto útiles Android like Toast using Java Swing

+1

Si es posible, complete las respuestas por su cuenta, los enlaces externos están bien, pero una respuesta debería poder sobrevivir sin ella –

6

probar este código para la tostada:

public class Test extends JFrame { 

    private JPanel contentPane; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        Test frame = new Test(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public Test() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 450, 300); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     contentPane.setLayout(new BorderLayout(0, 0)); 
     setContentPane(contentPane); 

     JButton btnTestToast = new JButton("Test Toast"); 
     btnTestToast.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       ToastMessage toastMessage = new ToastMessage("Sample text to toast ",3000); 
       toastMessage.setVisible(true); 
      } 
     }); 
     contentPane.add(btnTestToast, BorderLayout.SOUTH); 
    } 

} 

public class ToastMessage extends JDialog { 
    int miliseconds; 
    public ToastMessage(String toastString, int time) { 
     this.miliseconds = time; 
     setUndecorated(true); 
     getContentPane().setLayout(new BorderLayout(0, 0)); 

     JPanel panel = new JPanel(); 
     panel.setBackground(Color.GRAY); 
     panel.setBorder(new LineBorder(Color.LIGHT_GRAY, 2)); 
     getContentPane().add(panel, BorderLayout.CENTER); 

     JLabel toastLabel = new JLabel(""); 
     toastLabel.setText(toastString); 
     toastLabel.setFont(new Font("Dialog", Font.BOLD, 12)); 
     toastLabel.setForeground(Color.WHITE); 

     setBounds(100, 100, toastLabel.getPreferredSize().width+20, 31); 


     setAlwaysOnTop(true); 
     Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 
     int y = dim.height/2-getSize().height/2; 
     int half = y/2; 
     setLocation(dim.width/2-getSize().width/2, y+half); 
     panel.add(toastLabel); 
     setVisible(false); 

     new Thread(){ 
      public void run() { 
       try { 
        Thread.sleep(miliseconds); 
        dispose(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }.start(); 
    } 
} 
1

que implemen es similar a la información sobre herramientas. Está probado y funciona.

import java.awt.Color; 
import java.awt.Label; 
import java.awt.Point; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JComponent; 
import javax.swing.Popup; 
import javax.swing.PopupFactory; 

public class Toast { 

    private final JComponent component; 
    private Point location; 
    private final String message; 
    private long duration; //in millisecond 

    public Toast(JComponent comp, Point toastLocation, String msg, long forDuration) { 
     this.component = comp; 
     this.location = toastLocation; 
     this.message = msg; 
     this.duration = forDuration; 

     if(this.component != null) 
     { 

      if(this.location == null) 
      { 
       this.location = component.getLocationOnScreen(); 
      } 

      new Thread(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        Popup view = null; 
        try 
        { 
         Label tip = new Label(message); 
         tip.setForeground(Color.red); 
         tip.setBackground(Color.white); 
         view = PopupFactory.getSharedInstance().getPopup(component, tip , location.x + 30, location.y + component.getHeight() + 5); 
         view.show(); 
         Thread.sleep(duration); 
        } catch (InterruptedException ex) 
        { 
         Logger.getLogger(Toast.class.getName()).log(Level.SEVERE, null, ex); 
        } 
        finally 
        { 
         view.hide(); 
        } 
       } 
      }).start(); 
     } 
    } 



    public static void showToast(JComponent component, String message) 
    { 
     new Toast(component, null, message, 2000/*Default 2 Sec*/); 
    } 

    public static void showToast(JComponent component, String message, Point location, long forDuration) 
    { 
     new Toast(component, location, message, forDuration); 
    } 
} 

Para utilizar esta clase sólo tiene que llamar showToast()

0

Puede utilizar un auto-redondeada disponer JFrame como superposición que se posiciona con relación a la ventana de aplicación. Al desvanecerlo, parece un Toast de Android. Aquí está el código:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.RoundRectangle2D; 

class Toast extends JFrame { 

    private final float MAX_OPACITY = 0.8f; 
    private final float OPACITY_INCREMENT = 0.05f; 
    private final int FADE_REFRESH_RATE = 20; 

    private final int WINDOW_RADIUS = 15; 
    private final int CHARACTER_LENGTH_MULTIPLIER = 9; 
    private final int DISTANCE_FROM_PARENT_BOTTOM = 100; 


    public Toast(JFrame owner, String toastText) { 
     setTitle("Transparent JFrame Demo"); 
     setLayout(new GridBagLayout()); 

     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setUndecorated(true); 
     setFocusableWindowState(false); 

     setOpacity(0.4f); 


     // setup the toast lable 
     JLabel b1 = new JLabel(toastText); 
     b1.setForeground(Color.WHITE); 
     b1.setOpaque(false); 
     add(b1); 

     setSize(toastText.length() * CHARACTER_LENGTH_MULTIPLIER, 50); 

     int x = (int) (owner.getLocation().getX() + (owner.getWidth()/2)); 
     int y = (int) (owner.getLocation().getY() + owner.getHeight() - DISTANCE_FROM_PARENT_BOTTOM); 
     setLocation(new Point(x, y)); 


     // configure frame 
     setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), WINDOW_RADIUS, WINDOW_RADIUS)); 
     getContentPane().setBackground(new Color(0, 0, 0, 170)); 

    } 


    public void fadeIn() { 
     setOpacity(0); 
     setVisible(true); 

     final Timer timer = new Timer(FADE_REFRESH_RATE, null); 
     timer.setRepeats(true); 
     timer.addActionListener(new ActionListener() { 
      private float opacity = 0; 


      @Override 
      public void actionPerformed(ActionEvent e) { 
       opacity += OPACITY_INCREMENT; 
       setOpacity(Math.min(opacity, MAX_OPACITY)); 
       if (opacity >= MAX_OPACITY) { 
        timer.stop(); 
       } 
      } 
     }); 

     timer.start(); 
    } 


    public void fadeOut() { 
     final Timer timer = new Timer(FADE_REFRESH_RATE, null); 
     timer.setRepeats(true); 
     timer.addActionListener(new ActionListener() { 
      private float opacity = MAX_OPACITY; 


      @Override 
      public void actionPerformed(ActionEvent e) { 
       opacity -= OPACITY_INCREMENT; 
       setOpacity(Math.max(opacity, 0)); 
       if (opacity <= 0) { 
        timer.stop(); 
        setVisible(false); 
        dispose(); 
       } 
      } 
     }); 

     setOpacity(MAX_OPACITY); 
     timer.start(); 
    } 


    public static void makeToast(final JFrame owner, final String toastText, final int durationSec) { 


     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Toast toastFrame = new Toast(owner, toastText); 
        toastFrame.fadeIn(); 
        Thread.sleep(durationSec * 1000); 
        toastFrame.fadeOut(); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }).start(); 


    } 


    public static void main(String args[]) { 
     final JFrame frame = new JFrame("Cloud Tester"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


     JPanel jPanel = new JPanel(); 
     jPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); 
     JButton toastButton = new JButton("show toast"); 
     jPanel.add(toastButton); 

     toastButton.addActionListener(new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       Toast.makeToast(frame, "a toast!", 3); 
      } 
     }); 


     frame.add(jPanel); 
     frame.setSize(800, 600); 
     frame.setVisible(true); 
    } 
} 
Cuestiones relacionadas