Reputation: 31
I have a JFormattedTextField with a DateFormat. the format is "ddMMyy". This format allows quick input.On focus lost i want the text in the field to change to LocalDate as that is easier to read:
Input: "200295". converting to LocalDate with getValue() gives the LocalDate of 20. February 1995. this is all well and good, to text that is "1995-02-25" (LocalDate.toString()
).
When the field loses focus, i want the text displayed in the field to change into the LocalDate.toString()
without the actual value of the field to change from 200295/ 20. feb 1995.
Is there any way to make a text overlay the field instead of changing the value/text of it?
sscce of what i have been thinking so far:
main class:
public class FormatDateTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TheFrame();
}
});
}
}
Frame class:
public class TheFrame extends JFrame{
JPanel panel;
JPanel textPanel;
JFormattedTextField dateField;
JButton button;
JTextArea textArea;
DateFormat format;
public TheFrame() {
button = new JButton("click");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
//temporarily crates a date to be converted.
Date date = (Date) dateField.getValue();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
// sends the different values of the textarea
textArea.append("The value: " + dateField.getValue() + "\n");
textArea.append("the Date: " + date.toString() + "\n");
textArea.append("the LocalDate: " + localDate.toString() + "\n");
}
});
//Sets the text to the localDate for prettyness
button.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent arg0) {
Date date = (Date) dateField.getValue();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
dateField.setText(localDate.toString());
}
@Override
public void focusGained(FocusEvent arg0) {
dateField.setText("");
}
});
textArea = new JTextArea();
panel = new JPanel();
textPanel = new JPanel();
panel.setLayout(new BorderLayout());
textPanel.setLayout(new BorderLayout());
//datefield and format
format = new SimpleDateFormat("ddMMyy");
dateField = new JFormattedTextField(format);
textPanel.add(textArea,BorderLayout.CENTER);
panel.add(dateField,BorderLayout.NORTH);
panel.add(button, BorderLayout.CENTER);
add(panel,BorderLayout.NORTH);
add(textPanel,BorderLayout.CENTER);
pack();
setSize(400, 300);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
Upvotes: 0
Views: 568
Reputation: 2739
Use a JPanel
with a CardLayout
. Put two components in it - the input field and the properly formatted one (I assume a JTextField
would do).
On focus to any of them, bring the formatted field to front (using methods on the CardLayout
), and let the user input her data. On focus lost, process the value (remember to deal with errors!) and, if parsing goes well, put the properly formatted value in the JTextField
and bring it to the front.
-- UPDATE based on remark --
Lightweight solution: Use a JLabel
instead of a JTextField
for the formatted part. Just remember to call setFocusable(true)
.
Even Lighter: Subclass JTextField
. Override paintComponent
such that: a) When the component is focused, delegate the drawing to super
. b) When not focused, paint the properly formatted text yourself.
Upvotes: 1