3

For putting a JSlider into a JTable I wrote am AbstractCellEditor which implements a TableCellRendererand a TableCellEditor. It gets initialized with values from 0 to 100.

I have the strange behaviour that when I first click onta a slider it jumps to the maximum.

The second weird behaviour: I've added a ChangeListener. This Listener gets only called if I first click into the slider. A second click (which also changes the value) doesn't cause this event. Why?

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;
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Razer
  • 7,843
  • 16
  • 55
  • 103

1 Answers1

2

Absent your sscce, I'm speculating; but I can suggest two things to examine critically:

  1. In getTableCellEditorComponent(), the actual parameter value comes from your table model. Your setValue() invocation forwards the value to the slider's range model. An out-of-range value is pinned to the extreme.

  2. Your ChangeListener needs to fireEditingStopped(), as shown in the ItemListener of this related example.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    Thanks. Point 2 is fixed. Problem 1 seems to be something else. I'm using scrollDueToClickInTrack() to jump to the current position. This uses internally trackRect.width which has the wrong value on the first time. Clicking on the slider a second time, it's initialized right and the slider jumps to the right position. – Razer Jan 14 '12 at 12:50
  • I'm confused. It looks like your editor already does `setValue()`. – trashgod Jan 14 '12 at 20:15
  • 1
    I just fixed it by calling `super.calculateGeometry()` before `scrollDueToClickInTrack(). This calculates the right tracRect and this jump to a position works. – Razer Jan 14 '12 at 20:22
  • Glad you got it sorted, but I'm curious: Why override `scrollDueToClickInTrack()` at all? – trashgod Jan 14 '12 at 20:40
  • 2
    `scrollDueToClickInTrack()`normally increments the slider only. I want that the slider directly jumps to the clicked position. – Razer Jan 14 '12 at 20:51