Solved

Swing Gui trying to learn How to make a circular slider bar or knob component

Posted on 2006-07-12
8
974 Views
Last Modified: 2013-11-23
I've been trying to find an example of how to make a circular slider bar or round knob(something like a radio volume control), but Haven't been able to find much. I'm a little stuck on how to implement it.
I previously had learned to do a round text field by extending JtextField and overriding the paintComponent
method. I tried to do that with the JSlider, but wasn't even close. It just displays a regular slider bar

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


public class SliderDemo extends JSlider
{
    public SliderDemo() {  }

      protected void paintComponent(Graphics g)
      {
            Graphics2D g2d = (Graphics2D)g;
              int width = getWidth();
            int height = getHeight();
            g.setColor(getBackground());
            g.fillRoundRect(0, 0, width, height, height, height);
            super.paintComponent(g);
      }

    private static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("SliderDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SliderDemo roundSlider = new SliderDemo();
        roundSlider.setMajorTickSpacing(10);
      roundSlider.setMinorTickSpacing(1);
      roundSlider.setPaintTicks(true);
      roundSlider.setPaintLabels(true);
        roundSlider.setOpaque(true);
        frame.setContentPane(roundSlider);
        frame.pack();
        frame.setVisible(true);
            }

    public static void main(String[] args) {
               javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
 An example or link to an example would be great. I want to be able to display the value of the tick mark the knob
is turned to.
0
Comment
Question by:mitchguy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 35

Accepted Solution

by:
girionis earned 125 total points
ID: 17097214
Hi mitchguy

have a look here http://www.dreamfabric.com/java/knob/knob.html

Cheers
0
 
LVL 35

Expert Comment

by:girionis
ID: 17097224
0
 

Author Comment

by:mitchguy
ID: 17098687
The link you provided, is exactly the kind of components I want to try and make. I had found a couple
of those listed on that website prior to posting this question. The problem for me was that I couldn't find any of the source code. I want to make the component myself, all I could find was the component already made for me.
Do you know where an example is in code or can you provide one?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 35

Expert Comment

by:girionis
ID: 17098873
The first link I posted provides the source code here: http://www.dreamfabric.com/java/knob/dknob_src.zip
0
 

Author Comment

by:mitchguy
ID: 17099612
I was unable to get to the first link, I think it's our firewall. I look forward to
checking it out from home later.
Thanks
0
 
LVL 2

Expert Comment

by:RoyalNepal
ID: 17101084
did u find the code?? if not its here......

/*  
 * DKnob.java
 * (c) 2000 by Joakim Eriksson
 *  
 * DKnob is a component similar to JSlider but with
 * round "user interface", a knob.
 */
package com.dreamfabric;

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

public class DKnob extends JComponent
{
    private final static float START = 225;
    private final static float LENGTH = 270;
    private final static float PI = (float) 3.1415;
    private final static float START_ANG = (START/360)*PI*2;
    private final static float LENGTH_ANG = (LENGTH/360)*PI*2;
    private final static float DRAG_RES = (float) 0.01;
    private final static float MULTIP = 180 / PI;
    private final static Color DEFAULT_FOCUS_COLOR = new Color(0x8080ff);

    private int SHADOWX = 1;
    private int SHADOWY = 1;
    private float DRAG_SPEED;
    private float CLICK_SPEED;
    private int size;
    private int middle;
   
    public final static int SIMPLE = 1;
    public final static int ROUND  = 2;
    private int dragType = ROUND;
   

    private final static Dimension MIN_SIZE = new Dimension(40, 40);
    private final static Dimension PREF_SIZE = new Dimension(80, 80);
   
    // Set the antialiasing to get the right look!
    private final static RenderingHints AALIAS =
      new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                     RenderingHints.VALUE_ANTIALIAS_ON);
   
    private ChangeEvent changeEvent = null;
    private EventListenerList listenerList = new EventListenerList();
   
    private Arc2D hitArc = new Arc2D.Float(Arc2D.PIE);
   
    private float ang = (float) START_ANG;
    private float val;
    private int dragpos = -1;
    private float startVal;
    private Color focusColor;
    private double lastAng;
   
    public DKnob() {
      DRAG_SPEED = 0.01F;
      CLICK_SPEED = 0.01F;
      SHADOWX = 1;
      SHADOWY = 1;
      
      focusColor = DEFAULT_FOCUS_COLOR;
      
      setPreferredSize(PREF_SIZE);
      hitArc.setAngleStart(235); // Degrees ??? Radians???
      addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent me) {
                dragpos = me.getX() + me.getY();
                startVal = val;

                // Fix last angle
                int xpos = middle - me.getX();
                int ypos = middle - me.getY();
                lastAng = Math.atan2(xpos, ypos);

                requestFocus();
            }
            
            public void mouseClicked(MouseEvent me) {
                hitArc.setAngleExtent(-(LENGTH + 20));
                if  (hitArc.contains(me.getX(), me.getY())) {         
                  hitArc.setAngleExtent(MULTIP * (ang-START_ANG)-10);
                  if  (hitArc.contains(me.getX(), me.getY())) {
                      decValue();
                  } else incValue();      
                }
            }
          });

      // Let the user control the knob with the mouse
      addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent me) {
                if ( dragType == SIMPLE) {
                  float f = DRAG_SPEED * (float)
                      ((me.getX() + me.getY()) - dragpos);
                  setValue(startVal + f);
                } else if ( dragType == ROUND) {
                  // Measure relative the middle of the button!
                  int xpos = middle - me.getX();
                  int ypos = middle - me.getY();
                  double ang = Math.atan2(xpos, ypos);
                  double diff = lastAng - ang;
                  setValue((float) (getValue() + (diff / LENGTH_ANG)));

                  lastAng = ang;
                }
            }
            
            public void mouseMoved(MouseEvent me) {
            }
          });

      // Let the user control the knob with the keyboard
      addKeyListener(new KeyListener() {
            
            public void keyTyped(KeyEvent e) {}
            public void keyReleased(KeyEvent e) {}
            public void keyPressed(KeyEvent e) {
                int k = e.getKeyCode();
                if (k == e.VK_RIGHT)
                  incValue();
                else if (k == e.VK_LEFT)
                  decValue();
            }            
          });
      
      // Handle focus so that the knob gets the correct focus highlighting.
      addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {
                repaint();
            }
            public void focusLost(FocusEvent e) {
                repaint();
            }
          });
    }

    public void setDragType(int type) {
      dragType = type;
    }
    public int getDragType() {
      return dragType;
    }
   
    public boolean isManagingFocus() {
      return true;
    }
   
    public boolean isFocusTraversable() {
      return true;
    }
   
   
   
    private void incValue() {
      setValue(val + CLICK_SPEED);
    }
   
    private void decValue() {
      setValue(val - CLICK_SPEED);
    }
   

    public float getValue() {
      return val;
    }

    public void setValue(float val) {
      if (val < 0) val = 0;
      if (val > 1) val = 1;
      this.val = val;
      ang = START_ANG - (float) LENGTH_ANG * val;
      repaint();
      fireChangeEvent();
    }

   
    public void addChangeListener(ChangeListener cl) {
      listenerList.add(ChangeListener.class, cl);
    }
   
    public void removeChangeListener(ChangeListener cl) {
      listenerList.remove(ChangeListener.class, cl);            
    }
   
    public Dimension getMinimumSize() {
      return MIN_SIZE;
    }
   
    protected void fireChangeEvent() {
      // Guaranteed to return a non-null array
      Object[] listeners = listenerList.getListenerList();
      // Process the listeners last to first, notifying
      // those that are interested in this event
      for (int i = listeners.length-2; i>=0; i-=2) {
          if (listeners[i] == ChangeListener.class) {
            // Lazily create the event:
            if (changeEvent == null)
                changeEvent = new ChangeEvent(this);
            ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
          }
      }
    }
 

    // Paint the DKnob
    public void paint(Graphics g) {
      int width = getWidth();
      int height = getHeight();
      size = Math.min(width, height) - 22;
      middle = 10 + size/2;

      if (g instanceof Graphics2D) {
          Graphics2D g2d = (Graphics2D) g;
          g2d.setBackground(getParent().getBackground());
          g2d.addRenderingHints(AALIAS);
          
          // For the size of the "mouse click" area
          hitArc.setFrame(4, 4, size+12, size+12);
      }
      
      // Paint the "markers"
      for (float a2 = START_ANG; a2 >= START_ANG - LENGTH_ANG; a2=a2 -(float)
             (LENGTH_ANG/10.01))
          {
            int x = 10 + size/2 + (int)((6+size/2) * Math.cos(a2));
            int y = 10 + size/2 - (int)((6+size/2) * Math.sin(a2));
            g.drawLine(10 + size/2, 10 + size/2, x, y);
            
          }
      
      // Set the position of the Zero
      g.drawString("0", 2, size + 10);
      
      // Paint focus if in focus
      if (hasFocus()) {
          g.setColor(focusColor);
      } else {
          g.setColor(Color.white);
      }

      g.fillOval(10, 10, size, size);
      g.setColor(Color.gray);
      g.fillOval(14 + SHADOWX, 14 + SHADOWY, size-8, size-8);
      
      g.setColor(Color.black);
      g.drawArc(10, 10, size, size, 315, 270);
      g.fillOval(14, 14, size-8, size-8);
      g.setColor(Color.white);
      
      int x = 10 + size/2 + (int)(size/2 * Math.cos(ang));
      int y = 10 + size/2 - (int)(size/2 * Math.sin(ang));
      g.drawLine(10 + size/2, 10 + size/2, x, y);
      g.setColor(Color.gray);
      int s2 = (int) Math.max(size / 6, 6);
      g.drawOval(10 + s2, 10 + s2, size - s2*2, size - s2*2);
      
      int dx = (int)(2 * Math.sin(ang));
      int dy = (int)(2 * Math.cos(ang));
      g.drawLine(10 + dx + size/2, 10 + dy + size/2, x, y);
      g.drawLine(10-dx + size/2, 10-dy + size/2, x, y);
    }
}





package com.dreamfabric;

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

public class DTest
{
      public static void main(String[] args)
      {
          JFrame win = new JFrame("DTest!");
          win.getContentPane().setLayout(new BorderLayout());
          win.setSize(120,140);

          JPanel panel = new JPanel(new BorderLayout());
          panel.setBackground(new Color(200,200,255));
          win.getContentPane().add(panel, BorderLayout.CENTER);

          DKnob ts;
          JLabel jl;
          ChangeListener cl;
          panel.add(ts = new DKnob(), BorderLayout.CENTER);
          panel.add(jl = new JLabel("Volume: 0"), BorderLayout.NORTH);
          ts.setValue((float)1.0);
          final JLabel jla = jl;
          ts.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                  DKnob t = (DKnob) e.getSource();
                  int vol;
                  jla.setText("Volume: " + (vol = (int)(15 * t.getValue())));
                }
            });
          win.show();
      }
}


0
 

Author Comment

by:mitchguy
ID: 17112438
yes I found the code. Thanks
0
 
LVL 35

Expert Comment

by:girionis
ID: 17114102
:)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deletiā€¦
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This video teaches viewers about errors in exception handling.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question