我知道绘制JPanel
的正确方法是创建一个扩展JPanel
并覆盖paintComponent
方法的类。这很好,但在制作JPanels
之前我不知道我想要绘制什么。
我在JPanel
中有一个主GridLayout
。网格中充满了其他JPanels
。这些JPanels
也在2D数组中被跟踪。基于按钮事件或其他事件,我希望能够简单地遍历此数组,获取图形并重新绘制。然而,这不是很好。我想做的一个例子是:
for (int row = 0; row < GRID_ROWS; row++) {
for (int col = 0; col < GRID_COLS; col++) {
JPanel tmp_panel = new JPanel();
Graphics g = panelGrid[row][col].getGraphics();
Graphics2D g2d = (Graphics2D)g;
//Do some drawing
panelGrid[row][col] = tmp_panel;
backingPanel.add(panelGrid[row][col]);
}
}
稍后在代码中,或许我希望能够循环并重新绘制面板的另一个事件:
for (int row = 0; row < GRID_ROWS; row++) {
for (int col = 0; col < GRID_COLS; col++) {
Graphics g = panelGrid[row][col].getGraphics();
Graphics2D g2d = (Graphics2D)g;
//Do some drawing
panelGrid[row][col].repaint()
}
}
我从来没有写过第二个块,因为第一个块总是抱怨图形没有被初始化。
答案 0 :(得分:2)
你可以做的是有一个原型面板,它使用任何实现接口的类,比如Drawable
,它有一个需要被覆盖的draw(Graphics g)
方法。
public interface Drawable {
public void draw(Graphics g);
}
您的原型面板调用看起来像这样。
public class DrawablePanel extends JPanel {
private Drawable drawable;
public DrawablePanel(Drawable drawable) {
this.drawable = drawable;
}
public DrawablePanel() {
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
if (drawable != null) {
drawable.draw(g2);
}
}
}
仅当Drawable
对象不为null时,它才会绘制任何内容。您可以在实例化时将Drawable
对象传递给它,或可以稍后设置Drawable
对象。
因此,您可以创建DrawablePanel
数组,并随时设置Drawable
预言。
Drawable
实施的一个例子可能就像
public class Ball implements Drawable {
@Override
public void draw(Graphics g) {
g.fillOval(0, 0, 50, 50);
}
}
<强>更新强>
以下是您可以使用
的示例import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class LoopPanelPaint {
private static final int ROUND_SQR = 0;
private static final int BALL = 1;
private List<Color> colorList;
public LoopPanelPaint() {
JPanel matrixPanel = new JPanel();
DrawablePanel[][] drawPanels = createPanelMatrix(matrixPanel);
colorList = createColorList();
JButton createImages = createButton(drawPanels);
JFrame frame = new JFrame();
frame.add(matrixPanel);
frame.add(createImages, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public JButton createButton(final DrawablePanel[][] panels) {
JButton button = new JButton("Create Images");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
addShapesToPanels(panels);
}
});
return button;
}
private DrawablePanel[][] createPanelMatrix(JPanel panel) {
panel.setLayout(new GridLayout(10, 10));
DrawablePanel[][] panels = new DrawablePanel[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
DrawablePanel drawPanel = new DrawablePanel();
panels[i][j] = drawPanel;
panel.add(drawPanel);
}
}
return panels;
}
private void addShapesToPanels(DrawablePanel[][] panels) {
Random random = new Random();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
int type = random.nextInt(2);
Drawable drawable = getRandomDrawable(type);
int colorIndex = random.nextInt(colorList.size());
Color color = colorList.get(colorIndex);
panels[i][j].setColor(color);
panels[i][j].setDrawable(drawable);
}
}
}
private Drawable getRandomDrawable(int type) {
switch (type) {
case ROUND_SQR:
return new RoundSquare();
case BALL:
return new Ball();
default:
return null;
}
}
private List<Color> createColorList() {
List<Color> colors = new ArrayList<>();
colors.add(Color.blue);
colors.add(Color.red);
colors.add(Color.gray);
colors.add(Color.green);
colors.add(Color.orange);
colors.add(Color.magenta);
colors.add(Color.yellow);
colors.add(Color.cyan);
return colors;
}
public class DrawablePanel extends JPanel {
private Drawable drawable;
private Color color = Color.black;
public DrawablePanel(Drawable drawable) {
this.drawable = drawable;
}
public DrawablePanel() {
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
repaint();
}
public void setColor(Color color) {
this.color = color;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(color);
if (drawable != null) {
drawable.draw(g2);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(Drawable.SIZE, Drawable.SIZE);
}
}
public class Ball implements Drawable {
@Override
public void draw(Graphics g) {
g.fillOval(0, 0, Drawable.SIZE, Drawable.SIZE);
}
}
public class RoundSquare implements Drawable {
@Override
public void draw(Graphics g) {
g.fillRoundRect(0, 0, Drawable.SIZE, Drawable.SIZE, 10, 10);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new LoopPanelPaint();
}
});
}
}
interface Drawable {
public static final int SIZE = 50;
public void draw(Graphics g);
}