30. april 2002 - 14:20Der er
3 kommentarer og 1 løsning
TableCellrenderer flimrer første gang
Jeg har en JTable hvor nogle af cellerne indeholder en JSlider. jeg gør dette med to inner classes i min klasse som extender JTable
public class SliderRenderer extends JSlider implements TableCellRenderer{....}
public class SliderEditor extends DefaultCellEditor implements ChangeListener{..}
Problemet ligger i at første gang der klikkes på en celle bliver baggrunden vist og derefter JSlideren igen. Dette sker kun første gang en celle i hver kolonne der har en slider bliver klikket. Herefter virker det fint.
Både Renderer og Editor bliver initialiseret så det er formentlig ikke fordi Editor konstruktoren først bliver kaldt efter klikket. Nogen erfaringer?
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
Jeg har prøvet at genskabe problemet men det lader sig ikke gøre. Jeg har dog fundet ud af hvilken metode der forårsager fejlen. Når JSlideren modtager en Statechanged event, kaldes metoden handleSliderEvent. Der foretages 2 operationer (removeRow og dernæst InsertRow) på TabelModellen (En DefaultTableModel) det kan være dem og det virker også som en dårlig måde at fjerne en row og derefter tilføje en nu men jeg kan ikke se hvordan man eller gørt det?
generateViewRow opretter et nyt Object array til TableModellen
/** called by sliders statechanged method when the sliders are changed and osd is updated * the method takes the sliders value and recalculate criticality */ public void handleSliderEvent(int row, int col, int value) { // OSD values has changed and the criticality for the fault should be recalculated and displayed //1. get the dummyvalue from the module //2. insert the new value in the dummyOSD object //3. recalculate the criticality //4. insert the value in the tablemodel This causes the table to update
//String component was set in handlepopupevent, model iss A TableModel //we are using default so theres no point in letting the user think he is changing the values if( module.useDefaultOSD() ) { JOptionPane.showMessageDialog(gui,"Currently you have choosen to use default OSD values.\n"+ "Therefore your changes will have no effect. \n"+ " You can however change this by unchecking the 'use default osds' menuitem\n"+ "in the Display menu"); } else { DummyOSD temp = getDummyOSD(component, id ,(String) model.getValueAt(row,0)); //1 switch(col) { // 2 case 1: //O temp.setNewO(value); temp.setUseDefaultOSD(false);//o changed so now we dont use default anymore break; case 2: // S temp.setNewS(value); temp.setUseDefaultOSD(false); break; case 3: // S temp.setNewD(value); temp.setUseDefaultOSD(false); break; default:System.out.println("ERROR in handleslide event"); } module.fire(temp);//3 temp is now being changed
model.removeRow(row); model.insertRow(row,generateViewTableRow(temp));//generate a new row and insert it
setChanged();//the model has changed notifyObservers();//notify clearChanged();//no longer changed } }
/** generates data for 1 row in the table displaying osd and faults*/ public Object[] generateViewTableRow(DummyOSD temp) { Object[] data = new Object[8]; data[0] = temp.getDescription();
data[1] = new Integer((int)temp.getO()) ; data[2] = new Integer((int)temp.getS()); data[3] = new Integer((int)temp.getD()); data[4] = temp.getFuzzyCriticality(); data[5] = ""+( (int)temp.getCriticality() );//has to be an Object we put there so we convert to String data[6] = "" + calculateRPN(temp.getO(),temp.getS(),temp.getD() ); data[7] = new Boolean(temp.getUseDefaultOSD()); } else //not using default { data[1] = new Integer((int)temp.getNewO() ); data[2] = new Integer((int)temp.getNewS() ); data[3] = new Integer((int)temp.getNewD() ); data[4] = temp.getFuzzyCriticality(); data[5] = ""+( (int)temp.getCriticality() );//has to be an Object we put there so we convert to String data[6] = "" + calculateRPN(temp.getNewO(),temp.getNewS(),temp.getNewD() ); data[7] = new Boolean(temp.getUseDefaultOSD()); }
Jeg har et lille afkog af et eksempel her, som bruger en JScrollBar.
Min TableModel (Volume er en simpel klasse, indeholdende 0-100 som value): import javax.swing.table.*;
public class MixerModel extends AbstractTableModel{ Object data[][] = { { new Volume(56), new Volume(42) }, { new Volume(10), new Volume(88) } };
public int getColumnCount() { return data[0].length; }
public int getRowCount() { return data.length; }
public Class getColumnClass(int columnIndex) { return Volume.class; }
public boolean isCellEditable(int rowIndex, int columnIndex) { return true; }
public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { ((Volume) data[rowIndex][columnIndex]).setVolume(aValue); } }
Til min table har jeg følgende renderer: public class VolumeRenderer extends JScrollBar implements TableCellRenderer{ public VolumeRenderer() { super(JScrollBar.HORIZONTAL); }
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value == null) return this; if (value instanceof Volume) setValue(((Volume)value).getVolume()); else setValue(0); return this; } }
Og tilsvarende editor: public class VolumeEditor extends JScrollBar implements TableCellEditor{ protected transient Vector listeners; protected transient int originalValue;
public VolumeEditor() { super(JScrollBar.HORIZONTAL); listeners = new Vector(); }
public void addCellEditorListener(CellEditorListener l) { listeners.addElement(l); }
public void cancelCellEditing() { fireEditingCanceled();}
public Object getCellEditorValue() { return new Integer(getValue()); }
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (value == null) return this; if (value instanceof Volume) setValue(((Volume)value).getVolume()); else setValue(0); table.setRowSelectionInterval(row, row); table.setColumnSelectionInterval(column, column); originalValue = getValue(); return this; }
public boolean isCellEditable(EventObject anEvent) { return true; }
public void removeCellEditorListener(CellEditorListener l) { listeners.removeElement(l); }
public boolean shouldSelectCell(EventObject anEvent) { return true; }
public boolean stopCellEditing() { fireEditingStopped(); return true; }
protected void fireEditingCanceled() { setValue(originalValue); ChangeEvent ce = new ChangeEvent(this); for (int i = listeners.size() - 1 ; i >= 0 ; i--) ((CellEditorListener)listeners.elementAt(i)).editingCanceled(ce); }
protected void fireEditingStopped() { setValue(originalValue); ChangeEvent ce = new ChangeEvent(this); for (int i = listeners.size() - 1 ; i >= 0 ; i--) ((CellEditorListener)listeners.elementAt(i)).editingStopped(ce); } }
Jeg har brugt din kode Logical, og det virker (selvfoelgelig) perfekt. Hvad min fejl skyldtes maa staa hen i det uvisse. Tak for hjaelpen
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.