Gemalte Linien werden nicht dargestellt

MEETyA

Mitglied
Hallo,

mein Problem ist schlichtweg, dass die gemalten Linien ( g2.draw(new Line2D.Double(x1,y1,x2,y2)) ) nicht dargestellt werden.

Die Werte stimmen, die habe ich mir in die Konsole ausgeben lassen und auch der Debugger zeigt mir das er ganz normal die draw-Zeile durchgeht. Woran kann es liegen?

Folgender Aufbau:

Main.java (JFrame -> DrawPanel)
DrawPanel.java (mal-Methode)
Values.java (die zu zeichnenden Werte)

Der Aufruf zum malen geschiet ürbigens in einer while-Schleife, innerhalb einer ActionPerformed-Methode in der Main.Java

Da der Quelltext mittlerweile sehr groß ist hier nun das wichtigste:

Main.java
Code:
import try_02.DrawPanel;
import try_02.Values;

public class Main extends JFrame implements ActionListener, ItemListener, WindowListener {

    DrawPanel canvas = new DrawPanel ();

    public static void main(String[] args) {

        Main mainWindow = new Main ();

    }

    public Main() {
        
        super(" JAVA-Tool");

	setLayout(gridbag);

	addComponent(canvas, 1, 3, 5, 1, 25, 100, GridBagConstraints.BOTH,GridBagConstraints.CENTER);

        setVisible(true);

    }

    private void addComponent(Component component, int gridx, int gridy, int gridwidth, int gridheight, int weightx, int weighty, int fill, int anchor) {
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = gridx;
        constraints.gridy = gridy;
        constraints.gridwidth = gridwidth;
        constraints.gridheight = gridheight;
        constraints.weightx = weightx;
        constraints.weighty = weighty;
        constraints.fill = fill;
        constraints.anchor = anchor;
        constraints.ipadx = 2;
        constraints.ipady = 0;
        constraints.insets = new Insets(0, 0, 5, 0);
        gridbag.setConstraints(component, constraints);
        add(component);
    }

