2017-05-07 1 views
0

Je ne suis pas nouveau à Java et à la POO mais je suis nouveau à balancer.Java Swing: tâche facile, mais j'échoue

Je veux écrire un logiciel pour construire des pedigrees. Cela signifie: faites un clic droit au milieu de la zone de dessin et choisissez "Nouveau -> Homme". Un rectangle apparaît là où j'ai cliqué avec le bouton droit de la souris. Puis je clique sur le rectangle et choisis "Nouveau -> Frère -> Femme" et le pedigree se développe dynamiquement avec un cercle qui est relié au rectangle. Vous avez eu l'idée.

De plus, j'ai besoin de sauvegarder des informations pour chaque nœud du pedigree. Tels que "mutation dans le gène x: positif". Je pensais que cela doit être parfait pour la POO. J'ai besoin que chaque noeud de mon pedigree soit une instance qui s'inspire de la zone de dessin. Alors ... un Jpanel? J'étend JPanel, je donne à cette classe quelques attributs (tels que "int mutationX = 1") et une méthode pour s'ajouter au JFrame. Pour le moment, j'essaie seulement d'ajouter un rectangle au milieu de l'écran via le menu. Pas facile pour un débutant swing. Mais le rectangle désiré n'apparaît pas. Donc, fondamentalement, mes questions sont les suivantes:

  1. Suis-je même en train de résoudre ce que j'essaie de faire?
  2. Pourquoi le rectangle n'apparaît-il pas?

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class HelloWorld 
{ 
    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame("Hello World"); 

     JPanel mainpanel = new JPanel(); 

     JScrollPane scroll = new JScrollPane(mainpanel); 

     frame.add(scroll); 

     JMenuBar menubar = new JMenuBar(); 
     frame.setJMenuBar(menubar); 

     JMenu file = new JMenu("File"); 
     menubar.add(file); 

     JMenuItem exit = new JMenuItem("Exit"); 
     exit.addActionListener(
       new ActionListener(){ 
        public void actionPerformed(ActionEvent ae){ 
         System.exit(0); 
        } 
       } 
     ); 

     file.add(exit); 

     JMenuItem newMember = new JMenuItem("Add"); 
     newMember.addActionListener(
       new ActionListener(){ 
        public void actionPerformed(ActionEvent ae){ 
         FamilyMember fm = new FamilyMember(); 
         mainpanel.add(fm); 
         mainpanel.revalidate(); 
        } 
       } 
     ); 
     file.add(newMember); 

     frame.setLocation(400, 100); 
     frame.setPreferredSize(new Dimension(500,500)); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
} 

    public class FamilyMember extends JPanel { 

    @Override 
    protected void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.drawRect(230,80,10,10); 
     g.setColor(Color.RED); 
     g.fillRect(230,80,10,10); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(50, 50); 
     } 


} 
+1

Vous devez en savoir plus. mainpanel a (par défaut) un FlowLayout, donc les rectangles, quand ils apparaissent, apparaîtront à droite les uns des autres, avec le preferredSize que vous définissez à 50x50, alors que vous peignez après 230,80. –

+0

@LaurentG Avec un peu d'expansion, cela pourrait être une réponse .. –

+1

@AndrewThompson Je viens de répondre à la deuxième partie, celle que je peux résumer, mais assez pour pointer les problèmes sur le chemin. Je voulais juste donner des conseils pour permettre à l'OP de passer à autre chose. Je ne suis pas, de loin, aussi efficace que vous les (trois?) Grands gars du swing sur SO. Je vais essayer d'apprendre, mais je ne peux rien promettre. –

Répondre

0

Pour le deuxième point (pourquoi, a minima, il ne fonctionne pas/montrer tout rectangle), vous pouvez jeter un oeil à docs Oracle (de plus précis à la préoccupation plus large):

En bref,

votre instance JPanel mainpanel a un FlowLayout en tant que gestionnaire de mise en page (qui est la valeur par défaut pour une nouvelle instance)

une mise en page de flux utilisera chaque taille préférée enfant

et vous forcer la taille préférée de votre FamilyMember à 50x50

mais vous voulez dessiner seulement au sud-est de 230,80 qui n'est pas dans la zone 50x50.

=> il n'apparaîtra pas.

Pour le premier point, je dirais d'abord: séparer le modèle de la vue.