JTextField требует от меня, чтобы он сфокусировался во второй раз, прежде чем делать соответствующие обновления
В моем проекте у меня есть JTextField
для дат, которые будут введены в. У меня есть InputVerifier
чтобы убедиться, что введена правильная информация, а также поработать с ней. Одна из вещей, которые мне нужны, это получить DAY_OF_WEEK
от введенной даты. Я делаю это с
Calendar calTest = Calendar.getInstance();
calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);
Затем я печатаю его на экране, независимо от того, какая дата введена, показанное число 4
но когда я щелкаю вне поля и возвращаюсь без внесения изменений, правильный номер выводится на экран. Я не могу понять, почему это? Особенно, когда дата в строковой форме печатается правильно сразу после того, как поле теряет фокус. Ниже приведен метод, где это происходит:
private void updatePrimer(String dateString) {
Calendar calTest = Calendar.getInstance();
calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);
try {
primer = simpleFormat.parse(dateString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(day);
shortString = shortFormat.format(primer);
System.out.println(shortString);
labelTrip = true;
stringTrip = dateString;
updateLabels(labelTrip, stringTrip);
}
Вот небольшая исполняемая программа, которую я использовал в основном как песочницу:РЕДАКТИРОВАТЬ Это всего лишь программа "песочницы", которую я использовал перед внедрением в свою основную программу, чтобы я мог протестировать в основном функциональность. Конечный результат того, что мне нужно, это иметь JTextField
взяв строку, а затем отформатируйте ее в дату в формате MM/dd/yyyy
, Используя эту дату, JLabel
обновляется с той же датой, но в формате MM/dd
, Кроме того, JLabel
рядом с ним будет обновляться дата минус один день предыдущей даты, а затем то же самое дело с оставшейся JLabel. Изменение цвета было использовано, чтобы помочь мне визуализировать порядок операций программы. Я только что добавил текстовую область, чтобы щелкнуть что-то, чтобы изменить фокус. Кнопка просто печатает дату, введенную в JTextField
Важная вещь, и что здесь под вопросом, почему в updatePrimer(String dateString)
правильный день недели печатается правильно только во второй раз, когда JTextField фокусируется
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.MaskFormatter;
public class Hello implements ActionListener{
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private Date endingDate = new Date();
private Date primer = new Date();
private String endingString = null;
private SimpleDateFormat simpleFormat = new SimpleDateFormat("MM/dd/yyyy");
private SimpleDateFormat shortFormat = new SimpleDateFormat("MM/dd");
private JFormattedTextField weekEndingData = null;
private JLabel dateData[] = new JLabel[3];
private JTextArea ta = new JTextArea(20, 10);
private JButton b = new JButton("click");
private String shortString = null;
private boolean labelTrip = false;
private String stringTrip = null;
private Calendar cal = Calendar.getInstance();
private Color blank = Color.LIGHT_GRAY;
public Hello() {
b.addActionListener(this);
weekEndingData = createFormattedTextField();
simpleFormat.setLenient(false);
panel.add(weekEndingData);
for (int i=0; i<3; i++){
dateData[i] = new JLabel("12/34");
dateData[i].setForeground(blank);
panel.add(dateData[i]);
}
panel.add(ta);
panel.add(b);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Hello();
}
});
System.out.println("Hello, World");
}
private JFormattedTextField createFormattedTextField() {
JFormattedTextField formattedField = null;
try {
MaskFormatter dateMask = new MaskFormatter("##/##/####");
formattedField = new JFormattedTextField(dateMask);
} catch (ParseException ex) {
Logger.getLogger(Hello.class.getName()).log(Level.SEVERE, null, ex);
}
formattedField.setColumns(10);
formattedField.setInputVerifier(getInputVerifier());
return formattedField;
}
private InputVerifier getInputVerifier() {
InputVerifier verifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
JFormattedTextField field = (JFormattedTextField) input;
String text = field.getText();
return isValidDate(text);
}
@Override
public boolean shouldYieldFocus(JComponent input) {
boolean valid = verify(input);
if (!valid) {
JOptionPane.showMessageDialog(null, "Please enter a valid date in format dd/mm/yyyy");
weekEndingData.setText("");
}
return valid;
}
};
return verifier;
}
public boolean isValidDate(String dateString) {
if (dateString.equals(" / / ")){
resetLabels();
return true; //returns true in order to allow user to accidentally click field and still yield focus
}
else{
try {
simpleFormat.parse(dateString);
updatePrimer(dateString);
return true;
} catch (ParseException ex) {
resetLabels();
return false;
}
}
}
private void updatePrimer(String dateString) {
Calendar calTest = Calendar.getInstance();
calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);
try {
primer = simpleFormat.parse(dateString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(day);
shortString = shortFormat.format(primer);
System.out.println(shortString);
labelTrip = true;
stringTrip = dateString;
updateLabels(labelTrip, stringTrip);
}
private void resetLabels() {
weekEndingData.setValue(null);
labelTrip = false;
updateLabels(labelTrip, stringTrip);
}
private void updateLabels(boolean trip, String date) {
boolean validUpdate = trip;
if (validUpdate == false){
for (int i = 0; i < 3; i++){
dateData[i].setText("12/34");
dateData[i].setForeground(blank);
}
}
else if (validUpdate == true){
try {
cal.setTime(simpleFormat.parse(date));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int day = -1;
for (int i = 0; i < 3; i++){
cal.add(Calendar.DATE, day);
dateData[i].setText(shortFormat.format(cal.getTime()));
dateData[i].setForeground(Color.GREEN);
}
}
}
public void actionPerformed(ActionEvent e) {
/*System.out.println("Action performed");
System.out.println(formattedField);
endingDate = (Date) formattedField.getValue();
System.out.println(endingDate);
endingString = format.format(endingDate);
System.out.println(endingString);*/
System.out.println(weekEndingData.getText());
}
}
1 ответ
После распечатки моего кода и отслеживания моих данных через программу я обнаружил свою проблему.
В
private void updatePrimer(String dateString) {
Calendar calTest = Calendar.getInstance();
calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);
try {
primer = simpleFormat.parse(dateString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(day);
shortString = shortFormat.format(primer);
System.out.println(shortString);
labelTrip = true;
stringTrip = dateString;
updateLabels(labelTrip, stringTrip);
}
линии:
calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);
необходимо переместить после primer = simpleFormat.parse(dateString);
блок try-catch. Моя проблема заключалась в том, что я устанавливал время до установки даты.