Link to home
Start Free TrialLog in
Avatar of Mike Eghtebas
Mike EghtebasFlag for United States of America

asked on

Analog/ digital slider control...

In the attached code there are 3 items on a panel:

lbl
to show the value of the slider (yet to be coded).

slider
to set the value of lbl 0 to 10

chk
When checked, to show analog values of the slider like: 1.00, 1.04, 4.15, etc.
But when unchecked, to jump from 1 to 2, 3, etc

With unchecked version it is better to have graduation lines to show up. this means, the slider bar never stays between the graduation marks.

These features may already exist and we don't have to reinvent the wheel. If so, it will nice to know how it is done.

Thank you
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

public class GraduatedSlider extends JFrame implements ChangeListener {

    JSlider slider;
    JLabel lbl = new JLabel();
    JCheckBox chk = new JCheckBox();
    
   public GraduatedSlider(){

        JPanel panel = new JPanel();
        slider = new JSlider (0,10);     

        
        lbl.setText("Slider Value");
        chk.setText("Anolog/Digital");
        panel.add(lbl);
        panel.add(slider);
        panel.add(chk);
        
        Container c = this.getContentPane();
        c.add(panel);

        this.setSize(300,300);
        this.setTitle("Test Slider");
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

    }

    public void setValue(int i){
        lbl.setText(Integer.toString(i));
    }

    public void stateChanged(ChangeEvent ce){
        setValue(slider.getValue());
    }

    public static void main(String[] args) {
        new GraduatedSlider();
    }

    class UpperPanel{
        public UpperPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,80);
        }
    }

    class LowerPanel{
        public LowerPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,20);
        }
    }
}

Open in new window

Avatar of for_yan
for_yan
Flag of United States of America image



http://download.oracle.com/javase/6/docs/api/javax/swing/JSlider.html#getValueIsAdjusting%28%29

These options in fact exsist - look at the API - setSnaptToTicks()
and also minor major ticks
Avatar of Mike Eghtebas

ASKER

I will use this later on to set the a, b,and c values of a parabola. User sets it and then the formula shows up and its graph is plotted at the same time. Some may prefer to work with integer values for a, b, and c and some may prefer decimal.

The link above is very good. If you could do the above task with some comments with it such that I can follow it easily, I will study the content of the link and compare to your solution to get my arms around it.

So, please code for:

Adding ActionListner to update the label, show me how to adjust the physical appearance of the slider to be longer or shorter. And, of course use the link to have slider that snaps from one marker to another or behave in analog manner.

Thank you.
FYI, the focus of this question is on the slider not math formula composition or plotting the parabola. They are to be done much later.
This snaps to ticks and changes depending on the checkbox.
What I didn't do is to make it floating numbers,
I gues it may be done if you use

 http://www.splitbrain.org/_static/javadoc/WaveGradient/DoubleJSlider.html

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class GraduatedSlider extends JFrame implements ChangeListener, ItemListener {

    JSlider slider;
    JLabel lbl = new JLabel();
    JCheckBox chk = new JCheckBox();

   public GraduatedSlider(){

        JPanel panel = new JPanel();
        slider = new JSlider (0,100);
       slider.setMajorTickSpacing(10);
          slider.setMinorTickSpacing(2);

       slider.setSnapToTicks(true);
          slider.setPaintTicks(true);
       slider.setPaintLabels(true);


        lbl.setText("Slider Value");
        chk.setText("Anolog/Digital");
       chk.addItemListener(this);

       panel.setLayout(new BorderLayout());
        panel.add(lbl, BorderLayout.NORTH);
       
        panel.add(slider);

        panel.add(chk, BorderLayout.SOUTH);

        Container c = this.getContentPane();
        c.add(panel);

        this.setSize(1000,300);
        this.setTitle("Test Slider");
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

    }

    public void setValue(int i){
        lbl.setText(Integer.toString(i));
    }

    public void stateChanged(ChangeEvent ce){
        setValue(slider.getValue());
    }

    public static void main(String[] args) {
        new GraduatedSlider();
    }

    class UpperPanel{
        public UpperPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,80);
        }
    }

    class LowerPanel{
        public LowerPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,20);
        }
    }
    public void itemStateChanged(ItemEvent ie){
        boolean b =    slider.getSnapToTicks();
        slider.setSnapToTicks(!b);

    }
}
class DoubleJSlider extends JSlider {

    final int scale;

    public DoubleJSlider(int min, int max, int value, int scale) {
        super(min, max, value);
        this.scale = scale;
    }

    public double getScaledValue() {
        return ((double)super.getValue()) / this.scale;
    }
}

Open in new window


You can also use these tricks for doubles in JSlider:
http://stackoverflow.com/questions/2172574/jslider-for-doubles
this even draws doubles at the ticks

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Hashtable;

public class GraduatedSlider extends JFrame implements ChangeListener, ItemListener {

    JSlider slider;
    JLabel lbl = new JLabel();
    JCheckBox chk = new JCheckBox();

