Zaloguj się
Projekty Kategorie Archiwum
13 listopada

Przed:

...
showClose.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
		JCheckBox source = (JCheckBox)e.getSource();
		closeButton.setVisible(source.isSelected());
	}
} );
...

Po:

...
showClose.onSelect(closeButton, "visible");
...

Jak widać, druga wersja jest znacznie krótsza :) Cała tajemnica tkwi w klasie EventHandler, która tworzy za nas odpowiednie zdarzenia oraz ustawia odpowiednie właściwości obiektu. Prosta implementacja klasy MyCheckBox oraz MyButton wygląda tak:

MyCheckBox

public class MyCheckBox extends javax.swing.JCheckBox {
	
	public MyCheckBox(String text) {
		super(text);
	}

	public void onSelect(Object target, String propertyName) {
		addActionListener(java.beans.EventHandler.create(
			java.awt.event.ActionListener.class,
			target,
			propertyName,
			"source.selected"
		));
	}

}

Uwaga: "propertyName" musi być nazwą właściwości obiektu "target", zgodną ze specyfikacją JavaBeans™.

MyButton

public class MyButton extends javax.swing.JButton {
	
	public MyButton(String text) {
		super(text);
	}
	
	public void onClick(Object target, String action) {
		addActionListener(java.beans.EventHandler.create(
			java.awt.event.ActionListener.class,
			target,
			action
		));
	}

}

Uwaga: "action" musi być nazwą publicznej metody obiektu "target".

Program testowy

public class Main extends javax.swing.JFrame {
	Main() {
		super("Test");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		MyButton closeButton = new MyButton("Close");

		// po kliknięciu, okno zostanie zamknięte
		// ( odpowienik wywołania this.dispose() )
		closeButton.onClick(this, "dispose");

		add(closeButton);

		MyCheckBox showClose = new MyCheckBox("Show Close Button");
		showClose.setSelected(true);

		// po kliknięciu, przycisk "Close" zostanie ukryty/pokazany
		// ( odpowiednik closeButton.setVisible(showClose.isSelected()) )
		showClose.onSelect(closeButton, "visible");
		
		add(showClose, java.awt.BorderLayout.NORTH);

		MyCheckBox allEnabled = new MyCheckBox("Enabled");
		allEnabled.setSelected(true);
		allEnabled.onSelect(closeButton, "enabled");
		allEnabled.onSelect(showClose, "enabled");
		add(allEnabled, java.awt.BorderLayout.SOUTH);

		pack();
		setVisible(true);
	}
	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() { new Main(); }
		} );
	}
}

Proszę o komentarz

nullpointer
Czwartek 13 listopada, 2008 11:44

Fajne, trochę jak sloty w QT.
Jest jakieś IDE, które generuje coś takiego?

nullpointer
Czwartek 13 listopada, 2008 11:46

Powyżej, to taka ironia trochę była. Nie widzę sensu, aby tworzyć własną nadbudówkę każdego komponentu swinga, tylko po to, żeby zaoszczędzić na tworzeniu listenerów.

Ale pomysł byłby ciekawy, gdyby go SUN zaimplementował standardowo.

Czwartek 13 listopada, 2008 12:54

@nullpointer: nadbudówki są fajne, bo niektóre koponenty Swinga mocno obsysają, a nie będe przecież czekał 10 lat, aż Sun coś poprawi w API. Mogłoby być w standardzie, ale na razie bardzo wątpie w to, czy kiedyś tak się stanie ;)

Wynik kolejnych eksperymentów :) Załóżmy, że mamy komponent JList z elementami A, B, C, i chcemy, żeby pole tekstowe JTextField miało zawsze zawartość wybranego elementu z listy:

JTextField text = new JTextField();
MyList textList = new MyList("A", "B", "C");
textList.bind(text, "text"); // <--
public class MyList extends javax.swing.JList {

public MyList(Object... items) {
super(items);
}

public void bind(Object target, String propertyName) {
addListSelectionListener(java.beans.EventHandler.create(
javax.swing.event.ListSelectionListener.class,
target,
propertyName,
"source.selectedValue"
));
}

}
nullpointer
Czwartek 13 listopada, 2008 21:58

