package keepalive; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; import javax.swing.text.PlainDocument; public class PollIntervalDialog extends JDialog { @SuppressWarnings("compatibility:-4837128555563361740") private static final long serialVersionUID = 931087028121895189L; private JTextField textField; private JOptionPane optionPane; private Integer pollInterval; // minimal value for poll interval in seconds private final Integer minPollInterval = 60; // maximal value for poll interval in seconds private final Integer maxPollInterval = 43200; //12h private static final String OK_STRING = "OK"; private static final String CANCEL_STRING = "Cancel"; public PollIntervalDialog(JFrame parent) { super(parent, true); setTitle("keepalive"); initDialog(); pack(); } private void initDialog() { textField = new JTextField(20); PlainDocument doc = (PlainDocument) textField.getDocument(); doc.setDocumentFilter(new NumberFilter()); Object[] controls = { "Specify poll interval (in seconds):", textField }; Object[] options = { OK_STRING, CANCEL_STRING }; optionPane = new JOptionPane(controls, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, options[0]); setContentPane(optionPane); addComponentListener(new ComponentAdapter() { @Override public void componentShown(ComponentEvent ce) { textField.requestFocusInWindow(); } }); optionPane.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent e) { if (isVisible() && JOptionPane.VALUE_PROPERTY.equals(e.getPropertyName())) { Object value = optionPane.getValue(); if (value == JOptionPane.UNINITIALIZED_VALUE) { return; } switch (value.toString()) { case OK_STRING: String v = textField.getText(); if (checkValue(v)) { pollInterval = Integer.parseInt(v, 10); setVisible(false); } else { //to let PropertyChangeEvent fire next time the user presses button optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE); } break; case CANCEL_STRING: pollInterval = null; setVisible(false); break; } } } }); } private boolean checkValue(String txt) { if (txt != null && txt.length() > 0) { //avoid parsing possibly very long string into integer if (txt.length() <= maxPollInterval.toString().length()) { try { Integer value = Integer.parseInt(txt, 10); if (value >= minPollInterval && value <= maxPollInterval) { return true; } } catch (NumberFormatException e) { } } } JOptionPane.showMessageDialog(this, "Please specify value in range " + minPollInterval + " - " + maxPollInterval, "Wrong value", JOptionPane.ERROR_MESSAGE); return false; } public Integer getPollInterval() { return pollInterval; } } class NumberFilter extends DocumentFilter { private static final Pattern pattern = Pattern.compile("^[0-9]+$"); @Override public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { if (isNumber(text)) super.replace(fb, offset, length, text, attrs); else { java.awt.Toolkit.getDefaultToolkit().beep(); } } @Override public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { if (isNumber(text)) { super.insertString(fb, offset, text, attr); } else { java.awt.Toolkit.getDefaultToolkit().beep(); } } private static boolean isNumber(String s) { Matcher m = pattern.matcher(s); return m.matches(); } }