    public void actionPerformed(ActionEvent evt) {
        
        Object source = evt.getSource();

	if( source == field) {

		werte werden in values[i] gespeichert, jeder Punkt (X/Y) in eigenen array

                i=1;
                while (i < try_02.Values.getValueNumber() ) {
                      canvas.drawPoints(value[i-1].getX(),value[i-1].getY(),value[i].getX(),value[i].getY());
                      i++;
                }

		repaint();

   }

DrawPanel.java
Code:
public class DrawPanel extends JPanel {
    
    private static float PAD = 20, SPAD = 3, maxX = 10, maxY = 4;
    private static int startTime = 0, endTime = 10;
    private float x1, x2, y1, y2;
    private static Graphics g3;
    private static Graphics2D g2;

    public void drawPoints(float inXa, float inYa, float inXb, float inYb) {
        int w = getWidth(), h = getHeight();
        float xInc = (float)(w - 2*PAD)/(2*maxX);
        float yInc = (float)(h - 2*PAD)/(2*maxY);
        Graphics2D g2 = (Graphics2D)g3;
        g2.setPaint(Color.red);
        g2.draw(new Line2D.Double(inXa*xInc + PAD, PAD + (maxY*2 - inYa)*yInc, inXb*xInc + PAD, PAD + (maxY*2 - inYb)*yInc)); 
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g3 = g;
    }

}

Values.Java
Code:
public class Values {

    private static float maxValue = 0, minValue = 0;
    private static int valueNumber = 0;
    private float x = 0;
    private float y = 0;
    
    public Values() {

    }
    
    public void setX(float input) {
        x = input;
        valueNumber++;
    }
    
    public void setY(float input) {
        y = input;
    }
    
    public static int getValueNumber() {
        return valueNumber;
    }
    
    public static float getMaxValue() {
        return maxValue;
    }
    
    public static float getMinValue() {
        return minValue;
    }
    
    public float getX() {
        return x;
    }
    
    public float getY() {
        return y;
    }
    
}
 
Moin!
die Methode paintComponent(Graphics g) bewirkt, das die Komponente "gelöscht" und dann wieder neu gezeichnet wird. Die Methode selbst wird recht häufig automatisch vom System aufgerufen.
D.h. du zeichnest in deiner Event Methode deine Objekte und vom System werden sie wieder durch einen Aufruf von paintComponent() gelöscht.

Du solltest also aus der paintComponent Methode heraus deine zeichen Methode aufrufen..

*grüssle*
MeinerEiner
 
Danke für deine schnelle und einleuchtende Hilfe.

So wie ich dich verstanden habe muss meine DrawPanel-Klasse also folgendermaasen aussehen oder?

Code:
    private static float PAD = 20, SPAD = 3, maxX = 10, maxY = 4;
    private static int startTime = 0, endTime = 10;
    private float inXa, inXb, inYa, inYb;
    private float x1, x2, y1, y2;
    private static Graphics g3;
    private static Graphics2D g2;
    
    /** Creates a new instance of DrawPanel */
    public DrawPanel() {
    }

    public void drawPoints(float inXa, float inYa, float inXb, float inYb) {
        int w = getWidth(), h = getHeight();
        float xInc = (float)(w - 2*PAD)/(2*maxX);
        float yInc = (float)(h - 2*PAD)/(2*maxY);
        Graphics2D g2 = (Graphics2D)g3;
        g2.setPaint(Color.red);
        g2.draw(new Line2D.Double(inXa*xInc + PAD, PAD + (maxY*2 - inYa)*yInc, inXb*xInc + PAD, PAD + (maxY*2 - inYb)*yInc)); 
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g3 = g;
        drawPoints(inXa, inYa, inXb, inYb); 
        repaint();
    }
    
    public void paintComponent(float inXa, float inYa, float inXb, float inYb){
        this.inXa = inXa;
        this.inXb = inXb;
        this.inYa = inYa;
        this.inYb = inYb;
    }

Allerdings ist noch immer nichts zu sehen :'(

Edit:\ Ich habe natürlich in der Main die Anweisung umgeschrieben. Sie lautet nun:
Code:
canvas.paintComponent(value[i-1].getX(),value[i-1].getY(),value[i].getX(),value[i].getY());
 
Moin!
Also das repaint in paintComponent lass bitte weg..
Du müsstest dann einen code haben, der ungefähr so aussieht:
Code:
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.WindowListener;
import javax.swing.JFrame;

import java.util.Date;
import java.util.Random;

import javax.swing.JButton;

import java.awt.GridLayout;

public class Main extends JFrame implements ActionListener{

    DrawPanel canvas = new DrawPanel ();

   

    public Main() {
        
        super(" JAVA-Tool");
        this.getContentPane().setLayout(new GridLayout(2,1));
        this.getContentPane().add(canvas);
        JButton button = new JButton("press me");
        button.addActionListener(this);
        this.getContentPane().add(canvas);
        this.getContentPane().add(button);
    
    
        this.setSize(500,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

    }
    

    

    public void actionPerformed(ActionEvent evt) {
        
        Object source = evt.getSource();
        Random rand = new Random(new Date().getTime());
        canvas.paintComponent(rand.nextFloat()*10,rand.nextFloat()*10,rand.nextFloat()*10,rand.nextFloat()*10);
        repaint();

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

Code:
import javax.swing.JPanel;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import java.awt.geom.Line2D;
import java.awt.geom.Line2D.Double;

public class DrawPanel extends JPanel{

private static float PAD = 20, SPAD = 3, maxX = 10, maxY = 4;
    private static int startTime = 0, endTime = 10;
    private float inXa, inXb, inYa, inYb;
    private float x1, x2, y1, y2;
    
    /** Creates a new instance of DrawPanel */
    public DrawPanel() {
    }

    public void drawPoints(Graphics g) {
        int w = getWidth(), h = getHeight();
        float xInc = (float)(w - 2*PAD)/(2*maxX);
        float yInc = (float)(h - 2*PAD)/(2*maxY);
        Graphics2D g2 = (Graphics2D)g;
        g2.setPaint(Color.red);
        g2.draw(new Line2D.Double(inXa*xInc + PAD, PAD + (maxY*2 - inYa)*yInc, inXb*xInc + PAD, PAD + (maxY*2 - inYb)*yInc)); 
        //g2.draw(new Line2D.Double(inXa,inYa,inXb,inYb)); 
        
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawPoints(g); 
        
    }
    
    public void paintComponent(float inXa, float inYa, float inXb, float inYb){
        this.inXa = inXa;
        this.inXb = inXb;
        this.inYa = inYa;
        this.inYb = inYb;
    }
}

Der Code funktioniert bei mir auch soweit.

Was du nun noch beachten musst, ist folgendes:
Du hast eine Schleife, in der du mehrmals paintComponent(float x, float...) aufrufst.
D.h., du überschreibst bei jedem Aufruf deine Felder (inXa, inXb). Letzten endes würde also nur eine einzige Linie gezeichnet werden.. Du müsstest sie also speichern.
Ich würde es folgendermaßen lösen: Übergib deinem DrawPanel alle Value Objekte, die gezeichnet werden sollen. Das DrawPanel speichert sie, und generiert sich in der drawPoints Methode daraus die zu zeichnenden Linien...

*grüssle*
MeinerEiner
 
Dankeschön das hat mir schon sehr weitergeholfen und in der Tat funktioniert es auch. Danke danke :D

Deinen Tipp habe ich verstanden allerdings hapert es an der Umsetzung. Ich habe jetzt eine Methode in DrawPanel die Values points Arrays erstellt. Der Aufruf in der Main lautet folgendermaasen:

Code:
Schleife {
    canvas.setNewPoint(rtime.getVal(), fvalue.getVal(), i);
}
canvas.setArrayLenght(try_02.Values.getValueNumber());

Die geänderte DrawPanel sieht so aus:

Code:
public class DrawPanel extends JPanel {
    
    private static float PAD = 20, SPAD = 3, maxX = 10, maxY = 4;
    private static int startTime = 0, endTime = 10, lenght = 0;
    private float inXa, inXb, inYa, inYb;
    private float x1, x2, y1, y2;
    public static Values[] point = new Values[100];
    
    /** Creates a new instance of DrawPanel */
    public DrawPanel() {
    }
    public void setNewPoint(float inX, float inY, int i) {
        point[i] = new Values();
        point[i].setX(inX);
        point[i].setY(inY); 
    }
    
    public static void setArrayLenght(int inLenght) {
        lenght = inLenght;
    }
    public void drawPoints(Graphics g) {
        int w = getWidth(), h = getHeight();
        float xInc = (float)(w - 2*PAD)/(2*maxX);
        float yInc = (float)(h - 2*PAD)/(2*maxY);
        Graphics2D g2 = (Graphics2D)g;
        g2.setPaint(Color.red);
        int i = 0;
        while( i < lenght ) {
            i++;
            g2.draw(new Line2D.Double(point[i-1].getX()*xInc + PAD, PAD + (maxY*2 - point[i-1].getY())*yInc, point[i].getX()*xInc + PAD, PAD + (maxY*2 - point[i].getY())*yInc)); 
        }
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // paintGrid(g);
        drawPoints(g);
    }
    
    public void paintComponent(float inXa, float inYa, float inXb, float inYb){
        this.inXa = inXa;
        this.inXb = inXb;
        this.inYa = inYa;
        this.inYb = inYb;
    }    
}

Ob das ganze funktioniert weis ich nicht, da das Fenster grau wird (total ausgelastet), allerdings sagt mir die Konsole:

Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at try_02.DrawPanel.drawPoints(DrawPanel.java:78)
        at try_02.DrawPanel.paintComponent(DrawPanel.java:136)
        at javax.swing.JComponent.paint(JComponent.java:1027)
        at javax.swing.JComponent.paintChildren(JComponent.java:864)
        at javax.swing.JComponent.paint(JComponent.java:1036)
        at javax.swing.JComponent.paintChildren(JComponent.java:864)
        at javax.swing.JComponent.paint(JComponent.java:1036)
        at javax.swing.JLayeredPane.paint(JLayeredPane.java:564)
        at javax.swing.JComponent.paintChildren(JComponent.java:864)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5129)
        at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:285)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1128)
        at javax.swing.JComponent.paint(JComponent.java:1013)
        at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
        at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
        at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
        at java.awt.Container.paint(Container.java:1797)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:734)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:679)
        at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:659)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:128)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Das bedeutet das er anstatt den richtigen Inhalt nur null in der Graphics g hat oder? Wie behebe ich das?
 