Nadbudówki są fajne, to fakt. Niestety ciężko tą fajność wykorzystać w praktyce przy dużym projekcie (a z takimi mam do czynienia). Jeśli masz np. aplikację składającą się z 1000 formularzy i robisz ją w JDeveloperze i ADFie, to powyższe rozwiązanie więcej Ci nabruździ, niż pomoże. Utworzenie odpowiedniego listenera w tym środowisku to dwa kliknięcia + linijka kodu. Zmuszenie go do używania „fajnej nadbudówki” jest albo niemożliwe, albo katorżniczo trudne.

Niemniej, przy czysto akademickim podejściu – pomysł jest ciekawy (powtarzam się, ech ;-))

Piątek 14 listopada, 2008 00:10

Jak poprzednik uważam, ze pomysł jest ciekawy, aczkolwiek mało wydajny w praktyce.

Piątek 14 listopada, 2008 09:04

Yy, nie mógłbyś sobie zamiast tego utworzyć fabryki generującej i zwracającej takiego listenera, tak żebyś nie musiał nadpisywać każdej Swingowej kontrolki? Pisania sumarycznie mniej ;)

Piątek 14 listopada, 2008 13:14

@sztywny: mógłbym, ale nic nie wygląda tak pięknie jak foo.onClick ;)

Napisz komentarz

Dodaj komentarz

Formatowanie komentarza

Kategorie

Ewolucja Internetu 8 | Fail 40 | Gry 46 | Humor 129 | Idiotyzm 50 | Java 110 | KDE 85 | KShutDown 22 | Linux 84 | Makagiga 58 Muzeum 3 | Ogólne 819 | Polityka 76 | Programowanie 51 | Reklamy 4 | Techblog 19 | Teorie Spiskowe 12 | TV 59 | UI 9 | Użyteczność 30 | WWW 90 | Wyrwane z Kontekstu 34 | X Files 14

Archiwum

Maj 2012 | Kwiecień 2012 | Marzec 2012 | Luty 2012 | Styczeń 2012 | Grudzień 2011 | Listopad 2011 | Październik 2011 | Wrzesień 2011 | Sierpień 2011 | Lipiec 2011 | Czerwiec 2011 | Maj 2011 | Kwiecień 2011 | Styczeń 2011 | Listopad 2010 | Październik 2010 | Wrzesień 2010 | Sierpień 2010 | Lipiec 2010 | Czerwiec 2010 | Kwiecień 2010 | Marzec 2010 | Luty 2010 | Styczeń 2010 | Grudzień 2009 | Listopad 2009 | Październik 2009 | Wrzesień 2009 | Sierpień 2009 | Lipiec 2009 | Czerwiec 2009 | Maj 2009 | Kwiecień 2009 | Marzec 2009 | Styczeń 2009 | Grudzień 2008 | Listopad 2008 | Październik 2008 | Wrzesień 2008 | Sierpień 2008 | Lipiec 2008 | Czerwiec 2008 | Maj 2008 | Kwiecień 2008 | Marzec 2008 | Luty 2008 | Styczeń 2008 | Grudzień 2007 | Listopad 2007 | Październik 2007 | Wrzesień 2007 | Sierpień 2007 | Lipiec 2007 | Czerwiec 2007 | Maj 2007 | Kwiecień 2007 | Marzec 2007 | Luty 2007 | Styczeń 2007 | Grudzień 2006 | Listopad 2006 | Październik 2006 | Wrzesień 2006 | Sierpień 2006 | Lipiec 2006 | Czerwiec 2006 | Maj 2006 | Kwiecień 2006 | Marzec 2006 | Luty 2006 | Styczeń 2006 | Grudzień 2005 | Listopad 2005 | Październik 2005 | Wrzesień 2005 | Sierpień 2005 | Lipiec 2005 | Czerwiec 2005 | Maj 2005 | Kwiecień 2005 | Marzec 2005 | Luty 2005 | Styczeń 2005