How to create a mask for Jformattedtextfield?

Asked

Viewed 590 times

4

I am making a program that simulates the Turing machine, and the user fills in a form with the states in this way {q0,q1,q2}.

But I want to create mask that the user type only q0q1q2 and the value is formatted like this {q0,q1} and make it possible to enter one or more ex states: {q0} or {q0,q1,q2}.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package MaquinaTuring;

public class Maquina extends javax.swing.JFrame {

    /**
     * Creates new form Maquina
     */
    public Maquina() {
        initComponents();
    }

    String entrada;
    String [] estados;

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jFormattedTextField1 = new javax.swing.JFormattedTextField();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jLabel1.setText("Máquina de Turing");

        jLabel2.setText("Informe os Estados (Q):");

        try {
            jFormattedTextField1.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("{#,#}")));
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }

        jButton1.setText("Verificar");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(119, 119, 119)
                        .addComponent(jLabel1))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(27, 27, 27)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jFormattedTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(157, 157, 157)
                        .addComponent(jButton1)))
                .addContainerGap(133, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(34, 34, 34)
                .addComponent(jLabel1)
                .addGap(23, 23, 23)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jFormattedTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 58, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addGap(95, 95, 95))
        );

        pack();
    }// </editor-fold>                        

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

        entrada = jFormattedTextField1.getText();
        estados = entrada.split(",");

        if (estados[0].isEmpty() == false) {
            estados[0] = estados[0].replace("{", "");
            estados[estados.length - 1] = estados[estados.length - 1].replace("}", "");
        }

        for (int i = 0; i < estados.length; i++) {
            System.out.println("Estados " + i + " :"+ estados[i]);
        }
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Maquina.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Maquina.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Maquina.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Maquina.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Maquina().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JFormattedTextField jFormattedTextField1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration                   
}
  • What kind of limitation do you want to do? Only the letter "q" followed by any number, or specific numbers? How many minimum and maximum characters in the field?

  • Receive q0q1q2 and format like this {Q0,Q1,Q2}. At least 1 state like this: {Q0} and at most 10 like {Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,10}

  • Only pairs of letter q and a digit from 0 to 10?

  • This only pairs but the letter must be followed by the number.

  • Can’t it be qXX where XX is a pair of numbers like 01 to 10? This makes it easy enough to treat and limit the field.

  • Yes, it can be so.

Show 1 more comment

1 answer

2


One way I was able to do this is by applying regular expression to whatever is typed in a JTextField, so that only states that are valid are redeemed({q0,q1,q2,q3,...q10}) in format qXX, removing everything else. Every time the button is pressed, it will format the states by inserting comma between them and two keys ({}) at the beginning and at the end.

Take the example:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class Maquina3 extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private JPanel panelNorth;
    private JTextField textField;
    private JPanel panelSouth;
    private JButton btnFormatar;

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new Maquina3().setVisible(true);
        });
    }

    public Maquina3() {
        initComponents();
        pack();
        setLocationRelativeTo(null);
    }

    private void initComponents() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(400, 250));
        this.contentPane = new JPanel(new BorderLayout(0, 0));
        this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(this.contentPane);

        this.panelNorth = new JPanel();
        this.contentPane.add(this.panelNorth, BorderLayout.NORTH);

        this.panelSouth = new JPanel();
        this.contentPane.add(this.panelSouth, BorderLayout.SOUTH);

        this.textField = new JTextField();
        this.textField.setColumns(15);
        this.panelNorth.add(this.textField);

        this.btnFormatar = new JButton("Formatar");
        btnFormatar.addActionListener(e -> {

            String text = textField.getText();

            if (text == null | text.length() == 0)
                return;

            String regex = "([Qq]{1}(0[1-9]|10))";
            StringBuilder builder =  new StringBuilder();

            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(text);

            while (m.find()) {

                builder.append(builder.length() == 0 ? "" : ",");
                builder.append(m.group());
            }
            builder.insert(0, "{");
            builder.append("}");

            textField.setText(builder.toString().toLowerCase());
        });

        this.panelSouth.add(this.btnFormatar);
    }
}

A regex ([Qq]{1}(0[1-9]|10)) will validate only the parts of the text that are in the format qXX where XX is between 01 and 10. Then while, I am concatenating all the found states and separating them with a comma. The ternary condition is so that the comma is only added if the Uilder is not empty, so that there is no comma left at the beginning as it was occurring in the previous edition of this answer.

Finally, I added the keys at the beginning and end of the Builder and convert it to String when displaying it in the field, converting it to the lower box.

See working:

inserir a descrição da imagem aqui

  • Thanks for the help.

  • @Ffagundes :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.