[英]Repaint() not being called
最近,我一直在研究一個程序,該程序使用空的彩色正方形繪制區域。 它們在屏幕上的位置基於文本文件中的值1和2。 1應該被做成紅色的盒子,而2應該被做成綠色的盒子。 但是,當我運行該程序時,只繪制了紅色框。 我進行了一些測試,發現repaint方法僅被調用兩次(有時由於某種原因有時被調用),即使文件中有接近300個值,並且應該為每個值調用一次repaint()
。 這是我的代碼:
public class MAP extends JFrame {
public static void main(String[] args) throws IOException {
MAP map = new MAP();
}
Shape shape;
int x = -32;
int y = 0;
ArrayList<Shape> shapes = new ArrayList<Shape>();
Graphics2D g2;
Color coulor = null;
private class PaintSurface extends JComponent {
public PaintSurface() {
}
public void paint(Graphics g) {
g2 = (Graphics2D) g;
g2.setColor(coulor);
for (Shape s : shapes) {
g2.draw(s);
}
}
}
public MAP() throws FileNotFoundException, IOException {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
frame.setTitle("Grid Maker");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(new PaintSurface(), BorderLayout.CENTER);
frame.setVisible(true);
readNextLine();
}
private void readNextLine() throws IOException {
File file = new File("map.txt");
BufferedReader in = new BufferedReader(new FileReader(file));
String line = in.readLine();
while (line != null) {
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == '1') {
coulor = Color.RED;
x += 32;
int smallX = x / 32;
int smallY = y / 32;
shape = new Rectangle2D.Float(x, y, 32, 32);
shapes.add(shape);
repaint();
} else if (c == '2') {
coulor = Color.GREEN;
x += 32;
int smallX = x / 32;
int smallY = y / 32;
shape = new Rectangle2D.Float(x, y, 32, 32);
shapes.add(shape);
repaint();
}
}
line = in.readLine();
x = -32;
y += 32;
}
}
}
為什么此代碼無法正常工作?
繪畫是短暫的或無狀態的。
repaint
是對重新繪制管理器發出的“請求”,告訴它應該在將來的某個時候准備就緒時繪制屏幕的某些部分,認為它是臟的。
這意味着,當您在paint
方法中調用g2.setColor(coulor)
時,它使用的是設置為LAST的值(當paint
被調用時)....這可能是RED
。
Raufio是正確的,您應該隨形狀一起提供顏色信息。 就個人而言,我會成立第二個List
剛剛包含Color
的對象,其中的每個索引Shape
列表直接對應的Color
在Color
List
。
查閱AWT和Swing中的繪畫,以獲得有關Swing中繪畫工作原理的更多詳細信息。
現在,到了令人苦惱的部分;)
不建議覆蓋paint
。 造成這種情況的原因很多, paint
負責調用許多重要的方法,包括paintChildren
和paintComponent
,它們執行非常重要的任務。
相反,您應該重寫paintComponent
(並確保調用super.paintComponent
)
請查看執行自定義繪畫以獲取更多詳細信息。
用粗略的例子更新
所以這是我在說的一個粗糙的例子...
public class TestPainting {
public static void main(String[] args) {
new TestPainting();
}
public TestPainting() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PaintingPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PaintingPane extends JPanel {
private static final int WIDTH = 200;
private static final int HEIGHT = 200;
private List<Shape> shapes;
private List<Color> colors;
public PaintingPane() {
shapes = new ArrayList<>(25);
colors = new ArrayList<>(25);
for (int index = 0; index < (int) Math.round(Math.random() * 100); index++) {
int x = (int) Math.round(Math.random() * (WIDTH * 0.75f));
int y = (int) Math.round(Math.random() * (HEIGHT * 0.75f));
int width = (int) Math.round(Math.random() * (WIDTH * 0.25f));
int height = (int) Math.round(Math.random() * (HEIGHT * 0.25f));
if (width < 5) {
width = 5;
}
if (height < 5) {
height = 5;
}
if (x + width > WIDTH) {
x -= width - WIDTH;
}
if (y + height > HEIGHT) {
y -= height - HEIGHT;
}
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
Color color = ((int)Math.round(Math.random() * 2)) == 1 ? Color.RED : Color.GREEN;
shapes.add(new Rectangle(x, y, width, height));
colors.add(color);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(WIDTH, HEIGHT);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (int index = 0; index < shapes.size(); index++) {
g2d.setColor(colors.get(index));
g2d.draw(shapes.get(index));
}
g2d.dispose();
}
}
}
只是為了增加其他答案,以下是一段代碼(基於您的代碼),看起來看起來已經好了很多(但是仍然存在一些問題,但是您還不存在):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class MAP extends JFrame {
public static void main(String[] args) throws IOException {
MAP map = new MAP();
}
public static class ColoredShape {
private Shape shape;
private Color color;
public ColoredShape(Shape shape, Color color) {
super();
this.shape = shape;
this.color = color;
}
public Shape getShape() {
return shape;
}
public Color getColor() {
return color;
}
}
int x = -32;
int y = 0;
List<ColoredShape> shapes = new ArrayList<ColoredShape>();
Graphics2D g2;
private class PaintSurface extends JComponent {
public PaintSurface() {
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2 = (Graphics2D) g;
for (ColoredShape s : shapes) {
g2.setColor(s.getColor());
g2.draw(s.getShape());
}
}
}
public MAP() throws FileNotFoundException, IOException {
JFrame frame = new JFrame();
frame.setTitle("Grid Maker");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.add(new PaintSurface(), BorderLayout.CENTER);
frame.setVisible(true);
readNextLine();
}
private void readNextLine() throws IOException {
BufferedReader in = new BufferedReader(new StringReader("11121\n1221\n2212\n221121\n111221\n11221\n222\n2222\n"));
String line = in.readLine();
while (line != null) {
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
Color color = null;
if (c == '1') {
color = Color.RED;
} else if (c == '2') {
color = Color.GREEN;
}
if (color != null) {
shapes.add(new ColoredShape(new Rectangle2D.Float(x, y, 32, 32), color));
x += 32;
repaint();
}
}
line = in.readLine();
x = -32;
y += 32;
}
}
}
我看到的第一件事是,您一次只能為一種形狀上色一種顏色。 所以在這里:
public void paint(Graphics g) {
g2 = (Graphics2D) g;
g2.setColor(coulor); //set the drawing color
for (Shape s : shapes) {
g2.draw(s); //draw in that color
}
}
當您要為不同形狀着色時,所有形狀均以相同顏色繪制。 我認為一種更好的處理方法是將所有形狀添加到列表中,跟蹤其顏色,然后一次調用repaint()
。 另外,我將Paint方法更改為以下效果:
public void paint(Graphics g) {
g2 = (Graphics2D) g;
for (Shape s : shapes) {
g2.setColor(coulor[indexOfShape]); //set the drawing color
g2.draw(s); //draw in that color
}
}
另外,對於repaint
僅被調用兩次:它可能拋出IOException
。 嘗試使用try {...} catch(IOException e) {...}
塊,而不是僅僅將其扔在一行上。 就像是:
private void readNextLine() {
try {
File file = new File("map.txt");
BufferedReader in = new BufferedReader(new FileReader(file));
String line = in.readLine();
...
...
} catch (IOException e) {
e.printStackTrace();
}
}
如果閱讀不正確,它應該抱怨一些東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.