2011-08-21 62 views
10

我有點習慣於GUI的習慣用法,當我在文本輸入字段中輸入錯誤信息時,氣球會從字段中彈出,並提供有關我出錯/預期輸入的信息。它仍然可見,直到我再次打字。 但現在我找不到任何指向的示例。如何在輸入驗證期間顯示臨時baloon工具提示?

鑑於JTextfield你知道任何庫/代碼,當我的keylistener觸發時會顯示這樣的氣球嗎?

@see http://www.javapractices.com/topic/TopicAction.do?Id=151

+1

相關:http://stackoverflow.com/questions/5852941/popup-messages-for-validation –

回答

11

Balloon Tip是做一個庫:這是所有需要

balloonTip = new BalloonTip(f, "Tooltip msg"); 

!如果你堅持具有它是一個工具提示過:

tooltipBalloon = new BalloonTip(someComponent, "I'm a balloon tooltip!"); 
// Now convert this balloon tip to a tooltip, such that the tooltip shows up after 500 milliseconds and stays visible for 3000 milliseconds 
ToolTipUtils.balloonToToolTip(tooltipBalloon, 500, 3000); 
+0

感謝您的鏈接+1 – mKorbel

+1

真棒圖書館! –

6

詹姆斯Poulson芯片中給出的鏈接可能提供了一個更好的解決方案,但我不得不看到,如果這是可能使用某個DocumentFilter和的JWindow一些簡單的Java代碼。以下是一種可能的方法:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Point; 
import java.awt.Window; 
import javax.swing.*; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.PlainDocument; 

public class InfoBalloon extends JPanel { 
    private static final int PREF_WIDTH = 400; 
    private static final int PREF_HEIGHT = 300; 
    private static final String REGEX_TEST = "\\d*"; 
    private static final String ERROR_TEXT = "Please only add numbers to the text field"; 
    private JTextField textField = new JTextField(10); 
    private JWindow errorWindow; 


    public InfoBalloon() { 
     add(new JLabel("Please Enter Number")); 
     add(textField); 

     ((PlainDocument)textField.getDocument()).setDocumentFilter(new MyNumberDocFilter()); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_WIDTH, PREF_HEIGHT); 
    } 

    private void showErrorWin() {  
     if (errorWindow == null) { 
     JLabel errorLabel = new JLabel(ERROR_TEXT); 
     Window topLevelWin = SwingUtilities.getWindowAncestor(this); 
     errorWindow = new JWindow(topLevelWin); 
     JPanel contentPane = (JPanel) errorWindow.getContentPane(); 
     contentPane.add(errorLabel); 
     contentPane.setBackground(Color.white); 
     contentPane.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); 
     errorWindow.pack(); 
     } 

     Point loc = textField.getLocationOnScreen(); 
     errorWindow.setLocation(loc.x + 20, loc.y + 30); 
     errorWindow.setVisible(true); 
    } 

    private boolean textOK(String text) { 
     if (text.matches(REGEX_TEST)) { 
     return true; 
     } 
     return false; 
    } 

    private class MyNumberDocFilter extends DocumentFilter { 
     @Override 
     public void insertString(FilterBypass fb, int offset, String string, 
       AttributeSet attr) throws BadLocationException { 
     if (textOK(string)) { 
      super.insertString(fb, offset, string, attr); 
      if (errorWindow != null && errorWindow.isVisible()) { 
       errorWindow.setVisible(false); 
      } 
     } else { 
      showErrorWin(); 
     } 
     } 

     @Override 
     public void replace(FilterBypass fb, int offset, int length, String text, 
       AttributeSet attrs) throws BadLocationException { 
     if (textOK(text)) { 
      super.replace(fb, offset, length, text, attrs); 
      if (errorWindow != null && errorWindow.isVisible()) { 
       errorWindow.setVisible(false); 
      } 
     } else { 
      showErrorWin(); 
     } 
     } 

     @Override 
     public void remove(FilterBypass fb, int offset, int length) 
       throws BadLocationException { 
     super.remove(fb, offset, length); 
     if (errorWindow != null && errorWindow.isVisible()) { 
      errorWindow.setVisible(false); 
     } 
     } 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("Info Balloon"); 
     frame.getContentPane().add(new InfoBalloon()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowUI(); 
     } 
     }); 
    } 
} 

建議性的或破壞性的批評是最受歡迎的!

+1

不錯。我唯一會改變生產代碼的是我會確保JWindow通過使JWindow成爲一個ComponentAdapter(覆蓋'componentMoved')向JFrame註冊來保持其相對於固定的JFrame的相對位置。 – toto2

+0

@ toto2:感謝您的推薦! –

+0

phaaa您的窗口可能伸出父母:-) +1 – mKorbel