Java Swing:自定义JSpinner模型导致StackOverflower错误
我想为自己编写一个Java Swing:自定义JSpinner模型导致StackOverflower错误,java,swing,model,stack-overflow,jspinner,Java,Swing,Model,Stack Overflow,Jspinner,我想为自己编写一个JSpinner的AbstractSpinnerModel,它显示我定制的类Time的值。我扩展了JSpinner,如下所示: TimeSpinner.java 当我运行代码时,我会得到一个StackOverflowerError,因为似乎有一个侦听器循环在互相通知。但在所有代码示例中,我查看的代码都完全按照我的方式执行,即在setValue中调用fireStateChanged()为什么会发生这种情况? 我的堆栈跟踪(直到开始重复): 编辑: 这是我的时间。java: pub
JSpinner
的AbstractSpinnerModel
,它显示我定制的类Time
的值。我扩展了JSpinner
,如下所示:
TimeSpinner.java
当我运行代码时,我会得到一个StackOverflowerError,因为似乎有一个侦听器循环在互相通知。但在所有代码示例中,我查看的代码都完全按照我的方式执行,即在setValue
中调用fireStateChanged()
为什么会发生这种情况?
我的堆栈跟踪(直到开始重复):
编辑:
这是我的时间。java
:
public class Time {
private int sec;
public Time() {
sec = 0;
}
public Time(int sec) {
this.sec = sec;
}
public void add(int sec) {
this.sec += sec;
}
public void add(Time other) {
this.sec += other.sec;
}
public int getSeconds() {
return this.sec;
}
@Override
public String toString() {
if (this.sec < 3600)
return String.format("%d:%02d", sec/60, sec%60);
return String.format("%d:%02d:%02d", sec/3600, (sec%3600)/60, sec%60);
}
public static Time parseTime(String str) throws NumberFormatException {
try {
int i = Integer.parseInt(str);
return new Time(i);
} catch (NumberFormatException e) {}
try {
double d = Double.parseDouble(str.replace(',', '.'));
return new Time((int)(d * 60.0));
} catch (NumberFormatException e) {}
String[] strs = str.split(":");
int l = strs.length;
int h, m, s;
if (l == 3) {
h = Integer.parseInt(strs[0]);
m = Integer.parseInt(strs[1]);
s = Integer.parseInt(strs[2]);
}
else if (l == 2) {
h = 0;
m = Integer.parseInt(strs[0]);
s = Integer.parseInt(strs[1]);
} else {
throw new NumberFormatException();
}
return new Time(3600 * h + 60 * m + s);
}
}
公共课时间{
私人国际证券交易委员会;
公共时间(){
秒=0;
}
公共时间(整数秒){
本秒=秒;
}
公共无效添加(整数秒){
本秒+=秒;
}
公共无效添加(其他时间){
this.sec+=其他.sec;
}
公共整数getSeconds(){
返回此值。秒;
}
@凌驾
公共字符串toString(){
如果(本秒<3600)
返回字符串。格式(“%d:%02d”,秒/60,秒%60);
返回字符串格式(“%d:%02d:%02d”,秒/3600,(秒%3600)/60,秒%60);
}
公共静态时间解析时间(字符串str)抛出NumberFormatException{
试一试{
int i=Integer.parseInt(str);
返回新时间(i);
}catch(numberformatexe){}
试一试{
double d=double.parseDouble(str.replace(',',');
返回新时间((int)(d*60.0));
}catch(numberformatexe){}
字符串[]strs=str.split(“:”);
int l=标准长度;
int h,m,s;
如果(l==3){
h=整数.parseInt(strs[0]);
m=整数.parseInt(strs[1]);
s=Integer.parseInt(strs[2]);
}
else如果(l==2){
h=0;
m=整数.parseInt(strs[0]);
s=Integer.parseInt(strs[1]);
}否则{
抛出新的NumberFormatException();
}
返回新时间(3600*h+60*m+s);
}
}
这是经过一些修改后的工作代码
TimeSpinnerModel类
package com.test;
import javax.swing.AbstractSpinnerModel;
import javax.swing.JSpinner;
public class TimeSpinner extends JSpinner {
public TimeSpinner() {
super();
setModel(new TimeSpinnerModel());
((JSpinner.DefaultEditor) getEditor()).getTextField().setEditable(true);
}
public class TimeSpinnerModel extends AbstractSpinnerModel {
private Time t = new Time(0);
@Override
public Object getValue() {
return t;
}
@Override
public void setValue(Object o) {
try {
t.set(Time.parseTime(o.toString()));
fireStateChanged();
} catch (NumberFormatException e) {}
}
@Override
public Object getNextValue() {
// next 10 seconds step
return new Time(((t.getSeconds() + 10) / 10) * 10);
}
@Override
public Object getPreviousValue() {
if (t.getSeconds() > 0) {
// previous 10 seconds step
return new Time(((t.getSeconds() - 1) / 10) * 10);
}
return t;
}
}
}
public class Time {
private int sec;
public Time() {
sec = 0;
}
public Time(int sec) {
System.out.println(Com.cnt.getAndIncrement());
this.sec = sec;
}
public void set(int sec){
this.sec = sec;
}
public void add(int sec) {
this.sec += sec;
}
public void add(Time other) {
this.sec += other.sec;
}
public int getSeconds() {
return this.sec;
}
@Override
public String toString() {
if (this.sec < 3600)
return String.format("%d:%02d", sec / 60, sec % 60);
return String.format("%d:%02d:%02d", sec / 3600, (sec % 3600) / 60,
sec % 60);
}
public static int parseTime(String str) throws NumberFormatException {
try {
String[] strs = str.split(":");
if (strs.length == 1) {
return Integer.parseInt(str);
} else if (strs.length == 2) {
return Integer.parseInt(strs[0]) * 60
+ Integer.parseInt(strs[1]);
} else {
int h, m, s;
h = Integer.parseInt(strs[0]);
m = Integer.parseInt(strs[1]);
s = Integer.parseInt(strs[2]);
return 3600 * h + 60 * m + s;
}
} catch (NumberFormatException e) {
throw e;
}
}
}
时间课堂
package com.test;
import javax.swing.AbstractSpinnerModel;
import javax.swing.JSpinner;
public class TimeSpinner extends JSpinner {
public TimeSpinner() {
super();
setModel(new TimeSpinnerModel());
((JSpinner.DefaultEditor) getEditor()).getTextField().setEditable(true);
}
public class TimeSpinnerModel extends AbstractSpinnerModel {
private Time t = new Time(0);
@Override
public Object getValue() {
return t;
}
@Override
public void setValue(Object o) {
try {
t.set(Time.parseTime(o.toString()));
fireStateChanged();
} catch (NumberFormatException e) {}
}
@Override
public Object getNextValue() {
// next 10 seconds step
return new Time(((t.getSeconds() + 10) / 10) * 10);
}
@Override
public Object getPreviousValue() {
if (t.getSeconds() > 0) {
// previous 10 seconds step
return new Time(((t.getSeconds() - 1) / 10) * 10);
}
return t;
}
}
}
public class Time {
private int sec;
public Time() {
sec = 0;
}
public Time(int sec) {
System.out.println(Com.cnt.getAndIncrement());
this.sec = sec;
}
public void set(int sec){
this.sec = sec;
}
public void add(int sec) {
this.sec += sec;
}
public void add(Time other) {
this.sec += other.sec;
}
public int getSeconds() {
return this.sec;
}
@Override
public String toString() {
if (this.sec < 3600)
return String.format("%d:%02d", sec / 60, sec % 60);
return String.format("%d:%02d:%02d", sec / 3600, (sec % 3600) / 60,
sec % 60);
}
public static int parseTime(String str) throws NumberFormatException {
try {
String[] strs = str.split(":");
if (strs.length == 1) {
return Integer.parseInt(str);
} else if (strs.length == 2) {
return Integer.parseInt(strs[0]) * 60
+ Integer.parseInt(strs[1]);
} else {
int h, m, s;
h = Integer.parseInt(strs[0]);
m = Integer.parseInt(strs[1]);
s = Integer.parseInt(strs[2]);
return 3600 * h + 60 * m + s;
}
} catch (NumberFormatException e) {
throw e;
}
}
}
在我的问题中添加了
Time.java
。我会将equals
和hashCode
方法添加到Time
类中,并且仅当值真的发生了更改时(如果旧时间等于新时间,那么就没有更改状态)才会生成状态更改事件。主状态在哪里?我希望能够运行它并获得错误。整个项目都在GitHub上:您必须手动重置Time.java
和TimeSpinner.java
才能再次获得错误。我认为您的意思是t.set(Time.parseTime(o.toString.getSeconds())
-但是,它确实有效,谢谢。你能向我解释一下为什么这个方法有效,但我的解决方案无效吗?啊,不,我刚才看到你也修改了parseTime
,没关系
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + sec;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Time)) {
return false;
}
Time other = (Time) obj;
if (sec != other.sec) {
return false;
}
return true;
}