-3

As far as I can see, drawing in JFrame works like this:

  • Extends a JPanel and override its paint(Graphics g) method
  • add(panel) it to your JFrame

Is it possible to

  1. Draw a line
  2. Display that line
  3. Then later add a second line
  4. Show the new resulting image
  5. ...
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
arney
  • 795
  • 7
  • 20
  • Hi @arney, I think a good suggestion for you would be to have a look at [this](http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) tutorial. – AuroMetal Oct 23 '15 at 13:38
  • @AuroMetal As far as I can see, that demo is just about repainting, not about adding something at a later point in runtime. – arney Oct 23 '15 at 13:43
  • 1
    Hi @arney, well I assumed that would be a good start. However, I can suggest you [this](https://tips4java.wordpress.com/2009/05/08/custom-painting-approaches/) tutorial. Let me know if that helps and consequently answers your question. – AuroMetal Oct 23 '15 at 13:49
  • Oh and @arney, if you are interested to learn more about drawing, there's a very interesting [thread](http://stackoverflow.com/questions/408820/what-is-the-difference-between-swing-and-awt) about the differences between AWT and Swing. I know it doesn't relate at all with your question, but may be useful to know what Swing is capable of and expand your knowledge. =) – AuroMetal Oct 23 '15 at 13:56
  • 2
    Your first bullet point is incorrect. You should never override `paint(Graphics)`. Always override `paintComponent`, and the first line in your overridden method *must* call `super.paintComponent(g)`. – VGR Oct 23 '15 at 14:13
  • i think that usually if you want to display new modifications, you need to call `repaint`. thus, each time you want to add an element, to display the modifications you have to call repaint – SummerCode Oct 23 '15 at 14:14
  • @VGR While your comment seems to be correct, it also seems works if you do it the other way. Sometimes Java is just very robust ... – arney Oct 23 '15 at 14:15
  • 1
    _appearing_ robustness is not a good fundament for good programming ;-) Overriding paint in a Swing component is simply **WRONG** – kleopatra Oct 23 '15 at 22:43

2 Answers2

2

Yes, you need to use

repaint()

every time after you drew something new, to display the modifications on the screen. On a repaint, the whole screen is redrawn, therefore you need to ensure you draw again everything you want to keep.

With respect to preserving previous content, this question might help you out.

Community
  • 1
  • 1
SummerCode
  • 1,403
  • 1
  • 14
  • 28
1

AuroMetal pointed me to this tutorial and I extracted, that JPanel has no idea, what it has already drawn, so you have to maintain an ArrayList of everything to be drawn and cycle it through on every repaint():

import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Canvas extends JPanel implements LinePrinter {

    private static final long serialVersionUID = 1L;
    private ArrayList<Line> lines = new ArrayList<Line>();

    public Canvas(String title) {
        // Just generating a JFrame to display this JPanel
        JFrame frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 425);
        frame.setVisible(true);
        frame.add(this);
    }

    @Override
    public void addLine(Line line) {
        lines.add(line);
        this.repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for (Line line : lines) {
            g.drawLine(line.A.x, line.A.y, line.B.x, line.B.y);
        }
    }

}

where my custom Line class is

public class Line {

    public final Point A, B;

    public Line(Point A, Point B) {
        this.A = A;
        this.B = B;
    }

}

and my custom Point class is

public class Point {

    public final int x;
    public final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

}
arney
  • 795
  • 7
  • 20
  • 5
    No need to have an extended discussion about what Stack Overflow is or Is Not; just vote and move on. You'll never change anyone's mind and there will just be anger on both sides. – George Stocker Oct 23 '15 at 15:52
  • 1
    there are several issues with your perceived solution: a) mere struct classes are ... suboptimal - better add a service (aka: methods that do something) b) for best reusability, your Canvas must not have any business in instantiating its parent. Instead make your main class instantiate the parent frame and add the custom panel c) naming custom classes the same as core classes a recipe for confusion – kleopatra Oct 23 '15 at 22:54
  • @kleopatra True that. It's just the result of a quick and dirty first time exploration, but I thought the archive reader would benefit more from sample code than mere words. Feel free to edit or post your own solution. I'll be happy to award the check mark to your answer. – arney Oct 25 '15 at 18:50