Cours interface graphique en Java, tutoriel & guide de travaux pratiques JAVA en pdf.
Le presse-papier
● on écoute les changements pour mettre à jour la liste des DataFlavor:
public static void main(String[] args) {
…
…
}
final DefaultListModel model=new DefaultListModel(); updateModel(clipboard,model);
f.getContentPane().add(new JScrollPane(new JList(model)),BorderLayout.WEST); clipboard.addFlavorListener(new FlavorListener() {
@Override
public void flavorsChanged(FlavorEvent e) { updateModel(clipboard,model);
}
});
protected static void updateModel(Clipboard clipboard, DefaultListModel model) { model.clear();
DataFlavor[] flavors=clipboard.getAvailableDataFlavors(); for (int i=0;i<flavors.length;i++) {
model.addElement(flavors[i].getMimeType());
}
}
● récupération d’une image:
protected static JComponent getPastedImage(Clipboard clipboard) { try {
Image img = (Image) clipboard.getData(DataFlavor.imageFlavor); return new JLabel(new ImageIcon(img));
}
catch (IllegalStateException e1) {
/* Clipboard access can fail */
return null;
}
catch (UnsupportedFlavorException e) {
return null; /* Should not happen */
}
catch (IOException e) {
return null; /* Should not happen */
}
}
les accès peuvent échouer sur certains systèmes
● on obtient du texte ou une liste de fichiers de la même façon:
protected static JComponent getPastedText(Clipboard clipboard) { try {
String s = (String) clipboard.getData(DataFlavor.stringFlavor); return new JTextArea(s);
}
…
}
protected static JComponent getPastedFiles(Clipboard clipboard) { try {
List<File> files = (List<File>)clipboard.getData(DataFlavor.javaFileListFlavor); return new JList(files.toArray());
}
…
}
● résultat:
Mettre du contenu personnalisé
● on peut mettre ce que l’on veut dans le presse-papier, pour peu que l’on définisse une classe de représentation qui implémente Transferable:
– Object getTransferData(DataFlavor flavor)
● obtenir les données sous une forme précise
– DataFlavor[] getTransferDataFlavors()
● obtenir la liste des DataFlavor supportées par les données
– boolean isDataFlavorSupported(DataFlavor f)
● exemple: transférer des JButton
public class ButtonSelection implements Transferable {
public final static DataFlavor buttonFlavor=new DataFlavor(JButton.class, »buttonFlavor »); private final static DataFlavor[] supportedFlavors=new DataFlavor[] {buttonFlavor}; private JButton button;
public ButtonSelection(JButton b) {
this.button=b;
}
@Override public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if (!buttonFlavor.equals(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return button;
}
@Override public DataFlavor[] getTransferDataFlavors() { return supportedFlavors;
}
@Override public boolean isDataFlavorSupported(DataFlavor flavor) { return buttonFlavor.equals(flavor);
}
}
● application: utiliser des JPopupMenu pour couper/coller des JButton
● création de boutons avec des listeners sérialisables:
static abstract class SerializableActionListener implements ActionListener,Serializable {
/* We just need to indicate that we want a serializable ActionListener */
}
final static Random random=new Random();
private static Component createButton(String title,final String message) {
int n=random.nextInt(1000);
JButton b=new JButton(title+ » « +n);
/* We don’t want to inheritate the JPanel popup menu */
b.setInheritsPopupMenu(false);
b.setComponentPopupMenu(cutPopup);
final String id= »Message ID: « +n;
b.addActionListener(new SerializableActionListener () {
@Override public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,message,id,JOptionPane.INFORMATION_MESSAGE);
}
});
return b;
}
● création de l’action « Cut »: on enlève le bouton de son panel et le met dans le presse-papier
final Action cut=new AbstractAction(« Cut button ») {
@Override
public void actionPerformed(ActionEvent e) {
JButton b=(JButton)cutPopup.getInvoker();
/* We don’t want the popup menu to be serialized, since we
* have a static final reference on it. Better to restore it
* at paste time.
*/
b.setComponentPopupMenu(null);
JPanel p=(JPanel)b.getParent();
p.remove(b);
p.revalidate();
p.repaint();
try {
clipboard.setContents(new ButtonSelection(b),null); } catch (IllegalStateException e1) {
/* Do nothing */
}
}
};
cutPopup.add(new JMenuItem(cut));
● création de l’action « Paste »: on récupère un bouton du presse-papier et on le met dans le panel
final Action paste=new AbstractAction(« Paste button ») { @Override
public void actionPerformed(ActionEvent e) {
JPanel p=(JPanel)pastePopup.getInvoker();
try {
JButton b=(JButton) clipboard.getData(ButtonSelection.buttonFlavor); /* We have to restore the popup menu */ b.setComponentPopupMenu(cutPopup);
p.add(b);
p.revalidate();
p.repaint();
} catch(IllegalStateException e1) { /* Do nothing */
} catch (UnsupportedFlavorException e1) {
/* Should not happen */
} catch (IOException e1) {
/* Should not happen */
}
}
};
● on peut ainsi couper-coller des boutons, éventuellement plusieurs fois
● comme on utilise le presse-papier système, on peut coller un bouton qui a été coupé dans une session précédente.
………