2010-11-13 7 views
3

Je fais un projet où j'ai besoin de composants swing personnalisés. Jusqu'à présent, j'ai créé un nouveau bouton avec une série d'images (le look Java Metal ne correspond pas du tout à mon interface). J'ai implémenté MouseListener sur ce nouveau composant et c'est là que mon problème se pose. Mon widget change d'image en survol, cliquez sur etc. sauf que mon MouseListener saisit l'entrée de la souris dans le conteneur GridLayout au lieu de l'insérer dans l'image. Donc, j'ai une image d'environ 200 * 100 et le conteneur environnant est d'environ 400 * 200 et la méthode mouseEntered est tirée quand il entre dans cette section GridLayout (même les parties vides de l'espace) au lieu de sur l'image. Comment puis-je faire en sorte qu'il ne soit tiré que lorsque je survole l'image? J'ai essayé de régler la taille et les limites et d'autres attributs en vain.Java swing JComponent "taille"

EDIT: Voici une démonstration de mon problème. Comme vous pouvez le voir (en quelque sorte, les couleurs sont très similaires), le bouton en bas à droite est mis en évidence juste en entrant sa section du GridlLayout. Je veux seulement le mettre en surbrillance quand je suis sur l'image réelle, pas la section GridLayout.

alt text

I Will not ajouter les méthodes MouseListener car ils impliquent simplement passer l'image affichée.

public customWidget() 
{ 
    this.setLayout(new FlowLayout()); 
    try { 
     imageDef=ImageIO.read(new File("/home/x101/Desktop/buttonDef.png")); 
     imageClick=ImageIO.read(new File("/home/x101/Desktop/buttonClick.png")); 
     imageHover=ImageIO.read(new File("/home/x101/Desktop/buttonHover.png")); 
     current=imageDef; 
    } catch (IOException e) 
    { 

     e.printStackTrace(); 
    } 
    this.addMouseListener(this); 
} 

protected void paintComponent(Graphics g) 
{ 
    super.paintComponents(g); 
    g.drawImage(current, 0, 0, current.getWidth(), current.getHeight(), null); 

} 

EDIT: section de code ajouté

+0

veuillez poster un échantillon de code autonome ...Il est plus facile de voir ce que vous essayez de faire ... et plus facile de trouver le problème ... –

+0

Quelle est la superclasse de 'customWidget'? De même, où votre 'conteneur GridLayout' est-il configuré? –

+0

customWidget étend JComponent. Le GridLayout est mis en place dans le programme de test en utilisant pour tester le widget. Va mettre en place une image pour démontrer. – Alex

Répondre

3

Je suppose que votre image ne contient que 4 objets 'customWidget' (dans une grille 2x2).

Votre code fonctionne comme prévu. Vos méthodes MouseListener répondent à MouseEvents pour 'customWidget' (pas l'image dessinée dans 'customWidget'), qui est dimensionné pour occuper 1/4 de l'image, donc ils répondront quand il pénètre dans la zone agrandie. L'erreur est en fait dans votre programme de test, car vous autorisez le widget de bouton personnalisé à être plus grand que l'image. Si vous voulez un programme de test qui fournit une image similaire à la vôtre, vous devez créer une grille plus grande (disons 4x4), puis ne placer vos boutons que dans tous les autres nœuds de la grille. Placez un composant vide dans les espaces.

+0

Vous êtes exactement sur mon train de pensée. Y a-t-il un gestionnaire de disposition qui faciliterait la définition d'une section sur l'écran, par exemple une barre de hauteur 110, au lieu de toutes les fonctions proportionnelles que gridlayout et flowlayout font? – Alex

+0

'BoxLayout' comprend de tels composants de remplissage invisibles: http://download.oracle.com/javase/tutorial/uiswing/layout/box.html#filler – trashgod

+0

Aussi, si vous pouvez utiliser la méthode trashgod, je recommanderais fortement d'utiliser le approche standard. :) –

0

Bien que je ne répondrai pas à votre question particulière, je l'espère, cela aide:

Si les composants semblent tout simplement faux peut-être vous devriez réutiliser des composants Swing et juste écrivez un look personnalisé & Sentez-vous ou le thème.

Il serait certainement utile de s'assurer que l'apparence de l'application est cohérente et au moins vous utilisez le bon outil pour la tâche que vous souhaitez accomplir.

En tant que sidenote, sachez que Java est fourni avec plusieurs aspects & Look, y compris Look & Sentiments créés pour imiter le thème du système d'exploitation natif.

Voir: http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

+0

Cest im conscient de l'aspect et de la sensation, mais c'est un projet d'équipe et je travaille pour le design de quelqu'un d'autre et ils ont fait tout shiney avec le bouton de verre look ect. C'est donc la route que j'ai décidé de prendre. Bravo quand même! – Alex

8

Comme alternative, considérons le The Button API, qui comprend la méthode setRolloverIcon() « pour que le bouton affiche l'icône spécifiée lorsque le curseur passe au-dessus. »

Addendum: Pour example,

import java.net.MalformedURLException; 
import java.net.URL; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class ButtonIconTest { 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGui(); 
      } 
     }); 
    } 

    private static void createAndShowGui() { 
     String base = "http://download.oracle.com/" 
      + "javase/tutorial/uiswing/examples/components/" 
      + "RadioButtonDemoProject/src/components/images/"; 
     ImageIcon dog = null; 
     ImageIcon pig = null; 
     try { 
      dog = new ImageIcon(new URL(base + "Dog.gif")); 
      pig = new ImageIcon(new URL(base + "Pig.gif")); 
     } catch (MalformedURLException ex) { 
      ex.printStackTrace(System.err); 
      return; 
     } 
     JFrame frame = new JFrame("Rollover Test"); 
     JPanel panel = new JPanel(); 
     panel.add(new JLabel(dog)); 
     panel.add(new JLabel(pig)); 

     JButton button = new JButton(dog); 
     button.setRolloverIcon(pig); 
     panel.add(button); 

     frame.add(panel); 

     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
}