Avatar billede conrad Nybegynder
30. april 2002 - 14:20 Der 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?
Avatar billede logical Nybegynder
05. maj 2002 - 15:42 #1
Masser af erfaring, bare ikke de samme problemer:-)

De typiske problemer jeg har set med JTable skyldes forkert omgang med table model, men jeg håber det ikke er den slags du er ude i.

Kan du reproducere problemet simpelt??
Avatar billede conrad Nybegynder
06. maj 2002 - 12:10 #2
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();
           
           
            if(module.useDefaultOSD() || temp.getUseDefaultOSD())//using default
            {
           
            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());
            }
       
       
        return data;
    }
Avatar billede logical Nybegynder
07. maj 2002 - 01:54 #3
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);
    }
}
Avatar billede conrad Nybegynder
10. maj 2002 - 04:36 #4
Jeg har brugt din kode Logical, og det virker (selvfoelgelig) perfekt. Hvad min fejl skyldtes maa staa hen i det uvisse.
Tak for hjaelpen
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester