Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Swing:自定义JSpinner模型导致StackOverflower错误_Java_Swing_Model_Stack Overflow_Jspinner - Fatal编程技术网

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;
}