   public GraduatedSlider(){

       Hashtable h = new Hashtable();
       h.put(10,new JLabel("1.0"));
         h.put(20,new JLabel("2.0"));
         h.put(30,new JLabel("3.0"));
         h.put(40,new JLabel("4.0"));
       h.put(50,new JLabel("5.0"));
         h.put(60,new JLabel("6.0"));
         h.put(70,new JLabel("7.0"));
         h.put(80,new JLabel("8.0"));
          h.put(90,new JLabel("9.0"));
         h.put(1000,new JLabel("10.0"));


        JPanel panel = new JPanel();
        slider = new JSlider (0,100);
       slider.setMajorTickSpacing(10);
          slider.setMinorTickSpacing(2);

       slider.setSnapToTicks(true);
          slider.setPaintTicks(true);
       slider.setLabelTable(h);
       slider.setPaintLabels(true);


        lbl.setText("Slider Value");
        chk.setText("Anolog/Digital");
       chk.addItemListener(this);

       panel.setLayout(new BorderLayout());
        panel.add(lbl, BorderLayout.NORTH);
       
        panel.add(slider);

        panel.add(chk, BorderLayout.SOUTH);

        Container c = this.getContentPane();
        c.add(panel);

        this.setSize(1000,300);
        this.setTitle("Test Slider");
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

    }

    public void setValue(int i){
        lbl.setText(Integer.toString(i));
    }

    public void stateChanged(ChangeEvent ce){
        setValue(slider.getValue());
    }

    public static void main(String[] args) {
        new GraduatedSlider();
    }

    class UpperPanel{
        public UpperPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,80);
        }
    }

    class LowerPanel{
        public LowerPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,20);
        }
    }
    public void itemStateChanged(ItemEvent ie){
        boolean b =    slider.getSnapToTicks();
        slider.setSnapToTicks(!b);

    }
}

Open in new window

minor change to get 0.0 and 1.0:

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Hashtable;

public class GraduatedSlider extends JFrame implements ChangeListener, ItemListener {

    JSlider slider;
    JLabel lbl = new JLabel();
    JCheckBox chk = new JCheckBox();

   public GraduatedSlider(){

       Hashtable h = new Hashtable();

          h.put(0,new JLabel("0.0"));
       h.put(10,new JLabel("1.0"));
         h.put(20,new JLabel("2.0"));
         h.put(30,new JLabel("3.0"));
         h.put(40,new JLabel("4.0"));
       h.put(50,new JLabel("5.0"));
         h.put(60,new JLabel("6.0"));
         h.put(70,new JLabel("7.0"));
         h.put(80,new JLabel("8.0"));
          h.put(90,new JLabel("9.0"));
         h.put(100,new JLabel("10.0"));


        JPanel panel = new JPanel();
        slider = new JSlider (0,100);
       slider.setMajorTickSpacing(10);
          slider.setMinorTickSpacing(2);

       slider.setSnapToTicks(true);
          slider.setPaintTicks(true);
       slider.setLabelTable(h);
       slider.setPaintLabels(true);


        lbl.setText("Slider Value");
        chk.setText("Anolog/Digital");
       chk.addItemListener(this);

       panel.setLayout(new BorderLayout());
        panel.add(lbl, BorderLayout.NORTH);
       
        panel.add(slider);

        panel.add(chk, BorderLayout.SOUTH);

        Container c = this.getContentPane();
        c.add(panel);

        this.setSize(1000,300);
        this.setTitle("Test Slider");
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

    }

    public void setValue(int i){
        lbl.setText(Integer.toString(i));
    }

    public void stateChanged(ChangeEvent ce){
        setValue(slider.getValue());
    }

    public static void main(String[] args) {
        new GraduatedSlider();
    }

    class UpperPanel{
        public UpperPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,80);
        }
    }

    class LowerPanel{
        public LowerPanel(){
        }

        public Dimension getPreferredSize() {
            return new Dimension(80,20);
        }
    }
    public void itemStateChanged(ItemEvent ie){
        boolean b =    slider.getSnapToTicks();
        slider.setSnapToTicks(!b);

    }
}

Open in new window

Thank you for the grate solutions. The only part is not working is:

    public void setValue(int i){
        lbl.setText(Integer.toString(i));
    }

As the slider changes, the value of the slider is supposed to show in label named lbl but it doesn't

Sorry, don't understand what you want to do with this:

    public void setValue(int i){
        lbl.setText(Integer.toString(i));
    }

and what you mean by this:

>As the slider changes, the value of the slider is supposed to show in label named lbl but it doesn't


The slider itself is normal integer 0-100 JSlider - that's how you should set or read all values internally;
then you should only translate it to 0-10.0 double in all interactions with the user.
Although we can read the slider position on the slider itself, I want it to be displayed in the label control "lbl"
then read value from the slider - it will return it as int (0-100), then scale it to double accordinag to range which it shows in the labels,
format double (so it has say two decimnal points)
and then setText to your label - why shouild that be a problem?
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thank you