Un tableau de IBOutlet et de IBAction
Herve
Membre
Bonjour,
Je découvre votre site qui a l'air très intéressant. Débutant en Cocoa, je ferai de mon mieux pour vous aider néanmoins.
Après des années de Java, je me lance dans ObjectivC/Cocoa. Super!
Je voulais donc adapter un logiciel fait en Java pour bénéficier des méthodes plus complètes de Cocoa. Dans ce logiciel, j'avais fait des tableaux de boutons initialisés grâce à des tableaux de valeurs et une grille de placement sur la fenêtre.
Le code était du genre :
Ce code permettait de créer en quelques lignes 66 boutons, puis 44 pour une autre série, et enfin 24 pour la dernière, avec placement, couleur, et écoute (l'équivalent Java du IBAction).
En Cocoa, j'ai vu les "matrix", mais j'ai dû dériver NSButton pour les mettre en couleur, et les CustomView utilisées dans InterfaceBulder ne semblent pas être "matriciables" (pardon pour le barbarisme).
Verriez-vous une possibilité autre que de rentrer 134 IBOutlet et autant de IBActions dans le code de ObjectivC? (cent trente quatre, et plus encore!! mais les autres sont des boutons Aqua normaux, et il n'y en a pas trop)
Merci d'avance si vous avez une idée.
Je découvre votre site qui a l'air très intéressant. Débutant en Cocoa, je ferai de mon mieux pour vous aider néanmoins.
Après des années de Java, je me lance dans ObjectivC/Cocoa. Super!
Je voulais donc adapter un logiciel fait en Java pour bénéficier des méthodes plus complètes de Cocoa. Dans ce logiciel, j'avais fait des tableaux de boutons initialisés grâce à des tableaux de valeurs et une grille de placement sur la fenêtre.
Le code était du genre :
for (int i = 0; i<66; i++){<br /> BoutonTriangle[i] = new JButton();<br /> BoutonTriangle[i].setPreferredSize(new Dimension(10,10));<br /> GBC.gridx = (XTriangle[i]+2); GBC.gridy = (YTriangle[i]+2);<br /> GBC.gridwidth = 2; GBC.gridheight = 2;<br /> GBC.weightx = 2; GBC.weighty = 2;<br /> BoutonTriangle[i].addActionListener<br /> (new EcouteBoutonTriangle (i, ValCoul, ValTri, ValPal, Tab, palette, action));<br /> BoutonTriangle[i].setBackground(<br /> Color.getHSBColor(action.getHueFond(), ValTri[i].getSaturation(),<br /> ValTri[i].getBright()));<br /> add (BoutonTriangle[i], GBC);<br /> } <br />
Ce code permettait de créer en quelques lignes 66 boutons, puis 44 pour une autre série, et enfin 24 pour la dernière, avec placement, couleur, et écoute (l'équivalent Java du IBAction).
En Cocoa, j'ai vu les "matrix", mais j'ai dû dériver NSButton pour les mettre en couleur, et les CustomView utilisées dans InterfaceBulder ne semblent pas être "matriciables" (pardon pour le barbarisme).
Verriez-vous une possibilité autre que de rentrer 134 IBOutlet et autant de IBActions dans le code de ObjectivC? (cent trente quatre, et plus encore!! mais les autres sont des boutons Aqua normaux, et il n'y en a pas trop)
Merci d'avance si vous avez une idée.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
D'autre part, le passage d'un langage a un autre n'est pas toujours facile. Chaque langage à ses particularités et essayer de copier une méthodologie d'un langage à un autre n'est pas forcément la chose à faire.
Oui, NSMatrix ne fonctionne qu'avec des NSCell (je n'ai jamais eu besoin d'utiliser les matrices, alors je ne connais pas les détails).
Pour info, NSMatrix est une implémentation du design pattern Prototype. Ce système a donc été conçu pour améliorer les performances (vitesse/occupation mémoire) quand on a un grand nombre de contrôles identiques. Note que ce ne sont pas des NSButton dans la matrice, mais des NSButtonCells.
NSButtonCell ne peut pas être colorié, il me semble. Sous-classer est la seule solution.
On peut tout à fait créer les boutons par le code. Cependant, dans ce cas, tu n'auras pas d'outlets, puisque les outlets sont des pointeurs sur objets initialisés lors du désarchivage du NIB. Tu auras de "simples" pointeurs.
ça donnerait quelque chose comme ça:
Note bien que pour ce que tu veux faire, la bonne méthode est d'utiliser une matrice, encore une fois, pour des questions de performance.
Pour finir, je rejoins l'avis de tablier: ne cherche pas trop à retranscrire ton expérience Java dans Cocoa. Swing n'est certainement pas un modèle à suivre; mon expérience est que créer des IHM par des ressources est bien plus rapide et précis que le faire par le code.
Céroce, j'ai lu que l'on pouvait écrire en Cocoa avec "l'orthographe" (ou le style) Java. Mais j'ai appris le style C aussi. C'est marrant d'ailleurs que ce langage accepte deux "orthographes" : Apple nous surprendra décidément toujours...
J'allais dans mes réflexions du jour vers ce type de solution: un NSView avec un IBOutlet et un IBAction, liés à une classe qui gère les choses en interne. Il faut que j'étudie les "NSCell" et dérivations : je les ai un peu snobé - ou plutôt survolé - lors de la lecture du livre de Hillegards parce que il traitait de tableaux type Excell, mais il semble que ce soit plus riche que cela...
Je travaille ce WE, je vous tiens au courant. Si je trouve la solution, je la copie ici.
Après une journée passée à étudier les NSCell sans en voir l'intérêt pour mon problème, je me rends compte que Céroce a fait un travail magnifique. Merci beaucoup Céroce.
En fait, je ne savais pas que l'on pouvait instancier un tableau avec "NSButton *buttons[ROWS]
Merci beaucoup Céroce.
Je voulais savoir :
J'ai écrit :
NSButton *mesBoutons[66]; (dans "AppView.h")
Est-ce que j'aurais dû mettre [66][1]???
En écrivant cela, est-ce que je crée un "CFArray", un "NSArray" ou autre chose encore?? Cette écriture me rappelle les tableaux 2D de Java.
J'ai essayé pour l'initialiser (dans la méthode init de l'AppView) :
mesBoutons = [[NSArray alloc]init]; ou mesBoutons = [[CFArray alloc]init];
le compilateur rejette les deux.
Je pense que cela ne s'affiche pas à cause de l'initialisation de ce tableau. Qu'en pensez-vous?
Rien à voir avec la couche Objective-C du langage finalement. C'est un tableau statique de type ceux qu'on voit en langage C, rien à voir donc avec les NSArrays.
Si tu veux utiliser les NSArray, il faut bah... utiliser les NSArray :P
Donc, pour solution en utilisant des tableaux C statiques (ne pouvant être redimentionnés, et sur lesquels tu ne pourras pas appeler de méthodes pour demander leur nombre d'éléments, etc) tu fais pareil que si tu avais un seul NSButton sauf que tu le mets dans la i-ème case du tableau mesButtons : Et la solution avec NSArray : Y'a encore d'autres solutions avec les NSArray, entre autres utiliser plutôt un NSMutableArray qui peut donc modifier son contenu, et faire "addObject" à chaque bouton... bref t'as le choix.
Après si ton nombre de boutons est statique par essence, le tableau C est plus simple et plus rapide. L'avantage de NSArray étant que c'est lui-même un NSObject (qui peut être manipulé comme tel, être mis dans un conteneur, être archivé/sérialisé, suit les règles de gestion mémoire et retiens son contenu...) donc à toi de voir.
Dans tous les cas, quelle que soit la solution que tu choisis... c'est bien beau de créer un NSButton ou une NSView ou quoi que ce soit par code... mais ne pas oublier dans ce cas de l'ajouter en tant que subview à une vue qui est à l'écran, sinon tu ne la verra jamais à l'écran Par exemple l'ajouter à ta keyWindow.
J'écris ici que les boutons sont initialisés mais ne s'affichent pas : une unième modif et ils s'affichent!!
Aussi je réédite mon message. Les boutons s'affichent enfin, mais ne répondent pas encore.
Merci à tous pour votre aide.
Pour que mes boutons communiquent avec l'AppController, j'ai mis dans la classe MonBouton :
et dans l'AppController :
Le mouseDown du bouton est bien appelé, mais n'est pas reçu par l'AppController. La méthode "- (void) monBoutonClick: (MonBouton *) sender" n'est pas appelée. J'ai essayé aussi [self target], [self state] etc.
Sans la méthode mouseDown dans MonBouton, j'ai un NullPointerException lorsque je clique sur le bouton.
Vous n'auriez pas une idée s'il vous plaà®t??
Mes débuts en Java avaient été difficiles aussi. Après, ça allait mieux...
Révise le Programming Guide sur le mécanisme "Target-Action", et la documentation sur NSControl !!!
Tu n'as pas à surcharger mouseDown (et c'est une mauvaise idée sur les NSButtons vu qu'ils implémentent déjà cette méthode avec derrière le mécanisme de target/action justement) mais plutôt à indiquer un target et une action à ton bouton
Control and Cell Programming Guide
NSControl class reference : implementing the Target/Action Mechanism
L'AppController reçoit l'info mais ne sait pas l'interpréter.
Bon, je cherche encore...
En fait, j'avais changé la méthode
par
Aussi...
Dans cette méthode, j'ai fait :
ça marche. Y a t-il mieux??
Merci encore à tous pour votre aide. J'essaierai d'aider ici aussi, en fonction de mes progrès...
Problème résolu : l'indique t-on dans ce forum? Je ne vois pas l'onglet.
Une question : pourquoi as-tu sous-classé NSButton ? Est-ce vraiment toujours utile maintenant que tu as compris comment tout cela marche ? A priori il n'y a aucun besoin de le faire (sauf si tu veux effectivement personnaliser plus encore le look du bouton ou quoi, mais ce n'est pas nécessaire pour juste créer une grille de boutons et leur affecter une action)
Sinon pour "Résolu" il n'y a aucun bouton sur les forums pour le faire (cela a fait l'objet d'un petit débat pour/contre, enfin bon) mais si tu souhaites le mentionner, tu peux éditer ton tout premier message de ce sujet pour modifier le titre et rajouter "[Résolu]" au début du titre du sujet.
Pouvoir personnaliser l'interface utilisateur et créer toutes sortes de contrôles est, avec la richesse des classes multimédia et son une des raisons qui m'ont fait passer à Cocoa, malgré le fait de devoir apprendre un nouveau langage.
Merci encore AliGator pour ton aide, ainsi qu'à Céroce.
avec ou sans utiliser IB, mais probablement plus facile avec, tu as aussi la classe NSCollectionView qui permet d'afficher la même vue (qui peut être un bouton donc puisqu'un NSButton est un NSControl qui est une NSView..) dans autant de lignes et colonnes que tu le veux en les liant à un tableau via un NSArrayController. Je me demande si ça aurait pu aider car il me semble que c'est la manière la plus "Cocoa" avec bindings et MVC. http://developer.apple.com/library/mac/#documentation/cocoa/Reference/NSCollectionView_Class/Introduction/Introduction.html
Bref, c'est difficile à expliquer sans la voir en fonctionnement, mais le rôle de NSCollectionView est différent, et je ne crois pas que ce soit ce qu'Hervé cherchait à faire.