ValueBaseField.isReadOnly returns always true in 3.0.3. See my example:

Code:
public class GXT_3_0 implements EntryPoint {

    public void onModuleLoad() {
        RootPanel.get().add(createMainPanel());
    }


    private Container createMainPanel() {
        VerticalLayoutContainer vlc = new VerticalLayoutContainer();
        vlc.setBorders(true);
        vlc.setPixelSize(600, 400);


        final TextField field = new TextField();
        field.setValue("test string");


        vlc.add(field);


        final TextButton button = new TextButton("readOnly = true");
        
        button.addSelectHandler(new SelectHandler() {


            @Override
            public void onSelect(SelectEvent event) {
                field.setReadOnly(true);
                field.setValue(String.valueOf(field.isReadOnly()));
            }
        });
        vlc.add(button);
        
        final TextButton button2 = new TextButton("readOnly = false");
        
        button2.addSelectHandler(new SelectHandler() {


            @Override
            public void onSelect(SelectEvent event) {
                field.setReadOnly(false);
                field.setValue(String.valueOf(field.isReadOnly()));
            }
        });
        vlc.add(button2);


        return vlc;
    }
}
It's because you've changed your implementation for setReadOnly:
Code:
public void setReadOnly(boolean readOnly) {    
    getCell().setReadOnly(true);
    getCell().getInputElement(getElement()).setReadOnly(readOnly);
  }
  
  public boolean isReadOnly() {
    return getCell().isReadOnly(); // <-- returns always true after a setReadOnly(true|false) call
  }