說到揮桿,我是個菜鳥。到目前為止,我所有的知識都來自 YouTube 和 Stack Overflow。我正在嘗試制作一個互動式 5x5 板,每個位置都有一個隨機影像,每個影像上都有一個透明的 JLabel。我有一個二維陣列,我根據二維陣列中的 ID 值繪制影像。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Panel extends JPanel{
int rows, cols, size;
int[][] gameBoard;
static final int SCREEN_SIZE = 500;
Panel(){
setPreferredSize(new Dimension(SCREEN_SIZE, SCREEN_SIZE));
setBackground(new Color(135, 206, 235)); //Sky blue
newBoard();
}
//Here
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) g2D.drawImage(Images.getImage(board[r][c]), size*c, size*r, null);//Paints an image based on each int value in the 2D array
}
void newBoard() {
rows = cols = 5;
size = 100;
board = new int[rows][cols];
fill();
}
void fill() {
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) gameBoard[r][c] = Images.randomTile(); //fills the 2D array with random values that relate to which image to display
}
}
(我把所有不相關的東西都拿出來了)
這部分作業得很好。問題是我試圖用 MouseListeners 制作一組透明的 JLabels 來覆寫每個影像。在測驗時,我讓它們變得不透明,但它們沒有出現。我查看了 StackOverflow 以找到我的問題,并且我不斷看到人們說不要覆寫paint,而是要覆寫paintComponent。當我嘗試它時,我得到了背景,但沒有影像。這是完全相同的代碼,當我覆寫paint時,一切正常,但是當我將paint更改為paintComponent時,我只得到背景。
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) g2D.drawImage(Images.getImage(board[r][c]), size*c, size*r, null);//Paints an image based on each int value in the 2D array
}
完美運行
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) g2D.drawImage(Images.getImage(board[r][c]), size*c, size*r, null);//Paints an image based on each int value in the 2D array
}
只顯示背景
編輯:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Panel extends JPanel implements MouseListener{
int rows, cols, size;
int[][] board, shadowBoard;
JLabel[][] labelBoard;
static final int SCREEN_SIZE = 500;
Panel(){
setPreferredSize(new Dimension(SCREEN_SIZE, SCREEN_SIZE));
setBackground(new Color(135, 206, 235));
newBoard();
/*Timer tick = new Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
});
tick.start();*/
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) g2D.drawImage(Images.getImage(board[r][c]), size*c, size*r, null);
}
//Board methods
void newBoard() {
rows = 5;
cols = 5;
size = 100;
board = shadowBoard = new int[rows][cols];
labelBoard = new JLabel[rows][cols];
fillLabelBoard();
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) this.add(labelBoard[r][c]);
fill();
//printBoard();
}
void newBoard(int r, int c) {
rows = r;
cols = c;
board = new int[rows][cols];
shadowBoard = new int[rows][cols];
size = (int) ((r>c)? SCREEN_SIZE/r : SCREEN_SIZE/c);
Images.resize(size);
fill();
//printBoard();
}
void fill() {
for (int r = 0; r<rows; r ) for (int c = 0; c<cols; c ) board[r][c] = Images.randomImage();
}
void fillLabelBoard() {
for (int r = 0; r<rows; r ) {
for (int c = 0; c<cols; c ) {
labelBoard[r][c] = new JLabel();
labelBoard[r][c].setBounds(0, 0, size, size);
labelBoard[r][c].setBackground(Color.red);
labelBoard[r][c].setOpaque(true);
labelBoard[r][c].addMouseListener(this);
//add(labelBoard[r][c]);
}
}
}
//Debugging
void printBoard() {
for (int[] r: board) {
for (int c: r) System.out.print(c);
System.out.print("\n");
}
System.out.println(rows);
System.out.println(cols);
System.out.println(size);
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.print("click");
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
完整的、未經編輯的代碼
uj5u.com熱心網友回復:
再次,沒有問題。兩者都paint將paintComponent產生一個網格,問題不在于您提供給我們的代碼。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new Panel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Panel extends JPanel implements MouseListener {
int rows, cols, size;
int[][] board, shadowBoard;
JLabel[][] labelBoard;
static final int SCREEN_SIZE = 500;
Panel() {
setPreferredSize(new Dimension(SCREEN_SIZE, SCREEN_SIZE));
setBackground(new Color(135, 206, 235));
newBoard();
/*Timer tick = new Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
});
tick.start();*/
}
// public void paint(Graphics g) {
// super.paint(g);
// Graphics2D g2D = (Graphics2D) g;
// paintBoard(g2D);
// }
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
paintBoard(g2D);
}
protected void paintBoard(Graphics2D g2d) {
for (int r = 0; r < rows; r ) {
for (int c = 0; c < cols; c ) {
g2d.drawRect(c * size, r * size, size, size);
// g2D.drawImage(Images.getImage(board[r][c]), size * c, size * r, null);
}
}
}
//Board methods
void newBoard() {
rows = 5;
cols = 5;
size = 100;
board = shadowBoard = new int[rows][cols];
labelBoard = new JLabel[rows][cols];
fillLabelBoard();
for (int r = 0; r < rows; r ) {
for (int c = 0; c < cols; c ) {
this.add(labelBoard[r][c]);
}
}
// fill();
// printBoard();
}
void newBoard(int r, int c) {
rows = r;
cols = c;
board = new int[rows][cols];
shadowBoard = new int[rows][cols];
size = (int) ((r > c) ? SCREEN_SIZE / r : SCREEN_SIZE / c);
//Images.resize(size);
// fill();
//printBoard();
}
// void fill() {
// for (int r = 0; r < rows; r ) {
// for (int c = 0; c < cols; c ) {
// board[r][c] = Images.randomImage();
// }
// }
// }
void fillLabelBoard() {
for (int r = 0; r < rows; r ) {
for (int c = 0; c < cols; c ) {
labelBoard[r][c] = new JLabel();
labelBoard[r][c].setBounds(0, 0, size, size);
labelBoard[r][c].setBackground(Color.red);
labelBoard[r][c].setOpaque(true);
labelBoard[r][c].addMouseListener(this);
//add(labelBoard[r][c]);
}
}
}
//Debugging
void printBoard() {
for (int[] r : board) {
for (int c : r) {
System.out.print(c);
}
System.out.print("\n");
}
System.out.println(rows);
System.out.println(cols);
System.out.println(size);
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.print("click");
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
uj5u.com熱心網友回復:
覆寫paintComponentvs.的原因paint是 JComponent 實作paint了呼叫paintBackground、paintBorder和paintComponent. 這只是在現有 API 中添加間接步驟以便能夠分別繪制組件的不同部分的簡單案例。
uj5u.com熱心網友回復:
內部的 originpaint方法JComponent確實使用RepaintManager來確定是否必須完成渲染/繪畫。它還具有內部雙緩沖等機制。
paint僅paintComponent在組件或其客戶端矩形被標記為臟時呼叫,因此需要繪制。
當您覆寫時,paint您只需呼叫 origin 方法,然后您繪制自己的東西 - 這將始終完成。
但是,當您覆寫paintComponent您的部件時,當原始paint方法看不到需要渲染/繪制它時,您的部件將不會被渲染。如果你想使用paintComponent- 你必須確保組件將被標記為臟/要渲染。
有關詳細資訊,請查看JComponent paint實施:https ://github.com/openjdk/jdk/blob/739769c8fc4b496f08a92225a12d07414537b6c0/src/java.desktop/share/classes/javax/swing/JComponent.java#L1057-L1143
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/415683.html
標籤:
