Swing JTable中的JSlider

Swing JTable中的JSlider,swing,jtable,jslider,tablecellrenderer,tablecelleditor,Swing,Jtable,Jslider,Tablecellrenderer,Tablecelleditor,为了将JSlider放入JTable中,我编写了amAbstractCellEditor,它实现了TableCellRenderer和TableCellEditor。它使用0到100之间的值进行初始化 我有一种奇怪的行为,当我第一次点击滑块时,它会跳到最大值 第二个奇怪的行为:我添加了一个ChangeListener。仅当我第一次单击滑块时,才会调用此侦听器。第二次单击(也会更改值)不会导致此事件。为什么? public class SliderTableColumn extends Abstr

为了将
JSlider
放入
JTable
中,我编写了am
AbstractCellEditor
,它实现了
TableCellRenderer
TableCellEditor
。它使用0到100之间的值进行初始化

我有一种奇怪的行为,当我第一次点击滑块时,它会跳到最大值

第二个奇怪的行为:我添加了一个
ChangeListener
。仅当我第一次单击滑块时,才会调用此侦听器。第二次单击(也会更改值)不会导致此事件。为什么?

public class SliderTableColumn extends AbstractCellEditor implements TableCellRenderer,
                                                                     TableCellEditor

{
    private final JSlider slRenderer;
    private final JSlider slEditor;

    private final int INITAL_VALUE;
    private final int MIN_VLAUE;
    private final int MAX_VALUE;

    public SliderTableColumn(int min, int max, int initial, ChangeListener listener)
    {
        INITAL_VALUE = initial;
        MIN_VLAUE    = min;
        MAX_VALUE    = max;

        slRenderer = new JSlider(MIN_VLAUE, MAX_VALUE);
        slEditor   = new JSlider(MIN_VLAUE, MAX_VALUE);

        slEditor.addChangeListener(listener);

        slRenderer.setUI(new CustomSliderUI(slRenderer, INITAL_VALUE));
        slEditor.setUI(new CustomSliderUI(slEditor,     INITAL_VALUE));

        slRenderer.setValue(INITAL_VALUE);
        slEditor.setValue(INITAL_VALUE);
    }

    @Override
    public Object getCellEditorValue()
    {
        return slEditor.getValue();
    }

    @Override
    public Component getTableCellRendererComponent(JTable table,
                                                Object value,
                                                boolean isSelected,
                                                boolean hasFocus,
                                                int row,
                                                int column)
    {
        if(value != null)
        {
            slRenderer.setValue(((Integer) value).intValue());
        }
        return slRenderer;
    }

    @Override
    public Component getTableCellEditorComponent(JTable table,
                                                Object value,
                                                boolean isSelected,
                                                int row,
                                                int column)
    {
        if(value != null)
        {
            slEditor.setValue(((Integer) value).intValue());
        }
        return slEditor;
    }
}
没有你,我在猜测;但我可以建议两件事进行批判性检查:

  • getTableCellEditorComponent()
    中,实际参数
    来自表模型。您的
    setValue()
    调用将
    转发到滑块的范围模型。超出范围的
    被固定到

  • 您的
    ChangeListener
    需要
    fireEditingStopped()
    ,如本相关文档的
    ItemListener
    所示


  • 谢谢第2点是固定的。问题1似乎是另外一个问题。我正在使用scrollDueToClickInTrack()跳转到当前位置。这会在内部使用trackRect.width,它在第一次使用时的值是错误的。第二次点击滑块,它被初始化到右边,滑块跳转到正确的位置。我很困惑。看起来您的编辑器已经执行了
    setValue()
    。我刚刚通过在'scrollDueToClickInTrack()之前调用
    super.calculategemetry()
    修复了它。这将计算右tracRect,并跳转到某个位置。很高兴您对其进行了排序,但我很好奇:为什么要覆盖
    scrollDueToClickInTrack()
    scrollDueToClickInTrack()
    通常只增加滑块。我希望滑块直接跳到单击的位置。