複数のパネルがあるJFrameがあります。各パネルには、その上に設計されたいくつかのコンポーネントがあります。コンポーネント(JTextField)がフォーカスを取得したときに背景色を変更したい。多くのTextFieldがあり、すべてのコンポーネントにFocusListenerを記述したくありません。スマートマナーでそれを行うための解決策はありますか?
4 に答える
@Robin が提案しているように、必ずデザインを検討する必要があります。ファクトリを使用してアプリケーションのすべてのコンポーネントを作成および構成すると、コード全体に分散するのではなく、変更する場所が 1 か所になるため、要件の変更に対して堅牢になります。
さらに、コンポーネントごとの個々のリスナーは、フォーカスによって引き起こされるプロパティの変更が発生する場所の近くにコントロールを保持するため、グローバル リスナーで状態を処理する必要はありません。
とは言っても、グローバル focusListener の技術的な (慎重に使用するように!) 解決策は、propertyChangeListener を KeyboardFocusManager に登録することです。
簡単なコード スニペット (非常に大雑把な状態処理を含む :-)
JComponent comp = new JPanel();
for (int i = 0; i < 10; i++) {
comp.add(new JTextField(5));
}
PropertyChangeListener l = new PropertyChangeListener() {
Component owner;
Color background;
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (owner != null && evt.getOldValue() == owner) {
owner.setBackground(background);
owner = null;
}
if (evt.getNewValue() != null) {
owner = (Component) evt.getNewValue();
background = owner.getBackground();
owner.setBackground(Color.YELLOW);
}
}
};
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("permanentFocusOwner", l);
すべてのコンポーネントに対して FocusListener を書きたくない
だからあなたはあなたを交換したくない
JTextField textField = new JTextField();
に
JTextField textField = TextFieldFactory.createTextField();
whereは、目的の機能を備えたTextFieldFactory#createTextField
を作成するユーティリティ メソッドです。JTextField
それについて詳しく説明しますか?
TextFieldUI
別の方法は、リスナーを実装する独自の方法を作成することです。ただし、ファクトリアプローチははるかにエレガントです。
例:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalTextFieldUI;
public class CustomUI extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
UIManager.getDefaults().put("TextFieldUI", CustomTextFieldUI.class.getName());
new CustomUI().setVisible(true);
}
});
}
public CustomUI() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new FlowLayout());
add(new JTextField(10));
add(new JTextField(10));
pack();
}
public static class CustomTextFieldUI extends MetalTextFieldUI implements FocusListener {
public static ComponentUI createUI(JComponent c) {
return new CustomTextFieldUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
c.addFocusListener(this);
}
public void focusGained(FocusEvent e) {
getComponent().setBackground(Color.YELLOW.brighter());
}
public void focusLost(FocusEvent e) {
getComponent().setBackground(UIManager.getColor("TextField.background"));
}
}
}
ProperyChangeListener
あなたはKeyboardFocusManagerにアタッチすることができます@適切な変更を監視します