[英]Java Swing - Painting JPanels without overriding
I know the proper way to paint a JPanel
is to create a class that extends JPanel
and override the paintComponent
method.我知道绘制
JPanel
的正确方法是创建一个扩展JPanel
并覆盖paintComponent
方法的类。 That's nice, but I don't know what I want to draw before making the JPanels
.这很好,但我不知道在制作
JPanels
之前我想画什么。
I have a main JPanel
in a GridLayout
.我在
GridLayout
有一个主JPanel
。 The grids are filled with other JPanels
.网格填充了其他
JPanels
。 These JPanels
are also tracked in a 2D array.这些
JPanels
也在二维数组中进行跟踪。 Based on button events or other events I want to be able to simply loop through this array, get the graphics, and repaint.基于按钮事件或其他事件,我希望能够简单地遍历此数组,获取图形并重新绘制。 That is not working too nicely however.
然而,这并不太好。 An example of what I wanted to do is:
我想做的一个例子是:
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]);
}
}
Later in the code, perhaps another event I would like to simply be able to loop through and redraw the panels:在代码的后面,也许我希望能够简单地循环并重绘面板的另一个事件:
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()
}
}
I never got to writing the second block because the first one always complains about graphics not being initialized.我从来没有写过第二个块,因为第一个块总是抱怨图形没有被初始化。
What you can do is have a prototype panel that uses any class that implements an interface, say Drawable
, which has a draw(Graphics g)
method that need to be overridden.你可以做的是有一个原型面板,它使用任何实现接口的类,比如
Drawable
,它有一个需要覆盖的draw(Graphics g)
方法。
public interface Drawable {
public void draw(Graphics g);
}
Your prototype panel call can look something like this.您的原型面板通话可能看起来像这样。
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);
}
}
}
Only if the Drawable
object is not null, will it paint anything.只有当
Drawable
对象不为空时,它才会绘制任何东西。 You can either pass a Drawable
object to it on instantiation, or you can set the Drawable
object later.您可以通过一个
Drawable
对象给它的实例,也可以设置Drawable
后面的对象。
So you can create an array of DrawablePanel
and set the the Drawable
proptery whenever you want.因此,您可以随时创建
DrawablePanel
数组并设置Drawable
属性。
An example of a Drawable
implementation could be something as simple as一个
Drawable
实现的例子可能很简单
public class Ball implements Drawable {
@Override
public void draw(Graphics g) {
g.fillOval(0, 0, 50, 50);
}
}
UPDATE更新
Here's an example you can play with这是一个你可以玩的例子
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.