Melhor abordagem para a Ação dual-estado
-
13-09-2019 - |
Pergunta
Eu tenho implementado recentemente um Action
que alterna o status ativado de uma função de negócios. Sempre que o usuário chama a ação I definir um sinalizador boolean: " willEnable " para determinar se a próxima invocação irá ativar ou desativar a função. Da mesma forma que eu atualizar o nome da ação, breve descrição e ícone para refletir o novo estado. Em seguida, dentro do meu método actionPerformed(...)
eu tomar uma ação diferente com base no estado de willEnable
.
- Esta é a abordagem correta ou lata
Alguém recomenda um melhor (como eu
suspeita que este é um problema comum)?
(Eu posso ver que os atos
JToggleButton
como um botão de dois estados, mas eu quero esta ação para ser visível em umJMenuBar
, bem como umJButton
, por isso não acho que isso é apropriado).
Editar
Especificamente, como fazem aplicações como negócio IDEA com isso? Será que eles usam ações multi-estatais (como acima) ou se eles trocam um Action
diferente em um determinado JButton
usando setAction(Action)
? Talvez esta abordagem é melhor?
- Ao atualizar propriedades de uma ação
I pode contar com componentes GUI
inicializado com que
Action
(e.g.JButton
) repintar automaticamente si mesmos? E se oJButton
tamanho muda como resultado? Eu devo ser revalidação o que contenhamJPanel
me? - Está mudando o nome da ação uma má
coisa para fazer? Esta é a única maneira que eu
pode fazer a mudança de texto JButton, mas estou consciente de que o nome provavelmente deve permanecer constante se a ação está sendo colocado em uma
ActionMap
.
Agradecemos antecipadamente.
Solução
Eu esperaria que qualquer componente GUI que é criado com alguns dados "modelo" (I incluiria uma Action
como um modelo de dados) deve se registrar como um ouvinte para esse modelo. É deve tomar as medidas adequadas, erm, a ação em um ser PropertyChangeEvent
disparou:. Qualquer outro comportamento constituiria um erro na minha opinião
A coisa questionável aqui é se é legítimo para alterar o nome da acção; Eu acho que não é legítimo . Sua ação logicamente é ToggleEnabledStatus e isso não muda porque a ação foi invocado. Qualquer componente que precisa exibir qualquer outro texto deve se registrar como um ouvinte para o Action
e, em seguida, verificar a sua bandeira willEnable
para levar o apropriado, erm, ação.
Como alternativa, você pode escrever sua própria classe que implementou ToggleButtonModel
e Action
ao mesmo tempo e controlado os eventos de mudança de dentro dele. Este é um monte de código, no entanto, para tal benefício pouco
Outras dicas
Você pode querer olhar para o Estado Padrão .
Basicamente, você cria uma implementações do mesmo interface e dois (mais ou) para cada estado. Como um exemplo simples, o estado desativar só poderia implementar a interface para não fazer nada enquanto o estado habilitado faz algumas ações. Para estado interruptor você poderia simplesmente fazer
interface IState {
void doAction();
boolean isEnabled();
}
class EnabledState implement IState {
void doAction() {
setState(new DisabledState());
// do something
}
boolean isEnabled() {return true;}
}
class DisabledState implement IState {
void doAction() {
setState(new EnabledState());
// do nothing
}
boolean isEnabled() {return false;}
}
private IState state = new DisabledState(); // default is disabled
private PropertyChangeSupport support = new PropertyChangeSupport(this);
void setState(IState state) {
if (this.state != state) {
IState oldState = this.state;
this.state = state;
support.firePropertyChange("enabled", oldState.isEnabled(), state.isEnabled());
}
}
void doAction() {
state.doAction();
}
Embora seja um pouco de sobrecarga para um único método, ele certamente paga de, logo que você tem vários métodos que mudam seu comportamento dependendo de um único estado.