Reputation: 29
I create a window with a panel with custom panel class and paint circles on it based on array data. How do I get both sets of circles to stay on screen?
import java.awt.Color;
import java.awt.*;
import javax.swing.*;
class DataPaint extends JPanel {
static int offsetY = 0;
int leftX = 20;
int[] guessColours;
Color purple = new Color(155, 10, 255);
Color pink = new Color(255, 125, 255);
Color[] Colours = { Color.blue, Color.cyan, Color.green, Color.orange,
pink, purple, Color.red, Color.yellow };
public DataPaint() {
setBackground(Color.WHITE);
}
public void paintClues(int[] guessColours) {
this.guessColours = guessColours;
offsetY += 30;
}
// naive attempt to make it work !!!!
// what is diff between paintComponent and paint?
public void update(Graphics g) {
paintComponent(g);
}
// paint circles based on array data
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < guessColours.length; i++) {
g2.setPaint(Colours[guessColours[i]]);
g2.fillOval(leftX + (i * 30), offsetY, 20, 20);
}
}
// create window with panel and paint circles on it based on array data
public static void main(String args[]) {
JFrame frame = new JFrame("data paint");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
DataPaint panel = new DataPaint();
frame.add(panel);
frame.setVisible(true);
int[] cols = { 2, 4, 5, 3, 6 };
int[] cols2 = { 1, 3, 7, 3, 4 };
// the second call replaces the first call on the panel?
panel.paintClues(cols);
panel.paintClues(cols2);
}
}
Upvotes: 1
Views: 1482
Reputation: 43773
You don't stop it. The way Swing, and most GUI frameworks, work is that the paintComponent
method or its analogue is always supposed to draw everything from scratch.
There are several reasons for this. One is is that if the window were resized, or any other sort of layout change occurred, or if the data-set being drawn changed in a complex way, you will need to be able to redraw anyway. Also, some window systems do not even store what is drawn in the window permanently, so you need to be able to redraw if your window is covered then uncovered. It is possible to have a component which has a permanent image that you can draw into, but that is not the usual way to do things and is less efficient unless you're writing, say, a paint program.
Change your data structures so that you keep all the information, and write your paintComponent
so that it draws everything you want on screen every time it is called.
(There are refinements to make this efficient for partial updates of complex graphics, but you don't need to worry about those yet, as this is such a simple case. If you did need to do this, you would ask Swing to repaint a small region of your component (such as with JComponent.repaint(Rectangle r)
; it would then automatically prohibit drawing to areas outside that region while it calls your paintComponent
method. That works fine to prevent flicker and save some filling work; then if it really matters for efficiency, inside paintComponent you compare that clip region (Graphics.getClip()
) to what you're drawing and skip everything that doesn't intersect. But you really shouldn't worry about that yet for this simple case. First get your code working and using Swing correctly, then optimize if it matters.)
In your particular example, which I take it is intended to be a Mastermind game (you should mention that up front to help us read your code), put cols
and cols2
into an int[][]
field of DataPaint, and then use a loop inside of paintComponent
to read every sub-array in that array and paint all of them.
Upvotes: 3