Hello,
pour les besoin d'une appli j'ai du creer un nouveau TableCellRenderer et un nouveau TableCellEditor permettant d'afficher et de manipuler une MultiSlider, un composant de mon cru permettant d'avoir n curseurs. Le renderer etant MultiSlider tantdis que l'editor delege au MultiSlider. Egalement l'editor utilise la meme methode de configuration que le renderer. Tout marche pour le mieux ormis qq leger pb de coloration : curseurs peu visibles en LnF windows quand cellule non selectionnee (fond blanc) et parfois la couleur de selection ne se met pas quand la cellule est selectionee ( l'editeur ou le renderer reste en fond blanc) mais rien de bien grave.

Le probleme le plus ennuyant apparait quand on redimensionne la cellule : le renderer ne se redimensionne pas et reste a sa taille initiale (meme si on reduit la cellule). Au contraire l'editor, lui, s'adapte toujours correctement a la taille de la cellule.

Voici un screenshot demontrant le probleme :



Voici le code des classe :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    DefaultTableModel areaTableModel = new CriterionTableModel();
    areaTableModel.addRow(new Object[] {ExtendedUtilities.getString("LABEL_LONGITUDE"), 
new Limits.Float(0, 100), 0f, 100f});
    areaTableModel.addRow(new Object[] {ExtendedUtilities.getString("LABEL_LATITUDE"), 
new Limits.Float(0, 100), 0f, 100f});
    areaTableModel.addRow(new Object[] {ExtendedUtilities.getString("LABEL_DATE_DEPTH@" + SET), 
new Limits.Float(0, 100), 0f, 100f});
    JTable areaTable = new JTable(areaTableModel);
    areaTable.setDefaultEditor(Limits.Float.class, new IntervalTableCellEditor());
    areaTable.setDefaultRenderer(Limits.Float.class, new IntervalTableCellRenderer());
    ExtendedPanel areaTablePanel = new ExtendedPanel();
    areaTablePanel.setBorder(new LineBorder(getForeground()));
    areaTablePanel.setLayout(new BoxLayout(areaTablePanel, BoxLayout.Y_AXIS));
    areaTablePanel.add(areaTable.getTableHeader());
    areaTablePanel.add(areaTable);
 
[...]
 
 /** The customized table model.
* <p>Title: Dym2NetCDF</p>
* <p>Description: converts DYM file(s) to NetCDF.</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: SPC</p>
* @author Fabrice Bouyé (fabriceb@spc.int)
* @version 1.0
*/
  private static class CriterionTableModel
      extends DefaultTableModel {
    /** Defines the classes for each column.
*/
    public static Class[] COLUMN_CLASSES = {
        String.class, Limits.Float.class, Float.class, Float.class};
 
    /** Defines the label keys for each column.
*/
    public static String[] COLUMN_LABEL_KEYS = {
        "LABEL_VARIABLE", "LABEL_LIMITS", "LABEL_MINIMUM_SHORT", "LABEL_MAXIMUM_SHORT"};
 
    /** Creates a new instance.
*/
    public CriterionTableModel() {
    }
 
    /** {@inheritDoc}
*/
    @Override public int getColumnCount() {
      return COLUMN_CLASSES.length;
    }
 
    /** {@inheritDoc}
*/
    @Override public Class getColumnClass(int index) {
      return COLUMN_CLASSES[index];
    }
 
    /** {@inheritDoc}
*/
    @Override public String getColumnName(int index) {
      return ExtendedUtilities.getString(COLUMN_LABEL_KEYS[index]);
    }
 
    /** {@inheritDoc}
*/
    @Override public boolean isCellEditable(int row, int column) {
      return (column > 0);
    }
  }
 
  /** A customized cell renderer that shows a multislider.
* <p>Title: Dym2NetCDF</p>
* <p>Description: converts DYM file(s) to NetCDF.</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: SPC</p>
* @author Fabrice Bouyé (fabriceb@spc.int)
* @version 1.0
*/
  private static class IntervalTableCellRenderer
      extends MultiSlider implements TableCellRenderer {
    /** Creates a new instance.
*/
    public IntervalTableCellRenderer() {
      super(new DefaultMultiBoundedRangeModel(
new double[] {0, 0}, new double[] {0, 0}, 0, 100));
      //setBorder(new EmptyBorder(3, 3, 3, 3));
    }
 
   /** {@inheritDoc}
*/
    public Component getTableCellRendererComponent(JTable table,
 Object value, boolean isSelected, boolean hasFocus, int row, int column) {
      configureSlider(table, value, isSelected, hasFocus, row, column, this);
      return this;
    }
 
    /** Decorates a slider so it can fit as a table cell.
* @param table The parent table.
* @param value The current value.
* @param isSelected <code>True</code> if celle is selected.
* @param hasFocus <code>True</code> if celle has focus.
* @param row Current row.
* @param column Current column.
* @param slider The slider to configure.
*/
    public static void configureSlider(JTable table, 
Object value, boolean isSelected, boolean hasFocus, int row, int column, 
MultiSlider slider) {
      Limits.Float limits = (Limits.Float) value;
      TableModel model = table.getModel();
      float val0 = (Float) model.getValueAt(row, column + 1);
      float val1 = (Float) model.getValueAt(row, column + 2);
      if (isSelected) {
        slider.setBackground(table.getSelectionBackground());
        slider.setForeground(table.getSelectionForeground());
      }
      else {
        slider.setBackground(table.getBackground());
        slider.setForeground(table.getForeground());
      }
      slider.setMaximum(limits.getMaximum());
      slider.setMinimum(limits.getMinimum());
      slider.setValue(0, val0);
      slider.setValue(1, val1);
      slider.setEnabled(table.isEnabled());
    }
  }
 
  /** A customized cell renderer that shows a multislider.
* <p>Title: Dym2NetCDF</p>
* <p>Description: converts DYM file(s) to NetCDF.</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: SPC</p>
* @author Fabrice Bouyé (fabriceb@spc.int)
* @version 1.0
*/
  private static class IntervalTableCellEditor
      extends AbstractCellEditor implements TableCellEditor, 
ChangeListener {
    /** Delegated GUI component.
*/
    private MultiSlider component = new MultiSlider(
new DefaultMultiBoundedRangeModel(new double[] {0, 0}, 
new double[] {0, 0}, 0, 100));
 
   /** Reference to last visited table.
*/
    private JTable lastTable;
 
    /** Current edited interval.
*/
    private Limits.Float lastValue;
 
    /** Last visited row.
*/
    private int lastRow;
 
    /** Last visited column.
*/
    private int lastColumn;
 
    /** Creates a new instance.
*/
    public IntervalTableCellEditor() {
      super();
      //component.setBorder(new EmptyBorder(3, 3, 3, 3));
    }
 
    /** {@inheritDoc}
*/
    public Object getCellEditorValue() {
      return lastValue;
    }
 
    /** {@inheritDoc}
*/
    public Component getTableCellEditorComponent(JTable table, 
Object value, boolean isSelected, int row, int column) {
      lastTable = table;
      lastValue = (Limits.Float) value;
      lastRow = row;
      lastColumn = column;
      IntervalTableCellRenderer.configureSlider(table, value, isSelected,
 false, row, column, component);
      component.addChangeListener(this);
      return component;
    }
 
   /** {@inheritDoc}
*/
    @Override public void cancelCellEditing() {
      component.removeChangeListener(this);
      super.cancelCellEditing();
    }
 
    /** {@inheritDoc}
*/
    @Override public boolean stopCellEditing() {
      component.removeChangeListener(this);
      return super.stopCellEditing();
    }
 
    /** {@inheritDoc}
*/
    public void stateChanged(ChangeEvent event) {
      // We modify the table directly when we receive change event.
      DefaultTableModel model = (DefaultTableModel) lastTable.getModel();
      Limits.Float limits = new Limits.Float(component.getValue(0), component.getValue(1));
      model.setValueAt(limits.minimum(), lastRow, lastColumn + 1);
      model.setValueAt(limits.maximum(), lastRow, lastColumn + 2);
    }
  }
Si qqun a une idee ?

Merci