2011-08-21 20 views
10

Estoy algo acostumbrado a la expresión gráfica de GUI donde cuando escribo algo incorrecto en un campo de entrada de texto, aparece un globo del campo con información sobre lo que obtuve entrada incorrecta/esperada. Permanece visible hasta que vuelva a escribir. Pero ahora no pude encontrar ningún ejemplo para señalar.¿Cómo se muestra una información de herramienta temporal de baloon durante la validación de entrada?

Dado un JTextfield, ¿sabe de alguna biblioteca/código que muestre un globo así cuando lo active mi keylistener?

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

+1

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

Respuesta

11

Balloon Tip es una biblioteca que hace eso:

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

eso era todo lo necesario! Si usted insiste en un teniendo que ser un texto de ayuda demasiado:

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

gracias por el enlace +1 – mKorbel

+1

biblioteca impresionante! –

6

El enlace dado por James Poulson, probablemente, proporciona una mejor solución, pero tenía que ver si esto fuera posible con un poco de código Java simple usando un DocumentFilter y una JWindow. Aquí hay una forma posible de hacerlo:

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

¡Crítica constructiva o destructiva es bienvenida!

+1

Bastante bueno. Lo único que cambiaría por el código de producción es que me aseguraría de que JWindow mantenga su posición relativa al JFrame corregido haciendo que JWindow sea un ComponentAdapter (anulando 'componentMoved') registrado con el JFrame. – toto2

+0

@ toto2: gracias por la recomendación! –

+0

phaaa su ventana probablemente sobresalga del padre :-) +1 – mKorbel

Cuestiones relacionadas