我在项目中使用了几个JSpinner来显示小时和分钟。当JSpinner递增或递减时,我必须将值保存到数据库中。但问题是JSpinners给了我很旧的价值观。
例如 - 如果显示的时间是09:30
并且我将时间增加到10:30
,我将返回09:30作为返回值。我正在使用以下代码
更新的SSCCE
package spinnerupdation;
import java.awt.Container;
import java.awt.FlowLayout;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;
/**
*
* @author Rohan Kandwal
*/
public class SpinnerUpdation extends JFrame{
public JSpinner spinner;
SpinnerUpdation(){
Container pane=this.getContentPane();
JPanel panel=new JPanel();
panel.setLayout(new FlowLayout());
SpinnerDateModel model=new SpinnerDateModel();
model.setCalendarField(Calendar.HOUR);
spinner=new JSpinner();
spinner.setModel(model);
spinner.setEditor(new JSpinner.DateEditor(spinner,"hh:mm"));
panel.add(spinner);
pane.add(panel);
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JFormattedTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();
DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();
// Change the date format to only show the hours
formatter.setFormat(new SimpleDateFormat("hh:mm"));
//formatter.setCommitsOnValidEdit(true);
System.out.println(spinner.getValue());
//System.out.println(tf.getText());
}
});
}
public static void main(String[] args) {
SpinnerUpdation ss=new SpinnerUpdation();
ss.setDefaultCloseOperation(ss.EXIT_ON_CLOSE);
ss.setSize(574, 445);
//ss.pack();
ss.setLocationRelativeTo(null);
ss.setResizable(false);
ss.setVisible(true);
}
}
如果我正在使用tf.getText()
我将获得旧值两次,但如果我使用spinner.getValue
我将获得新值,但它是长格式
Thu Jan 01 10:18:00 IST 1970
Thu Jan 01 11:18:00 IST 1970
我应该如何设置微调器以仅提供11:18
?
答案 0 :(得分:3)
您可以维护一个“主日期”,您可以将时间值重新合并到每个stateChanged
事件中。
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
add(new DateSpinner(new Date()));
}
}
public class DateSpinner extends JSpinner {
private Date masterDate;
public DateSpinner(Date date) {
super(new SpinnerDateModel());
this.masterDate = date;
SpinnerDateModel model = (SpinnerDateModel) getModel();
model.setCalendarField(Calendar.HOUR);
setEditor(new JSpinner.DateEditor(this, "hh:mm"));
JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField();
DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();
DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();
formatter.setFormat(new SimpleDateFormat("hh:mm"));
setValue(date);
addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
Calendar cal = Calendar.getInstance();
cal.setTime(masterDate);
Calendar time = Calendar.getInstance();
time.setTime((Date) getValue());
cal.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, time.get(Calendar.MINUTE));
masterDate = cal.getTime();
System.out.println(masterDate);
}
});
}
public String getTime() {
return new SimpleDateFormat("hh:mm").format((Date)getValue());
}
}
}
答案 1 :(得分:2)
Java swing使用MVC模式,因此它在JSpinner中是相同的。如果查看JSpinner源代码,您会发现getValue()方法实际上是调用getModel()。getValue(),因此它调用模型的getValue。你使用的模型是SpinnerDateModel,它的值是Date Object,当你打印Date对象时,它会显示默认格式,如“Thu Jan 01 11:18:00 IST 1970”,如果你想获得像“11:18”这样的东西,你需要自己格式化。像
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm");
System.out.println(sdf.format(spinner.getValue()) );
您可能想知道为什么tf.getText()只获取旧值,因为在微调器上的ChangeEvent发生后,将发生tf上的PropertyChangeEvent,将新值设置为它。当然,您可以像tf.addPropertyChangeListener一样收听tf。但我会建议使用上面的解决方案。