Le bloc notes Java |
L'architecture
MVC (Model-View-Controller)
est à la base de Swing. Elle apporte souplesse et
puissance dans le codage d'interface graphique. Pourtant,
quand il s'agit de l'appliquer à une interface graphique
réelle, les choses se gâtent. Voici quelques
solutions pour simplifier le codage d'interfaces graphiques en Java.
| package example; import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.beans.EventHandler; import javax.swing.Action; import javax.swing.DefaultBoundedRangeModel; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public final class MyForm { public final class Controller { Action actionMin = getAction("onButtonMin", "Min", null); Action actionMax = getAction("onButtonMax", "Max", null); Action closeAction = getAction("onClose", "Exit", null); ChangeListener changeListener = getChangeListener("onChange"); WindowListener windowListener = getWindowListener("onWindowEvent"); private Action getAction(final String command, final String name, Icon icon) { return new TrampolineAction(command, name, icon, this); } private ChangeListener getChangeListener(String method) { return (ChangeListener) EventHandler.create(ChangeListener.class, this, method, ""); } private WindowListener getWindowListener(String method) { return (WindowListener) EventHandler.create(WindowListener.class, this, method, ""); } public void onButtonMin(ActionEvent e) { model.boundedRangeModel.setValue(model.boundedRangeModel .getMinimum()); } public void onButtonMax(ActionEvent e) { model.boundedRangeModel.setValue(model.boundedRangeModel .getMaximum()); } public void onChange(ChangeEvent event) { view.label.setText("" + model.boundedRangeModel.getValue()); } public void onClose(ActionEvent e) { view.frame.dispose(); } public void onWindowEvent(WindowEvent e) { if (e.getID()==WindowEvent.WINDOW_ACTIVATED) { view.label.setText("Window Activated"); } } } private final class Model { DefaultBoundedRangeModel boundedRangeModel = new DefaultBoundedRangeModel(); } private final class View { JFrame frame; JLabel label; private void createAndShowGUI() { frame = new JFrame("Form Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.addWindowListener(controller.windowListener); label = new JLabel(" "); JButton btMax = new JButton(controller.actionMax); JButton btMin = new JButton(controller.actionMin); JButton closeBouton = new JButton(controller.closeAction); JSlider slider = new JSlider(model.boundedRangeModel); slider.addChangeListener(controller.changeListener); Container container=frame.getContentPane(); container.add(slider, BorderLayout.NORTH); container.add(btMax, BorderLayout.WEST); container.add(btMin, BorderLayout.CENTER); container.add(closeBouton, BorderLayout.EAST); container.add(label, BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } } private Controller controller; private Model model; private View view; public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new MyForm().view.createAndShowGUI(); } }); } public MyForm() { super(); model = new Model(); controller = new Controller(); view = new View(); } } |
| package example; import java.awt.event.ActionEvent; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; /** * The <code>TrampolineAction</code> call the command method of the controller * when the actionPerformed method is invoked. */ public class TrampolineAction extends AbstractAction { private final Object controller; private transient Method method; /* * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { try { if (method == null) { method = controller.getClass().getMethod( (String) getValue(Action.ACTION_COMMAND_KEY), new Class[] { ActionEvent.class }); } method.invoke(controller, new Object[] { e }); } catch (NoSuchMethodException ex1) { throw new RuntimeException(ex1); } catch (InvocationTargetException ex2) { throw new RuntimeException(ex2.getTargetException()); } catch (Exception ex3) { throw new RuntimeException(ex3); } } /** * TrampolineAction constructor. * @param command method name * @param name action name * @param icon action icon * @param controller controller object invoked on actionPerformed event. */ public TrampolineAction(String command, String name, Icon icon, final Object controller) { super(name, icon); this.putValue(Action.ACTION_COMMAND_KEY, command); this.controller = controller; } } |
| sujet |
liens |
|---|---|
| MVC | Model-View-Controller Pattern, MVC meets Swing The Java Tutorial |
| Différentes sortes de trampolines | Asserting Control Over the GUI |
| La classe EventHandler |
Class EventHandler, Using EventHandler for event listening, Proposal to reduce repetition with Swing and SWT listeners |
| MVC avec EventListener | Patterns for Java Events |
| MVC avec la reflexion (method) | Generating Event Listeners Dynamically, Putting Reflection to Work |
| MVC avec Dynamic Proxy | Using Dynamic Proxies to Generate Event Listeners Dynamically, The Dynamic Proxy API, Explore the Dynamic Proxy API, Dynamic Proxy Classes, EventInitializer librairie |
| MVC avec Observer/Observable pour les nostalgiques | Implementing The Model-View-Controller Paradigm using Observer and Observable, Building Graphical User Interfaces with the MVC Pattern |