JSlider korrekt implementieren

feldmarv

Mitglied
Hallo Zusammen


Ich habe einen JSlider erstellt. Er soll wenn ich eine Linie auf meinem Zeichnungspanel zeichne die Strichdicke einstellen lassen.
Meiner Meinung nach soll aber die Linie so bestehen wie sie gezeichnet wurde. Wenn also der Slider auf 5 Px gestellt und ich eine Linie zeiche soll diese 5 Px breit werden. Wenn ich nun den Slider auf 8 Px stelle soll sie mit 5 Px erhalten bleiben und nicht auf 8 Px. wechseln.
Wie erreiche ich das? Im Moment wechseln alle gezeichneten Objekte immer auf die Zahl im Slider. Ich kann also keine Linien mit verschiedenen Strichdicken zeichnen. =(

Vielen Dank für die Hilfe.

Java:
		Graphics2D g2 = ( Graphics2D )g;				// Dicke der Linie soll mit JSlider bestimmt werden
		g2.setStroke(new BasicStroke(Gui.dicke));
		g.drawLine(x, y, x2, y2);

Java:
public class MyChangeAction implements ChangeListener{
		public void stateChanged(ChangeEvent ce){
				dicke = slider.getValue();
				
			}

Java:
		slider.setValue(2);
		slider.addChangeListener(new MyChangeAction());
		slider.setMinimum(0); //Minimalwert ist Null
        slider.setMaximum(10);
        slider.setMajorTickSpacing(1); //Große Striche (mit Zahl) in 10er Schritten
        slider.setPaintTicks(true); //Striche werden angezeigt
        slider.setPaintLabels(true); //Anzeige der Zahlen true
        slider.setPaintTrack(true); //Balken wird angezeigt
        slider.setSnapToTicks(true); //automatisches Versetzen
 
Zuletzt bearbeitet:
Vielen Dank für die Antwort, aber können Sie das mir etwas ausführlicher Erklären. Bin noch etwas zu Neu in Java.

Du willst mehrere Linien zeichen, jede Linie soll eine eigene Strichstärke haben. Wo speicherst du die Strichstärke für jede Linie, wo speicherst du die Koordinaten für jede Linie? (Rhetorische Frage)
 
Du willst mehrere Linien zeichen, jede Linie soll eine eigene Strichstärke haben. Wo speicherst du die Strichstärke für jede Linie, wo speicherst du die Koordinaten für jede Linie? (Rhetorische Frage)

Die Strichstärken werden im Moment nirgends gespeichert. Genau das ist mein Problem. Ich weiss nicht genau wie ich das lösen soll.

Die Koordinaten der Linie werden in einer ArrayList gespeichert.
 
Die x,y Koordinaten werden in einer Variable <objekte> gespeichert, eine Arraylist.

aber wie kann ich nun die Dicke und später auch noch die Farbe des Objekt auch noch irgendwo speichern?

Vielen Dank für die Hilfe.
 
Ganz pragmatisch:
Java:
class TheClass
{
    private List<Shape> shapes = ...
    private List<Stroke> strokes = ... // NEU

    public void addToPaint(Shape shape, Stroke stroke)
    {
        shapes.add(shape);
        strokes.add(stroke);
    }

    public void paint(...)
    {
         for (int i=0; i<shapes.size(); i++)
         {
             Shape shape = shapes.get(i);
             Stroke stroke = strokes.get(i);
             g.setStroke(stroke);
             g.draw(shape);
         }
    }

Wenn da noch mehr dazukommt (z.B. noch Farbe oder sonstwas) kann man sich was geschickteres basteln, z.B. eine kleine Klasse wie
Java:
class Zeichenaufgabe
{
    private Shape shape;
    private Stroke stroke;
    private Color color;
    
....
    public void führeAus(Graphics2D g)
    {
    ....
    }
aber das muss man sich genauer überlegen.

EDIT: Und wichtig: Hör auf, die Leute hier mit "SIE" anzureden :autsch: :noe: 😉
 
Vielen Dank für den ersten Input.
Versuche diesen noch zu implementieren. Mein Fehler: der JSlider der die Strichdicke einstellen lässt gibt einen Wert als Integer. Ich benötige aber den Typ "Stroke".

(Type mismatch: cannot convert from int to Stroke)
 
Vielen Dank für den ersten Input.
Versuche diesen noch zu implementieren. Mein Fehler: der JSlider der die Strichdicke einstellen lässt gibt einen Wert als Integer. Ich benötige aber den Typ "Stroke".

(Type mismatch: cannot convert from int to Stroke)

Versuch es mal in etwa so:
Java:
   BasicStroke b = new BasicStroke((float)slider.getValue());
🙂

VG ROlf
 
Vielen Dank. Ich versuchte es mal mit der float und dem Basicstroke. Aber nun kann ich nichts mehr zeichnen auf dem Zeichnungspanel. ???:L
Darum poste ich einmal die Painter.java. Diese Klasse sollte die gezeichneten Objekte und die Strichdicken speichern und immer wieder neu zeichnen.

Java:
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.List;
import java.awt.Stroke;
import java.util.ArrayList;
import javax.swing.JPanel;


public class Painter extends Thread{									 // Painter für Nebenaktivität -> repaint graphics objekt immer neu holen und neu zeichnen
																		// Thread ist die Nebenaktivität
	

	private JPanel fenster;
	private ArrayList<Vector> objekte; 									// Liste von Vektoren dynamisch
	private ArrayList<BasicStroke> strokes; 							// Liste mit den Strichdicken
	
	public Painter(JPanel f){
		fenster = f;
		objekte = new ArrayList<Vector>();
		strokes = new ArrayList<BasicStroke>();
	}
	
	public void addToPaint(BasicStroke stroke){
		Gui.b = stroke;
		strokes.add(stroke);
    }
	
	public void run() {
		while(true){
			try{
			Graphics g = fenster.getGraphics();
			g.clearRect(0, 0, fenster.getWidth(), fenster.getHeight());
			for(int i=0; i<objekte.size(); i++){ 						// alle gezeichnete Objekte durchgehen
				Vector v = objekte.get(i);								// hole aus Liste Element an Position i
				BasicStroke stroke = strokes.get(i);


				((Graphics2D) g).setStroke(stroke);
				v.Paint(g); 											
			}}
			catch(Exception e){}
			try {
				Thread.currentThread();
				Thread.sleep(1000/24);
			} catch (InterruptedException e) {
				e.printStackTrace();

				
			} // 1000/24 24 tausendstel sekunden bis warten... Zahl aus Flashprogrammierung
		}		
	}
	
	public void addVector(Vector v){
		objekte.add(v);
		
	}
	
	public void clearVector(){
		objekte.clear();
	}
	

}

In der Gui.java Klasse ist der Listener der den JSlider abfangen soll.
Java:
	public class MyChangeAction implements ChangeListener{
		public void stateChanged(ChangeEvent ce){
			BasicStroke b = new BasicStroke((float)slider.getValue());
			//System.out.println(b);
			}
		}
 
Zuletzt bearbeitet:
fenster.getGraphics und dieser eigene Thread sind ohnehin Bogus. Faustegel: NIE auf einer Component getGraphics aufrufen. Alles, was gezeichnet wird, muss von der paintComponent aus gezeichnet werden.

Mehr dazu steht in Malen in Swing Teil 1: der grundlegende Mechanismus ? Byte-Welt Wiki , und Malen in Swing Teil 2: ein einfaches Malprogramm ? Byte-Welt Wiki könnte auch gut zu deinem Vorhaben passen.


Die Lösung mit dem Thread hat aber bisanhin gar nicht gestört. Nein es hat wunderbar geklappt.
Aber als ich nun BasicStroke implementieren wollte. Wird gar nichts mer gemacht.? ;(
 
Ich wäre sehr froh um weitere Informationen. Denn ich möchte an meinem Projekt weiterarbeiten, stehe jedoch voll an.

Ich muss einfach den Wert des JSliders in die ArrayList<BasicStroke> weitergeben können und danach das ganze immer mit den Vectordaten der Linie neu zeichnen lassen. Aber mit meinem Java Anfängerwissen komm ich da irgendwie nicht weiter.
 
Ich muss einfach den Wert des JSliders in die ArrayList<BasicStroke> weitergeben können und danach das ganze immer mit den Vectordaten der Linie neu zeichnen lassen. Aber mit meinem Java Anfängerwissen komm ich da irgendwie nicht weiter.

Ich versteh nicht wo dein Problem ist, du hast doch genau das gleiche schon für deine Koordinaten gemacht.

Im Übrigen, wenn du schon einen eigenen Datentyp für deine Linie hast warum speicherst du die Strichstärke nicht auch dadrin anstatt noch eine zweite Liste zu benutzen.
 
Das Problem bei getGraphics ist ja gerade, dass es meistens zu funktionieren scheint, aber schlicht falsch ist, und deswegen früher oder später irgendwo kracht.

Wann und wo rufst du jetzt die Methode addToPaint auf (die anders aussieht, als ich beschreiben habe, und deswegen potentiell auch schlicht falsch ist) und warum steht da noch dieses
Gui.b = stroke;
drin? Wozu ist das gut?

Poste am besten mal ein KSKB (auch wenn sie die Gefahr von Augenblutungen schon abzeichnet 😉 )
 
Das Problem bei getGraphics ist ja gerade, dass es meistens zu funktionieren scheint, aber schlicht falsch ist, und deswegen früher oder später irgendwo kracht.

Wann und wo rufst du jetzt die Methode addToPaint auf (die anders aussieht, als ich beschreiben habe, und deswegen potentiell auch schlicht falsch ist) und warum steht da noch dieses
Gui.b = stroke;
drin? Wozu ist das gut?

Poste am besten mal ein KSKB (auch wenn sie die Gefahr von Augenblutungen schon abzeichnet 😉 )

das Gui.b sollte für die Werte aus dem JSlider sein. Ich verstehe nicht wie die Werte des JSlider ChangeListeners nun zu der Stroke ArrayList kommen.

Die Stroke ArrayList ist in der Klasse mit dem Thread und der JSlider ist in der Klasse Gui.
 
Dort wo bisher
addVector(einVector);
aufgerufen wird, muss eben eine Methode
Java:
public void addVector(Vector v, float thickness){
    objekte.add(v);
    strokes.add(new BasicStroke(thickness));        
}
mit sowas wie
addVector(einVector, dieThicknessDieManIrgendwieVomSliderHierHerTransportiertHat);
aufgerufen werden...
 

Zurück
Oben