Pergunta

Eu tenho uma caixa suspensa na minha GUI que mostra o conteúdo de um ArrayList em outra classe. Novos objetos podem ser adicionados ao ArrayList em outras partes do GUI, então eu preciso saber quando ela é atualizada, para que eu possa atualizar no menu suspenso. Pelo que eu pude perceber, minhas duas opções são para estender a classe ArrayList para permitir-me para adicionar minha própria ChangeListener a ele, ou para fazer a classe que contém o ArrayList em questão estender observável.

O que seria uma solução mais adequada?

Foi útil?

Solução

As duas soluções são essencialmente implementações do mesmo padrão de design de raiz (o padrão "Observer", conforme definido pelo Gang of Four.) No primeiro caso, você está fazendo a si ArrayList "observáveis", no último você é fazendo com que o objeto de domínio que usa a lista de matriz "observável."

Minha tendência seria a de fazer o último: tornar o objeto de domínio observável. Isso ocorre principalmente porque você pode eventualmente ter outras coisas que poderiam mudar sobre o objeto de domínio (para o qual o GUI deve ser atualizado). Se já é observável, você já está definido.

Note que você não estritamente necessário estender java.util.Observable -. Você pode implementar o padrão de design sem fazer isso

Outras dicas

A implementação Observable em Java é raramente usada, e não inter-operar bem com Swing. Use um EventListener vez.

Em particular, há uma razão para não estender AbstractListModel ou mesmo usar DefaultListModel diretamente ao gerenciar o conteúdo da lista "em outras partes do GUI"? Em seguida, a caixa de combinação poderia usar um ComboBoxModel que os delegados para a mesma instância ListModel, acrescentando sua própria implementação para acompanhar o estado de seleção.

Eu tenho em mente algo como isto (mas eu não testá-lo):

final class MyComboBoxModel 
  extends AbstractListModel 
  implements ComboBoxModel 
{

  private final ListModel data;

  private volatile Object selection;

  MyComboBoxModel(ListModel data) { 
    /* 
     * Construct this object with a reference to your list, 
     * which contents are managed somewhere else in the UI.
     */
    this.data = data;
    data.addListDataListener(new ListDataListener() {
      public void contentsChanged(ListDataEvent evt) { 
        fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
      }
      public void intervalAdded(ListDataEvent evt) { 
        fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
      }
      public void intervalRemoved(ListDataEvent evt) { 
        fireContentsChanged(this, evt.getIndex0(), evt.getIndex1()); 
      }
    });
  }

  public void setSelectedItem(Object selection) { 
    this.selection = selection;
    fireContentsChanged(this, 0, data.getSize() - 1);
  }

  public Object getSelectedItem() { return selection; }

  public int getSize() { return data.getSize(); }

  public Object getElementAt(int idx) { return data.getElementAt(idx); }

}

Por que não usar ligações?

http://wiki.eclipse.org/index.php/JFace_Data_Binding

Bind seu GUI widget para sua lista. Mudanças irão propagar entre os dois objetos de forma transparente. Certifique-se de envolver seu modelo com um observável apropriado, como WritableList (se estiver usando o ArrayList diretamente).

Prefira sempre a composição sobre a extensão (minha referência é java eficaz e minha experiência pessoal). estendendo ArrayList é simplesmente uma promessa que você não irá violar qualquer um dos invariantes classes. Ele também se liga você à implementação lista específica você está estendendo.

Você poderia passar a usar um GUI design padrão . Ou construir uma implementação limitada.

Criar um formulário de interface GUI que tem um DrawXArrayList método (com X sendo um nome meaningfull. Ele tem um parâmetro do tipo ArrayList

Criar uma nova classe chamada GUIView. Ele tem pelo menos dois métodos: UpdateXArrayList e RegisterForm

Quando você inicializa o aplicativo tem o Formulário GUI registar-se com o GUIView implementação de classe. Faça a classe implementando GUIView visível para o formulário.

Quando nada em seu Formulário GUI atualiza o ArrayList tem que chamar UpdateXArrayList como a última coisa que ele faz. O método UpdateXArrayList na GUIView implementação de classe, então, por sua vez chamada DrawXArrayList passando o ArrayList atualizado. DrawXArrayList na classe de formulário implementação do GUIFormInterface, então, tomar as medidas precisam atualizar o controle exibindo o ArrayList.

Enquanto esta parece ser uma série de etapas, em comparação com uma configuração de observador e ouvinte. Você tem mais controle sobre como as diversas ações do usuário efeito a interface do usuário, em seguida, o observador padrão-ouvinte. Além disso, você documentou, em código, a interação entre a ação do usuário e as atualizações para a interface do usuário.

Se você pode adicionar um novo frasco para a aplicação, consulte a vidros Listas

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top