2012-04-15 129 views
8

我想在我的Swing應用程序中開發吐司(Android)功能。作爲一個獨立的,它的工作完美。但是,當將其整合到應用程序中時,其存在問題。Android像鞦韆吐司

類文件是:

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(); 
    } 

} 

可能有一些實施的故障,但是這是基本的東西。

這效果很好。但是當我試圖用資源密集型運營的方式來解決它時,它會絆倒。正如在GIF動畫中沒有顯示出來的那樣,我認爲這意味着它的這種停頓。

的使用方法是:

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

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

    toast.hide(); 

要添加到我的苦難,「吐司」已被釋放後,也將應用變得可怕緩慢。我相當肯定,減速並不是因爲有問題的操作,因爲如果我放棄了「吐司」,它的工作是完美的。

請問有人可以指出這裏有什麼錯?我想通過this question。但那裏的事情遠比我所尋找的要複雜得多。我正在尋找的是一個簡單的對話框。不是一個需要容納多個組件的完整吹制框架。

+0

*問候 Binaek薩卡 基金會 httc://www.foundation.....in/*不包括SIGS。或在帖子中呼叫卡片。如果這些信息對您很重要,請將其放入[您的個人資料](http://stackoverflow.com/users/951243/binaek-sarkar)。 – 2012-04-15 10:35:39

+0

糟糕!下次會記住它。感謝您指出。 – 2012-04-15 10:37:13

+0

我在評論前刪除了它。 – 2012-04-15 10:38:07

回答

0

可能是JOptionPane你需要什麼?

+0

不是。我正在嘗試製作一個自定義對話框。我試圖想出的是Android Toast和/或iOS Growl的桌面版本。 – 2012-04-15 18:39:58

0

我覺得你可以不覆蓋在Dialog隱藏方法解決您的問題,並修改showDialog方法是這樣的:

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

我已經做了一些變化,對我的作品,希望這將樂於助人 Android like Toast using Java Swing

+1

如果可能的話自己完成答案,外部鏈接是好的,但答案應該能夠沒有它的生存 – 2013-09-26 12:13:07

6

試試這個代碼敬酒:

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

我implemen將它與tooltip類似。它經過測試和工作。

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); 
    } 
} 

要使用這個類,你只需要調用showToast()

0

您可以使用一個圓形的自配置的JFrame作爲相對於定位到你的應用程序窗口覆蓋。通過淡出它看起來像一個Android的吐司。下面的代碼:

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); 
    } 
}