2010-10-19 21 views
2

Je crée une barre de curseur, qui sera une sous-classe de JSlider, dans le cadre d'un GUI de consignation. Ce que j'aimerais faire, c'est pouvoir dessiner certains éléments au-dessus de la barre de défilement (par exemple, un affichage de "volume", indiquant combien d'informations de journalisation seront crachées par un paramètre particulier). J'ai surchargé la méthode paintComponent(), mais je suis un peu confus sur la façon dont le rectangle de découpe est calculé pour l'objet Graphics transmis à paintComponent.Comment le rectangle de découpe d'un composant JComponent est-il calculé?

Fondamentalement, ce que je veux faire est de créer plus d'espace dans la zone visible du composant qui peut être dessiné, mais seulement au-dessus de ce qui est déjà dessiné. Ainsi, par exemple, dans l'image suivante, j'ai trois barres de défilement:

slider bars

Le rectangle de découpage est représenté en rouge pour chacun d'entre eux. (Elles sont quelque peu dessinées à la main, mais j'ai effectivement utilisé le drawRect (g.getClipBounds()) et j'ai trouvé des rectangles similaires La barre de curseur supérieure est ce que je reçois si je n'augmente pas du tout la barre du curseur. Le rectangle moyen est ce que j'obtiens si je substitue getPreferredSize() pour ajouter un certain montant (je l'appelle la hauteur du volume - par défaut, 20) à la hauteur du composant, l'image du bas est celle que je veux. Donc, ma question est: «Comment les rectangles d'écrêtage sont-ils calculés dans l'objet Graphics quand ils sont passés à un composant paintComponent?() méthode? 'Je n'arrive pas à trouver comment le système détermine quelles limites de découpage devraient être pour un composant donné

Merci,

~ Scott

Répondre

1

L'API java.awt.Graphics mentionne, « La combinaison du clip utilisateur et un clip dispositif définit le clip composite, qui détermine la zone de découpage finale », mais écrêtage est pas vraiment pertinent à votre question . Vous voulez probablement utiliser une mise en page appropriée à la place. Box layout, qui active Using Invisible Components as Filler, peut être utile dans ce contexte.

Addendum:

... Je préfère passer outre paintComponent() dans JSlider.

AFAIK, paintComponent() seulement les délégués à une sous-classe de javax.swing.plaf.SliderUI. Ce example peut suggérer une approche.

alt text

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridLayout; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 

/** @see https://stackoverflow.com/questions/3971972 */ 
public class JSliderTest extends JPanel { 

    public JSliderTest() { 
     super(new GridLayout(0, 1)); 
     this.setPreferredSize(new Dimension(500, 400)); 
     this.add(genSliderPanel()); 
     this.add(genSliderPanel()); 
     this.add(genSliderPanel()); 
    } 

    private JPanel genSliderPanel() { 
     JPanel panel = new JPanel(); 
     panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 
     panel.setBorder(BorderFactory.createLineBorder(Color.red)); 
     JSlider slider = new JSlider(JSlider.HORIZONTAL); 
     slider.setValue(40); 
     slider.setMajorTickSpacing(20); 
     slider.setPaintTicks(true); 
     slider.setPaintLabels(true); 
     panel.add(Box.createVerticalGlue()); 
     panel.add(slider); 
     panel.add(Box.createRigidArea(new Dimension(16, 16))); 
     return panel; 
    } 

    private void display() { 
     JFrame f = new JFrame("JSliderTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new JSliderTest().display(); 
      } 
     }); 
    } 
} 
+0

Merci. C'est un bon conseil. En fait, je voulais que cet objet étende JSlider, plutôt que JPanel, cependant. Je préfère qu'il soit traité comme un composant entièrement contenu, et remplace paintComponent() dans JSlider, plutôt que d'étendre JPanel. – jwir3

+0

@ jwir3: Je me méfie de l'utilisation du délégué de l'interface utilisateur pour faire la mise en page, mais j'ai suggéré une approche ci-dessus. L'utilisation de votre propre gestionnaire de disposition peut être une autre alternative. – trashgod

+0

Donc, je veux juste être clair. Vous préféreriez faire du VolumeSlider une sous-classe de JPanel, parce que vous pensez que le problème est la mise en page? J'ai un peu abordé le problème un peu différemment, je pense en le regardant comme un problème de peinture spécial. – jwir3