2016-05-09 3 views
1

Je travaille sur un curseur de volume et je voudrais changer l'apparence par défaut de Nimbus JSlider.Comment remplir la piste JSlider jusqu'au point de la valeur actuelle du pouce avec Nimubs L & F?

Je veux que mon JSlider remplisse automatiquement la piste jusqu'au point de la valeur actuelle du pouce. Une idée de cette approche serait comme (voir photo)

The second jSlider fills its background to the point of thumb value.

J'ai essayé d'étendre BasicSliderUI et remplacer la méthode paintTrack() sans chance. J'ai également essayé d'habiller le JSlider (voir l'exemple http://www.jasperpotts.com/blog/2008/08/skinning-a-slider-with-nimbus/) mais il semble que cette méthode change seulement l'apparence de JSlider.

Quelqu'un sait comment aborder ce problème?

Répondre

2

Cet exemple est pris en charge que pour JSlider horizontale:

enter image description here

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

public class SliderSkinDemo2 { 
    public JComponent makeUI() { 
    UIDefaults d = new UIDefaults(); 
    d.put("Slider:SliderTrack[Enabled].backgroundPainter", new Painter<JSlider>() { 
     @Override public void paint(Graphics2D g, JSlider c, int w, int h) { 
     int arc   = 10; 
     int trackHeight = 8; 
     int trackWidth = w - 2; 
     int fillTop  = 4; 
     int fillLeft = 1; 

     g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
          RenderingHints.VALUE_ANTIALIAS_ON); 
     g.setStroke(new BasicStroke(1.5f)); 
     g.setColor(Color.GRAY); 
     g.fillRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc); 

     int fillBottom = fillTop + trackHeight; 
     int fillRight = xPositionForValue(
      c.getValue(), c, 
      new Rectangle(fillLeft, fillTop, trackWidth, fillBottom - fillTop)); 

     g.setColor(Color.ORANGE); 
     g.fillRect(fillLeft + 1, fillTop + 1, fillRight - fillLeft, fillBottom - fillTop); 

     g.setColor(Color.WHITE); 
     g.drawRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc); 
     } 
     //@see javax/swing/plaf/basic/BasicSliderUI#xPositionForValue(int value) 
     protected int xPositionForValue(int value, JSlider slider, Rectangle trackRect) { 
     int min = slider.getMinimum(); 
     int max = slider.getMaximum(); 
     int trackLength = trackRect.width; 
     double valueRange = (double) max - (double) min; 
     double pixelsPerValue = (double) trackLength/valueRange; 
     int trackLeft = trackRect.x; 
     int trackRight = trackRect.x + (trackRect.width - 1); 
     int xPosition; 

     xPosition = trackLeft; 
     xPosition += Math.round(pixelsPerValue * ((double) value - min)); 

     xPosition = Math.max(trackLeft, xPosition); 
     xPosition = Math.min(trackRight, xPosition); 

     return xPosition; 
     } 
    }); 

    JSlider slider = new JSlider(); 
    slider.putClientProperty("Nimbus.Overrides", d); 

    JPanel p = new JPanel(); 
    p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 
    p.setBackground(Color.DARK_GRAY); 
    p.add(new JSlider()); 
    p.add(Box.createRigidArea(new Dimension(200, 20))); 
    p.add(slider); 
    return p; 
    } 
    public static void main(String... args) { 
    EventQueue.invokeLater(() -> { 
     try { 
     for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { 
      if ("Nimbus".equals(laf.getName())) { 
      UIManager.setLookAndFeel(laf.getClassName()); 
      } 
     } 
     } catch (Exception e) { 
     e.printStackTrace(); 
     } 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     f.getContentPane().add(new SliderSkinDemo2().makeUI()); 
     f.setSize(320, 240); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    }); 
    } 
} 
+0

Bien que je l'aurais voulu savoir comment maintenir le thème de fond par défaut de garder la 3D regarder qu'il fournit. Mais néanmoins, c'est une solution simple et géniale, merci! :) – blueFalcon