2011-08-21 11 views
10

Sono un po 'abituato all'idioma della GUI in cui quando digito qualcosa di sbagliato in un campo di input di testo viene visualizzato un fumetto dal campo con informazioni su ciò che ho ricevuto input errato/previsto. Rimane visibile finché non digito di nuovo. Ma ora non sono riuscito a trovare alcun esempio a cui puntare.Come visualizzare un suggerimento baloon temporaneo durante la convalida dell'input?

Dato un JTextfield conosci qualche libreria/codice che visualizzerebbe un fumetto quando attivato dal mio keylistener?

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

+1

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

risposta

11

Balloon Tip è una libreria che fa questo:

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

che era tutto necessario! Se si insiste su un avere che si tratti di un tooltip troppo:

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

grazie per il collegamento +1 – mKorbel

+1

Libreria impressionante! –

6

Il collegamento dato da James Poulson probabilmente fornisce una soluzione migliore, ma ho dovuto vedere se questo fosse possibile con qualche semplice codice Java utilizzando un DocumentFilter e JWindow. Ecco un possibile modo per farlo:

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

critica costruttiva o distruttiva è il benvenuto!

+1

Abbastanza bene. L'unica cosa che cambierei per il codice di produzione è che mi assicurerei che la JWindow mantenga fissa la sua posizione relativa a JFrame rendendo JWindow un ComponentAdapter (che sovrascrive 'componentMoved') registrato con JFrame. – toto2

+0

@ toto2: grazie per la segnalazione! –

+0

phaaa probabilmente la tua finestra si sporge dal genitore :-) +1 – mKorbel

Problemi correlati