我尝试了解MouseActionListener / Adapter类以及Graphics,我认为我是通过创建Tic-Tac-Toe游戏来实现的。我并不想使用JButton,因为我只是改变按钮上的措辞而不是绘制图形图像。 我无法让我的面板绘制图像。我为JPanels创建了两个内部类,一个叫做Board,一个用于MouseAdapter类。我的绘制方法位于Board类中,但是当我单击JPanel时它不会绘制图形(到目前为止我只是设置为绘制X)。 我知道它识别出使用调试器点击了一个面板,但是我不明白为什么它在调用时不会调用paint方法。
这是我的代码:
package xno;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics.*;
/**
*
* @author jordynsmith
*/
public class XnOFrame extends JFrame {
private int win=0;
private int loss=0;
private int turn=1; //keeps track of the turn so that color can change with each turn
public XnOFrame(){
super("X n' O");
//instantiate
board = new Board[3][3];
for(int i=0 ;i< 3; i++){
for(int j=0; j<3; j++){
board[i][j] = new Board();
board[i][j].setStatus("Empty");
board[i][j].setBackground(Color.black);
//creates tic tac toe border
//1st column
if(j==0){//top
board[i][j].setBorder(BorderFactory.createMatteBorder(0, 0, 2, 2, Color.blue));
if(i==1){//center
board[i][j].setBorder(BorderFactory.createMatteBorder(2, 0, 2, 0, Color.blue));
}
if(i==2){//bottom
board[i][j].setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, Color.blue));
}
}
//2nd column
else if(j==1){//top
board[i][j].setBorder(BorderFactory.createMatteBorder(0, 2, 2, 2, Color.blue));
if(i==1){//center
board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.blue));
}
if(i==2){//bottom
board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 0, 2, Color.blue));
}
}
//3rd column
else if(j==2){//top
board[i][j].setBorder(BorderFactory.createMatteBorder(0, 2, 2, 0, Color.blue));
if(i==1){//center
board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 2, 0, Color.blue));
}
if(i==2){//bottom
board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 0, 0, Color.blue));
}
}
}
}
goBtn = new JButton("Start Game");
quitBtn = new JButton("End Game");
newBtn = new JButton("New Game");
score = new JLabel("Score");
wins = new JLabel("Wins");
losses = new JLabel("Losses");
wPoints = new JLabel(win + "");
lPoints = new JLabel(loss + "");
line = new JLabel("||");
menuPanel = new JPanel();
scorePanel = new JPanel();
gridPanel = new JPanel();
scoreLabelPanel = new JPanel();
pointsPanel = new JPanel();
//set layout
this.setLayout(new BorderLayout());
menuPanel.setLayout(new FlowLayout());
scorePanel.setLayout(new BorderLayout());
gridPanel.setLayout(new GridLayout(3,3));
scoreLabelPanel.setLayout(new FlowLayout());
pointsPanel.setLayout(new FlowLayout());
//add components
this.add(gridPanel, BorderLayout.CENTER);
this.add(menuPanel, BorderLayout.SOUTH);
this.add(scorePanel, BorderLayout.WEST);
menuPanel.add(goBtn);
menuPanel.add(quitBtn);
menuPanel.add(newBtn);
scorePanel.add(scoreLabelPanel, BorderLayout.NORTH);
scorePanel.add(pointsPanel, BorderLayout.CENTER);
scoreLabelPanel.add(score);
pointsPanel.add(wins);
pointsPanel.add(wPoints);
pointsPanel.add(line);
pointsPanel.add(losses);
pointsPanel.add(lPoints);
for(int i=0; i<board.length; i++){
for(int j=0; j<board[i].length; j++){
gridPanel.add(board[i][j]);
}
}
//adding action
for(int i=0; i<board.length; i++){
for(int j=0; j<board[i].length; j++){
board[i][j].addMouseListener(new BoardAction());
}
}
}
这就是我的问题所在。我不确定如何组织以及何时调用某些方法,以及应该调用什么来使其工作。
private class BoardAction extends MouseAdapter{
private Board panel = new Board();
@Override
public void mouseClicked(MouseEvent me){
//determines which panel was clicked
panel = (Board) me.getSource();
panel.repaint();//calls paint method
}
}
private class Board extends JPanel{
public String status;
public Board(){
status="Empty";
}
public String getStatus(){
return status;
}
public void setStatus(String s){
status = s;
}
public void piant(Graphics g){
super.paint(g);
draw(g);
}
private void draw(Graphics g){
if(status.equals("Empty")){//paints x if empty
if(turn%2 != 0){//if turn is odd the color is green
g.setColor(Color.green);
}
else//if even the color is yellow
g.setColor(Color.yellow);
g.drawLine(0, 0, getWidth(), getHeight());
g.drawLine(getHeight(), 0, getWidth(), 0);
setStatus("X");
}
}
}
//components
Board [][] board;
JPanel menuPanel, scorePanel, gridPanel, scoreLabelPanel, pointsPanel;
JButton goBtn, quitBtn, newBtn;
JLabel score, wins, losses, wPoints, lPoints, line;
}
因此,在将paint方法更改为paintComponent之后,调用super.paint()方法时会抛出StackOverflowError,并且我的JButton将永远显示。只是为了看看会发生什么,我评论说排队并运行程序。通过这样做,我得到了这个: 黑色面板是我点击的那个。面板应为黑色以开始,单击时绿线应显示。此外,只有一条绿线出现(应该有两条,因为它是一个x)。我正在尽力遵循教程,但非常感谢任何其他帮助!
答案 0 :(得分:3)
public void piant(Graphics g){
piant!=油漆。
paintComponent
@Override
注释,以便编辑器在您做错时告诉您。答案 1 :(得分:3)
不要在paint
private void draw(Graphics g){
if(status.equals("Empty")){//paints x if empty
if(turn%2 != 0){//if turn is odd the color is green
g.setColor(Color.green);
}
else//if even the color is yellow
g.setColor(Color.yellow);
g.drawLine(0, 0, getWidth(), getHeight());
g.drawLine(getHeight(), 0, getWidth(), 0);
// This is bad idea...
setStatus("X");
}
}
绘制方法不应该只绘制组件的当前状态,它永远不应该修改它。
首选使用paintComponent
而不是paint
。有关详细信息,请参阅Painting in AWT and Swing和Performing Custom Painting
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
private void draw(Graphics g) {
if (status.equals("Empty")) {//paints x if empty
if (turn % 2 != 0) {//if turn is odd the color is green
g.setColor(Color.green);
} else//if even the color is yellow
{
g.setColor(Color.yellow);
}
g.drawLine(0, 0, getWidth(), getHeight());
g.drawLine(getHeight(), 0, getWidth(), 0);
}
}
您的BoardAction
实际上应该以某种有意义的方式更改Board
的状态...
private class BoardAction extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent me) {
//determines which panel was clicked
Board panel = (Board) me.getSource();
panel.setStatus("X");
panel.repaint();//calls paint method
}
}
另请注意,您Board
类还应覆盖getPreferredSize
并返回0x0
以外的其他大小