# drehknopf



## htz (3. Mai 2008)

Hallo,

ich versuche derzeit einen Drehknopf in Java zu erstellen, weiss aber derzeit nicht wie ich das nun machen soll.

Zur Veranschaulichung erstmal ein Bild:






Diesen Drehknopf möchte ich nun per Maus drehen können, sprich man soll ihn anklicken können und bei gedrückter Maustaste den Knopf um seinen Mittelpunkt drehen können. Dabei soll er aber immer nur einen Strich weiter gedreht werden können. Er soll halt an den Positionen der Striche sozusagen einrasten und nie dazwischen stehen bleiben. Außerdem darf man ihn nur von der 0 bis zur 10 drehen können (später bis zur 14, da es eigentlich 14 Stufen gibt). Er darf nicht darüber hinaus drehbar sein.

Wie kann ich das nun realisieren, das ich den Knopf anklicken und drehen kann? Das Zeichnen ist das kleinere Problem, das bekomme ich schon hin. Ich weiss nur nicht, wie ich eine Drehbewegung mit einer solchen Zeichnung mache bzw. mit einem solchen Objekt(Rad + Strich drauf).

Kann mir da wer weiter helfen?

mfg
htz


----------



## André Uhres (3. Mai 2008)

Folgendes Beispiel ist zwar nicht genau das, was du willst, aber vielleicht hilft es:

```
/*
 * RotaryButtonDemo.java
 */

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

public class RotaryButtonDemo extends JFrame {

    public RotaryButtonDemo() {
        super("RotaryButtonDemo");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);
        setLayout(new GridBagLayout());
        add(new RotaryButton(0, 0));
    }

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

            public void run() {
                new RotaryButtonDemo().setVisible(true);
            }
        });
    }
}

class RotaryButton extends JComponent {

    private ButtonLabel b;
    private int xB;
    private int yB;
    private int size = 100;

    public RotaryButton(final int x, final int y) {
        xB = x + 15;
        yB = y + 15;
        setLayout(null);
        b = new ButtonLabel();
        add(b);
        setPreferredSize(new Dimension(size + 70, size + 60));
    }

    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.drawString("Click on the knob (left/right)", xB, yB + size + 40);
        double angle = 45;
        for (int i = 0; i < 15; i++) {
            double sin = Math.sin(Math.toRadians(angle));
            double cos = Math.cos(Math.toRadians(angle));
            int x1 = (int) ((xB + size / 2) - cos * 40 - sin * 40);
            int y1 = (int) ((yB + size / 2) + sin * 40 - cos * 40);
            g.setColor(Color.GRAY);
            g.drawLine(x1, y1, (xB + size / 2), (yB + size / 2));
            if (i % 5 == 0) {
                g.drawString(String.valueOf(i), x1, y1 + 3);
            }
            angle -= 18;
        }
        g.setColor(Color.BLUE);
        g.drawRect(xB-15, yB-15, size + 69, size + 59);
        g.drawString(b.toString(), xB, yB + size + 20);
    }

    class ButtonLabel extends JLabel {

        private double angle;
        private int value;
        private GradientPaint gradient1;

        public ButtonLabel() {
            setLocation(xB, yB);
            setSize(new Dimension(size, size));
            gradient1 = new GradientPaint(0, 50, Color.LIGHT_GRAY, 0, 0, Color.GRAY, true);
            addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(final MouseEvent e) {
                    if (SwingUtilities.isLeftMouseButton(e)) {
                        if (angle != 18 * 14) {
                            angle += 18;
                            value++;
                        }
                    } else {
                        if (angle != 0) {
                            angle -= 18;
                            value--;
                        }
                    }
                    repaint();
                }
            });

        }

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.rotate(Math.toRadians(angle), 50, 50);
            g2.setPaint(gradient1);
            g.fillOval(0, 0, size, size);
            g.setColor(Color.DARK_GRAY);
            g.drawLine(1, 50, 15, 45);
            g.drawLine(1, 50, 15, 55);
        }

        @Override
        public String toString() {
            return "Value: " + value;
        }
    }
}
```


----------



## htz (3. Mai 2008)

Danke für die Antwort! 

Das ist nich genau das was ich will, aber es hilft mir weiter! Ich versuch es mal für mich anzupassen und meld mich dann nochmal.

Darf ich fragen ob du nun grade das passende Demo zu Hand hattest oder ist dir das eben aus der Feder geflossen? 

mfg
htz


----------



## André Uhres (3. Mai 2008)

Ist mir so aus dem Ärmel gerutscht


----------



## htz (4. Mai 2008)

Ich habe es nun doch so übernommen wie du es geschrieben hast. Der Knopf soll als Geschwindigkeitsregler für eine Eisenbahn dienen und diese Eisenbahn hat die Geschwindigkeitsstufen 0-14, somit ist es sinnvoller auch gleich die Visualisierung so zu gestalten.

Ich habs ein wenig in der Farbe angepasst und mir auch die Art und Weise angeschaut wie du das gebaut hast. Das merk ich mir 

Danke nochmal, ich bin gespannt ob ich den Knopf noch bei einer anderen Gruppe im Projekt sehen werde, die schauen ja auch oft hier rein  

mfg
htz


----------



## htz (30. Mai 2008)

Hallo, 

ich habe mal dein Codebeispiel so abgeändert, dass es nun doch mit dem Draggen geht. Man kann nun den Button "greifen" und den Knopf somit bewegen.

Der Code ist natürlich genau der selbe, einzige Änderung ist der MouseListener des JLabels.


```
class RotaryButton extends JLabel {

    private double angle;
    private int size = 100;
    private int value;
    private GradientPaint gradient1;

    public RotaryButton(final int x, final int y) {
    	setCursor(new Cursor(Cursor.HAND_CURSOR));
		setLayout(null);
    	setLocation(x, y);
        setSize(new Dimension(size, size));
        gradient1 = new GradientPaint(0, 50, Color.orange, 0, 0, Color.red, true);
        addMouseMotionListener(new MouseMotionListener() {
        	
        	@Override
        	public void mouseDragged(MouseEvent e){
        		Point mousePosition = e.getPoint();
				double a_x = mousePosition.getX()-size/2;
				double a_y = mousePosition.getY()-size/2;
				double b_x = -1.0;
				double b_y = 0.0;
				
				double winkel = Math.acos(((a_x * b_x)+(a_y * b_y))/((Math.sqrt(Math.pow(a_x,2)+Math.pow(a_y,2)))*((Math.sqrt(Math.pow(b_x,2)+Math.pow(b_y,2))))));
				
				double gradWinkel = (winkel / Math.PI)*180;
				
				if(mousePosition.getY()>50){
				 gradWinkel = 360 - gradWinkel;
				}
				System.out.println("Winkel: "+(int)gradWinkel);
				int z = (int)gradWinkel/18;
				if(z>14){
				 z=14;
				}
				angle = z * 18;
				value = z;
				repaint();
				getParent().repaint();
       	}

    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.rotate(Math.toRadians(angle), 50, 50);
        g2.setPaint(gradient1);
        g.fillOval(0, 0, size, size);
        g.setColor(Color.DARK_GRAY);
        g.drawLine(1, 50, 15, 45);
        g.drawLine(1, 50, 15, 55);
    }

    @Override
    public String toString() {
        return "Value: " + value;
    }
}
```


Funktioniert ganz gut wie ich finde.

mfg
htz


----------

