2012-03-05 3 views
2

J'essaie d'obtenir des graphiques tracés pour actualiser/repeupler lorsque l'utilisateur choisit chacune des différentes options dans un JComboBox. Les exemples que j'ai trouvés sur le web utilisent tous des JLabels, ce qui peut convenir aux fichiers image, mais qui ne fonctionnent pas avec les graphiques personnalisés créés par paintComponent.repaint de JComboBox contrôle

J'ai essayé de rouler ma propre solution dans les ~ 60 lignes de code ci-dessous. J'utilise un exemple trivial d'un rectangle à redimensionner. Si vous compilez et exécutez le code ci-dessous, vous verrez qu'il ne repeint pas lorsque l'utilisateur sélectionne différentes options de JComboBox. En outre, je n'ai délibérément pas encore fait quoi que ce soit avec displayConstraints, car je ne veux pas imposer une solution si quelqu'un a une meilleure approche. Mon objectif est que le JComboBox soit affiché dans sa propre rangée en haut, et que le graphique tracé soit fait dans une deuxième rangée beaucoup plus grande sous la première rangée. La deuxième ligne absorbera tous les changements de redimensionnement, tandis que la première rangée restera plus ou moins de la même taille lorsque le JFrame est redimensionné. En choisissant différentes options de JComboBox, l'utilisateur sera en mesure de rendre le rectangle tracé plus petit ou plus grand par rapport à la taille actuelle du JFrame. Est-ce que quelqu'un peut me montrer comment réparer le code ci-dessous afin qu'il accomplisse mes buts mentionnés ci-dessus?

import java.awt.Graphics; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 

public class ComboBox extends JFrame implements ItemListener { 
final String[] sizes = { "10%", "20%", "33%" }; 
JComboBox combobox = new JComboBox(sizes); 
int selectedIndex; 

public ComboBox() { 
    setLayout(new GridBagLayout()); 
    combobox.setSelectedIndex(-1); 
    combobox.addItemListener(this); 
    GridBagConstraints comboBoxConstraints = new GridBagConstraints(); 
    comboBoxConstraints.gridx = 0; 
    comboBoxConstraints.gridy = 0; 
    comboBoxConstraints.gridwidth = 1; 
    comboBoxConstraints.gridheight = 1; 
    comboBoxConstraints.fill = GridBagConstraints.NONE; 
    add(combobox,comboBoxConstraints);//This should be placed at top, in middle. 

    GridBagConstraints displayConstraints = new GridBagConstraints(); 
    displayConstraints.gridx = 0; 
    displayConstraints.gridy = 1; 
    displayConstraints.gridwidth = 1; 
    displayConstraints.gridheight = 1; 
    displayConstraints.fill = GridBagConstraints.BOTH; 
    //I am aware that nothing is done with displayConstraints. 
    //I just want to indicate that the rectangle should go below the combobox, 
    //and that the rectangle should resize while the combobox should not. 
    //Other suggested approaches are welcome. 

    setSize(300, 300); 
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    setLocationRelativeTo(null); 
    setVisible(true); 
} 

public static void main(String[] args) {new ComboBox();} 

public void itemStateChanged(ItemEvent e) { 
    if (e.getStateChange() == ItemEvent.SELECTED) { 
     JComboBox combo = (JComboBox) e.getSource(); 
     selectedIndex = combo.getSelectedIndex(); 
     System.out.println("selectedIndex is: "+selectedIndex); 
     repaint(); 
    } 
} 
protected void paintComponent(Graphics g){ 
    int scaleFactor = 1; 
    if(selectedIndex==0){scaleFactor = 10;} 
    if(selectedIndex==1){scaleFactor = 5;} 
    if(selectedIndex==2){scaleFactor = 3;} 
    if(selectedIndex!=-1){ 
     int xStart = (getWidth()/2)-(getWidth()/scaleFactor); 
     int yStart = (getHeight()/2)-(getHeight()/scaleFactor); 
     g.drawRect(xStart, yStart, (getWidth()/scaleFactor), (getHeight()/scaleFactor)); 
    } 
} 
} 
+0

