Jframe - rysowanie tła i lini na tle w tym samym czasie

0

Witam,
jestem dość początkującym Java programistą i natrafiłem na taki problem. Mam program który rozwiązuje mi pewne równanie różniczkowe, a następnie na podstawie wygenerowanych danych rysuje linie (takie wahadło). Chciałbym dodać do także do mojego programu tło (grafika w jpg na cały frame), lecz nie za bardzo wiem jak bo albo rysuje mi samą linię albo samo tło.

Oto kod rysowania linii, byłbym niesamowicie wdzięczny jakby ktoś pokazał mi jak wyświetlić także w tym samym czasie tło:


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.util.ArrayList;


class LinePanel extends JPanel {

    Timer animationTimer;
    double angle = 0f;
    int lineLen = 160;
    int x = 290;
    int y =90;
    double angleChange = Math.PI/30;
    ArrayList<Double> myArr = new ArrayList<Double>();
    double tablica[];
    int index = 0;
    
    public LinePanel() {

//rozwiazuje rownanie rozniczkowe
        obliczKaty();
//a nastepnie startuje z rysowaniem
        animationTimer = new Timer(10, new LineAnimation());
        animationTimer.start();

    }

    @Override
    protected void paintComponent(Graphics g) {

//rysowanie linii (grubszej niz zwykla linia stąd te stroke'i)
    BasicStroke stroke = new BasicStroke(2.0f);
    BasicStroke wideStroke = new BasicStroke(3.0f);
    Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint
          (RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
       g2.setStroke( stroke );
        g2.draw(new Line2D.Double(1.0, 1.0, 1.0, 1.0));
        g2.setStroke( wideStroke );
        g2.draw(new Line2D.Double(1.0, 5.0, 1.0, 5.0));

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //System.out.println(angle+" "+ Math.cos(angle)+ " w radianach: "+(Math.PI*angle)/180);
        
        double dx = Math.sin(angle) * lineLen;
        double dy = (-1)*Math.cos(angle) * lineLen;
        g2d.clearRect(0, 0, getWidth(), getHeight());
        g2d.setColor(Color.BLACK);
        g2d.drawLine((int)(x), (int)(y), (int)(x + dx), (int)(y - dy));

    }
    
    class LineAnimation implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            //System.out.println((tablica[index++]*Math.PI)/180);

            if(index >= tablica.length) index = 31;
            angle = ((tablica[index++]*Math.PI)/180);

            repaint();
        }
    }
    public  void obliczKaty()
    {
        double v0, v1, x0, x1;
        double h=0.01, tmax=100.0;	//krok, wartosc poczatkowa i brzegowa x
	double  k=2.0, b=3.0, a=4.0;      //parametry
        int i=0;
        float xi=0;
        int koniec = 0;
	v0 = 0.0;
	x0=0.0;

	for (double t=0;t<tmax && koniec<10;t+=h, i++) {		//petla glowna

		x1 = v0*h + x0;
		v1 = (a*Math.sin(t)-k*v0+b*(x0-x0*x0*x0))*h + v0;
                if(x0<0 && x1>0) koniec++;
                else if(x0>0 && x1<0) koniec++;
        //wypisuje wynik
		//System.out.println("x_"+i+" (kat wychylenia): "+ x1);
                myArr.add(x1);
		x0 = x1;
		v0 = v1;

	}

        tablica = new double[myArr.size()];
        i=0;
        for (Double kat : myArr)
        {
           tablica[i++] = kat*50;
        }

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

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new LinePanel());
                
        f.setBounds(100, 100, 600, 400);
        f.setVisible(true);
    }
}

Z góry dziękuje bardzo za pomoc!

0

g2d.clearRect(0, 0, getWidth(), getHeight());Zdajesz sobie sprawę, co to robi?

0

Okey, clearRect resetuje tło.

Zakomentowuje to. Ponadto dodałem klasę wyświetlającą obrazek:

class ImagePanel extends JPanel {

  private Image img;

  public ImagePanel(String img) {
    this(new ImageIcon(img).getImage());
  }

  public ImagePanel(Image img) {
    this.img = img;
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
    setPreferredSize(size);
    setMinimumSize(size);
    setMaximumSize(size);
    setSize(size);
    setLayout(null);
  }

  public void paintComponent(Graphics g) {
    g.drawImage(img, 0, 0, null);
  }

}

i teraz jak zmienię main'a na:

 public static void main(String[] args) {

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
    ImagePanel panel = new ImagePanel(new ImageIcon("a.jpg").getImage());
    f.getContentPane().add(panel);
    f.pack();

        f.add(panel);
        f.add(new LinePanel());
                
        f.setBounds(100, 100, 600, 400);
        f.setVisible(true);
    }

To znów mam najpierw obrazek (przez pół sekundy), a następnie juz przez cały czas samą linię. Jak to połączyć?

0
public static void main(String[] args) {

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
        ImagePanel panel = new ImagePanel(new ImageIcon("a.jpg").getImage());
        f.add(panel);
        f.pack();

        //f.add(panel);
        //f.add(new LinePanel());
               
        f.setBounds(100, 100, 600, 400); //ta instrukcja po mojemu jest raczej bez sensu, wielkość ramki 
        //powinna być dopasowana do wielkości panelu, którą wcześniej ustaliłes
        f.setVisible(true);
    }

class ImagePanel extends JPanel {

  private Image img;

  public ImagePanel(String img) {
    this(new ImageIcon(img).getImage());
  }

  public ImagePanel(Image img) {
    this.img = img;
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
    setPreferredSize(size);
    setMinimumSize(size);
    setMaximumSize(size);
    setSize(size);
    setLayout(null);
  }

  public void paintComponent(Graphics g) {
    g.drawImage(img, 0, 0, null);
    // tu dodaj rysowanie linii
  }

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1