You want to change at runtime the field mask, only the install
apparently does not work, but according to that answer, you need to change by the call of setFormatterFactory()
, where necessary. In your example, I would suggest changing to JRadioButton
to avoid risk of conflict of masks.
You create a group, add the radiobuttons on it, this way, you can only select one item at a time, avoiding the problem mentioned in the previous paragraph.
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(radioButtonCPF);
radioGroup.add(radioButtonCNPJ);
It is also interesting to create the masks before wearing them, so that the treatment of the exception of the ParseException
occur only once.
private MaskFormatter CNPJMask;
private MaskFormatter CPFMask;
//...
try {
CNPJMask = new MaskFormatter("##.###.###/####-##");
CPFMask = new MaskFormatter("###.###.###-##");
} catch (ParseException ex) {
ex.printStackTrace();
}
Then just add one ItemListener
in each RadioButton
, and within the intemStateChanged
, check if he’s been checked:
radioButtonCPF.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
fmtField.setValue(null);
fmtField.setFormatterFactory(new DefaultFormatterFactory(CPFMask));
}
}
});
radioButtonCNPJ.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
fmtField.setValue(null);
fmtField.setFormatterFactory(new DefaultFormatterFactory(CNPJMask));
}
}
});
The fmtField.setValue(null);
need to be called before applying the mask, because if you have any content in the field, the exchange is not performed. The consequence of this is that each time the exchange is made, what was typed will be lost.
You can improve, but the above is already well simplified.
Here’s an executable example of the masking app if you want to see it working before you change your code:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.text.ParseException;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EmptyBorder;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.MaskFormatter;
public class ChoiceMaskTextFormattedFieldTest extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JFormattedTextField fmtField;
private JRadioButton radioButtonCNPJ;
private JRadioButton radioButtonCPF;
private MaskFormatter CNPJMask;
private MaskFormatter CPFMask;
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new ChoiceMaskTextFormattedFieldTest().setVisible(true);
});
}
public ChoiceMaskTextFormattedFieldTest() {
initComponents();
}
public void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(190, 250));
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
fmtField = new JFormattedTextField();
radioButtonCPF = new JRadioButton();
radioButtonCNPJ = new JRadioButton();
radioButtonCPF.setText("CPF");
radioButtonCNPJ.setText("CNPJ");
// adiciona os radiobuttons no groupbutton
// pra que apenas um seja selecionavel
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(radioButtonCPF);
radioGroup.add(radioButtonCNPJ);
// cria as mascaras e já a deixa pronta pra uso
try {
CNPJMask = new MaskFormatter("##.###.###/####-##");
CPFMask = new MaskFormatter("###.###.###-##");
} catch (ParseException ex) {
ex.printStackTrace();
}
// adiciona um listener aos radiobuttons
radioButtonCPF.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
fmtField.setValue(null);
fmtField.setFormatterFactory(new DefaultFormatterFactory(CPFMask));
}
}
});
radioButtonCNPJ.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
fmtField.setValue(null);
fmtField.setFormatterFactory(new DefaultFormatterFactory(CNPJMask));
}
}
});
contentPane.add(fmtField);
contentPane.add(Box.createVerticalStrut(30));
contentPane.add(radioButtonCPF);
contentPane.add(radioButtonCNPJ);
contentPane.add(Box.createVerticalStrut(100));
pack();
}
}
No. It’s one mask at a time in a field, unless you create your own mask class, replacing the one already ready in the API. As a less complicated alternative, you can control which mask to apply using another component, such as a checkbox or togglebuton to change the mask to one or the other.
– user28595
The legal.. would have some example?
– Valdecir
Do you already have the CPF and CNPJ masks and your screen with the text field ready? Preparing a response explaining how to make these masks and how to change between them will make the response complex. Add what you’ve done so far to the question, so the problem gets more specific.
– user28595