Moin!
Da ich nicht weis, wo genau die Zeile 78 ist, muss ich raten, aber ich denke mal der Fehler tritt hier auf:

Code:
        while( i < lenght ) {
            i++;
            g2.draw(new Line2D.Double(point[i-1].getX()*xInc + PAD, PAD + (maxY*2 - point[i-1].getY())*yInc, point[i].getX()*xInc + PAD, PAD + (maxY*2 - point[i].getY())*yInc)); 
        }

Wenn du 5 Werte gespeichert hast, greifst du im letzten Schritt auf point[5] zu.. Das wäre der 6. Wert im Array.. und der ist null...

Statt eines Arrays, würde ich eine ArrayList nehmen. Vor der Schleife dann die Liste leeren und dann über die anzahl der Elemente in der Liste iterieren..



Code:
canvas.clearPoint();
Schleife {
    canvas.setNewPoint(rtime.getVal(), fvalue.getVal(), i);
}


Code:
public class DrawPanel extends JPanel {
    
   //public static Values[] point = new Values[100];      warum static?
    private ArrayList<Values> point = new ArrayList<Values>();
   
 /** Creates a new instance of DrawPanel */
    public DrawPanel() {
    }
    
    public void clearPoint(){
        point.clear();
    }

    public void drawPoints(Graphics g) {
        int w = getWidth(), h = getHeight();
        float xInc = (float)(w - 2*PAD)/(2*maxX);
        float yInc = (float)(h - 2*PAD)/(2*maxY);
        Graphics2D g2 = (Graphics2D)g;
        g2.setPaint(Color.red);
        for(int i=1; i < point.size();i++){
              g2.draw(...
        } 
     }

Testen kann ichs hier gerade nicht, aber sollte eigentlich klappen..

*grüssle*
MeinerEiner
 
Zurück