question était bien avant l'édition – CodeMed

+0

Vous pouvez annuler la modification, mais il semble OK maintenant. – trashgod

Répondre

3

Vous ne devriez pas tirer directement dans un JFrame et même si vous avez fait, JFrame n'a pas de méthode de paintComponent. Utilisez une annotation @Override pour voir par vous-même. Au lieu de cela, tracez un JPanel ou JComponent, faites le dessin dans paintComponent et assurez-vous que vous avez correctement écrasé la méthode avec l'annotation override.

Par exemple:

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

public class ComboBoxTest extends JPanel implements ItemListener { 
    private static final int PREF_W = 300; 
    private static final int PREF_H = PREF_W; 
    final String[] sizes = { "10%", "20%", "33%" }; 
    JComboBox combobox = new JComboBox(sizes); 
    int selectedIndex; 
    private double scaleFactor = 1; 

    public ComboBoxTest() { 
     setLayout(new GridBagLayout()); 
     combobox.setSelectedIndex(-1); 
     combobox.addItemListener(this); 
     GridBagConstraints comboBoxConstraints = new GridBagConstraints(); 
     comboBoxConstraints.gridx = 0; 
     comboBoxConstraints.gridy = 0; 
     comboBoxConstraints.gridwidth = 1; 
     comboBoxConstraints.gridheight = 1; 
     comboBoxConstraints.fill = GridBagConstraints.NONE; 
     add(combobox, comboBoxConstraints);// This should be placed at top, in 
             // middle. 

     GridBagConstraints displayConstraints = new GridBagConstraints(); 
     displayConstraints.gridx = 0; 
     displayConstraints.gridy = 1; 
     displayConstraints.gridwidth = 1; 
     displayConstraints.gridheight = 1; 
     displayConstraints.fill = GridBagConstraints.BOTH; 
    } 

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

    public void itemStateChanged(ItemEvent e) { 
     if (e.getStateChange() == ItemEvent.SELECTED) { 
     JComboBox combo = (JComboBox) e.getSource(); 
     selectedIndex = combo.getSelectedIndex(); 
     System.out.println("selectedIndex is: " + selectedIndex); 
     if (selectedIndex == -1) { 
      return; 
     } 
     String selectedItem = combo.getSelectedItem().toString().trim(); 
     selectedItem = selectedItem.replace("%", ""); 
     scaleFactor = Double.parseDouble(selectedItem)/100.0; 
     repaint(); 
     } 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     int xStart = (getWidth()/2) - (int)(getWidth() * scaleFactor); 
     int yStart = (getHeight()/2) - (int)(getHeight() * scaleFactor); 
     g.drawRect(xStart, yStart, (int)(getWidth() * scaleFactor), 
       (int)(getHeight() * scaleFactor)); 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("ComboBoxTest"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new ComboBoxTest()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

+1 pour une réponse rapide. Je marque cela comme la réponse, mais il place toujours la combobox au milieu du cadre au lieu de haut. Je vais essayer de corriger ce détail plus tard quand j'aurai plus de temps pour ça. – CodeMed

+0

@CodeMed: Pour le mettre en haut, utilisez un autre gestionnaire de disposition. Moi-même je mettrais le JComboBox dans un FlowLayout en utilisant JPanel et placerais JPanel dans l'autre JPanel (le panneau principal) qui utilise BorderLayout dans la position BorderLayout.NORTH. –

0

Du haut de ma tête, sans tester ce que je suis venu avec. Faire un sous-classes JPanel qui remplace paintComponent où vous faites vos graphiques (comme ce que Hovercraft Full Of Eels a dit). Ajouter à la JFrame. Maintenant, faire ajouter un ActionListener (au lieu d'un ItemListener) à votre zone de liste déroulante:

public void actionPerformed(ActionEvent evt) { 
    //do other stuff... 
    yourGraphicsPanel.repaint(); 
} 

yourGraphicsPanel est une instance de vous de la sous-classe JPanel.

J'espère que ça aide! :)