Java 无法使用JPanels
我试图理解MouseActionListener/Adapter类以及图形,我想我应该通过创建一个Tic-Tac-Toe游戏来做到这一点。我不想使用JButtons,因为我只是在更改按钮上的文字,而不是绘制图形图像。 我无法让我的面板绘制图像。我创建了两个内部类,一个用于JPanel,称为Board,另一个用于MouseAdapter类。我的paint方法位于Board类中,但当我单击JPanel时,它不会绘制图形(到目前为止,我只是设置为绘制X)。 我知道它可以识别面板是通过使用调试器单击的,但我不明白为什么它在调用时不调用paint方法 这是我的密码:Java 无法使用JPanels,java,swing,graphics,mouselistener,Java,Swing,Graphics,Mouselistener,我试图理解MouseActionListener/Adapter类以及图形,我想我应该通过创建一个Tic-Tac-Toe游戏来做到这一点。我不想使用JButtons,因为我只是在更改按钮上的文字,而不是绘制图形图像。 我无法让我的面板绘制图像。我创建了两个内部类,一个用于JPanel,称为Board,另一个用于MouseAdapter类。我的paint方法位于Board类中,但当我单击JPanel时,它不会绘制图形(到目前为止,我只是设置为绘制X)。 我知道它可以识别面板是通过使用调试器单击的,
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());
}
}
}
}
因此,在将我的paint方法更改为paintComponent之后,调用super.paint()方法时会抛出StackOverflower错误,我的JButtons会永远出现。为了看看会发生什么,我把那行注释掉,然后运行程序。通过这样做,我得到了以下结论:
黑色面板就是我点击的那个。面板开始时应为黑色,单击时应显示绿线。此外,只有一条绿线显示(因为它是x,所以应该有两条)。我正在尽我最大的努力学习教程,但是非常感谢任何额外的帮助
public void piant(Graphics g){
皮安特!=油漆
paintComponent
@override
注释,这样编译器会在您出错时告诉您paintComponent
@override
注释,这样编译器会在您出错时告诉您不要更改内部组件的状态
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
。有关详细信息,请参阅和
@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);
}
}
您的板操作
实际上应该以某种有意义的方式更改板
的状态
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
不要更改内部组件的状态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
。有关详细信息,请参阅和
@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);
}
}
您的板操作
实际上应该以某种有意义的方式更改板
的状态
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
1。不要在BorderActon
中创建Board
的新实例,不需要它;2.覆盖paintComponent
,以支持paint
;3.据推测,您的BoardAction
实际上应该以某种有意义的方式更改Board
的状态1。不要在BorderActon
中创建Board
的新实例,不需要它;2.覆盖paintComponent
,以支持paint
;3.据推测,您的BoardAction
实际上应该以某种有意义的方式更改Board
的状态way@JonnyHenly因为它实际上并没有回答这个问题,但提供了通常很好的建议,这将有助于OP进一步减少问题的数量,这些代码有助于隔离实际问题。如果我们说过一次,我们已经说过一千次了:P@JonnyHenly因为它实际上并没有回答这个问题,但提供了通常很好的建议,这将有助于OP进一步减少问题的数量,这些代码有助于隔离实际问题。如果我们说过一次,我们已经说过一千次了:P