Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2006-07-12
8
Medium Priority
?
1,046 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 500 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
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!

 
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

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Suggested Courses

636 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