无法在JButton上完成绘制线 [英] Can not complete drawline on JButton

查看:250
本文介绍了无法在JButton上完成绘制线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在制作一个简单的tic tac toe游戏,并在最后一分钟遇到问题。

我试图在赢得位置画一条线,但是最后的胜利位置(索引),该行隐藏在 JButton 后面,不能确定它为什么这样做。



<我知道很多人说不要使用 getGraphics(),我想知道这是否是我的问题的来源,他们说覆盖 paintComponent 方法,但这对我来说不是工作。



我附上了一张结果如何的图片和代码片段我试图执行这些操作



PS我正在使用 JFrame ,如果需要更多代码,我会很高兴显示它

  if(win [i] == 264){//如果其中一个组合等于'X','X ','X'等于264,然后在那里是赢家
System.out.println(X is the winner !!!);
System.out.println(游戏结束!);
number = i;
draw(); } //调用绘制方法

private void draw(){//在获胜位置绘制一条线


Graphics2D g1 =(Graphics2D)GUI.getFrame ).getGraphics(); //在我们的Jframe上声明图形
描边stroke3 =新的BasicStroke(12f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);如果(数字== 0){//语句将决定赢的位置,所以在win0,XXX,
g1.setStroke(stroke3); //我们将添加描边到我们的行
g1.drawLine(0,104,500,104); //从0,104开始画线,结束坐标500,104
}

是一个更易于运行的代码,它是很多虽然

  import java.awt.BasicStroke; 
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
导入javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class tic implements Runnable {
final static int row = 3; //我们的行
final static int col = 3; //我们的col
final static int sizeOfBoard = row * col;
//我们板子的大小不会改变,所以我们最终确定
static JButton [] clickButton;
char [] templateOfBoard; //我们的板,TicTacToe字段,静态
char userTurn; //用户转过来,只有一个字母,跟踪它是否是X或O
int count; //跟踪用户移动
静态JFrame框架; //我们的JFrame
int数字;


公共抽搐(JFrame框架){

tic.frame =新JFrame(TicTacToe GAME);
clickButton = new JButton [9];
count = 0; //转数从0开始;
number = 0;

setUserTurn('X'); //第一个回合将总是X
setTemplateOfBoard(new char [sizeOfBoard]); //我们要做的板的大小


尝试{
for(int spaces = 0; spaces< sizeOfBoard; spaces ++){// Board的大小是在GUI类中

getTemplateOfBoard()[spaces] =''; //电路板正在创建,循环遍历所有行和col

//电路板的每个索引都不具有等于空格的char值

//确定是否一切都正确
//应该等于总共9
// 3x3
}
System.out.println(Board template created); //表示板现在具有所有空间
}
catch(Exception e){
System.out.println(不能初始化板以清空字符);
e.printStackTrace();



public static void main(String [] args){

try {
SwingUtilities.invokeLater(new tic(帧)); //运行
}
catch(Exception e){//想要测试以确保Runnable可以被调用
System.out.println(不能执行Runnable应用程序);
e.printStackTrace();



public void run(){

setup(); //将使用设置方法,我们的游戏是由
}

公共void setup(){
//设置Board
/ / board由JButton
和一个3x3框架组成b

$ b frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //当用户关闭窗口时,JFrame将退出

//去设计板子
//板子的尺寸= sizeOfBoard

getFrame( ).setLayout(new GridLayout(row,col)); //这是大纲行* col
//根据我们将这些数字定义为
// col的大小排出col * col例如3x3

getFrame()。setBounds( 0,0,500,500); //位置为0,0,大小为500 x 500
Border border = new LineBorder(Color.DARK_GRAY,2); // JButton边框的颜色

System.out.println(您的棋盘游戏正在创建!);

尝试{
getFrame()。setVisible(true); //显示板,
//这将显示屏幕上的所有内容
System.out.println(Board is now visable);
}
catch(Exception e){
System.out.println(Board was not displayed);
}

// 9个不同的按钮,对于每个索引,都会有一个按钮
(int i = 0; i< sizeOfBoard; i ++){//要填充带有clickableButtons的板通过循环遍历每个索引并在其中放置一个按钮
final int move = i;

clickButton [i] = new JButton(); //在某个索引处有一个新按钮
clickButton [i] .setSize(250,250); //每个按钮的大小
clickButton [i] .setBackground(Color.WHITE); // JButton的颜色

getFrame()。add(clickButton [i]); //我们将在框架上的该索引处添加实际的按钮

clickButton [i] .setFont(new Font(Arial,Font.BOLD,70)); //文本的大小
clickButton [i] .setBorder(border); //添加边框

clickButton [i] .getModel()。addChangeListener(new ChangeListener(){//将覆盖当我们滚动并按下Butotn

时发生的情况public void stateChanged(ChangeEvent e){
ButtonModel button =(ButtonModel)e.getSource(); //管理按钮的状态,即让我控制按钮发生了什么

如果(clickButton [move]!= null){//如果我们不包含这个参数
//这个按钮在新游戏中还没有制作,这意味着clickButton [i] = null
//所以boolean(!button.isRollover())将返回true,因为在新游戏中,你不能让鼠标悬停在
上//但是当它返回true时,它将返回一个空值,并给出一个空指针例外
//最好的办法是只在按钮不为空$ b $时才运行这些情况b
if(button.isRollover()){//当鼠标悬停在索引上时
clickButton [move] .setBackground(Color.BLACK); //颜色将等于黑色
}
否则if(!button.isRollover()){//当按钮没有悬停在
上时clickButton [move] .setBackground(Color.WHITE) ; // color will be whte,like like our background
}

}
}
});


clickButton [i] .addActionListener(new ActionListener(){

//我们的点击事件,将被覆盖以让它知道我们想要发生的事情
//一旦我们点击按钮
public void actionPerformed(ActionEvent e){


clickButton [move] .setEnabled(false); //去在点击后禁用按钮
// ORDER:按钮首先被点击,然后测试被添加
mouseListener(e,move); //我们在游戏类中的mouseListenerEvent

//
}
});



$ b public static void playAgain(){

try {
System.out.println(新游戏);
SwingUtilities.invokeLater(new tic(frame)); //再次运行run(class)
}
catch(Exception e){//想测试以确保Runnable可以被调用
System.out.println(Could not Execute Runnable应用程序);
e.printStackTrace();



public static JFrame getFrame(){
return frame;
}

public tic userMove(int moveMade){

getTemplateOfBoard()[moveMade] = getUserTurn();
//董事会的索引,或者以更简单的方式,其中用户
//在那里插入,即X或O,0-8
//System.out.println(userMove) ;

//布尔语句来确定转向
//所以用户X首先开始
//如果转弯是X,nextTurn现在是O,

if(getUserTurn()=='X'){
setUserTurn('O');
}
else {
setUserTurn('X');
}

count ++;

返回这个; //要返回userTurn
//实际进入userTurn的问题没有给出正确的值,但使用'this'确实是
}


// for一些奇怪的原因toString导致了一些问题,不断得到@hash代码
//在线看到它覆盖它,像这样
//将使电路板脱离emepty字符串
// //去返回一个对象的字符串表示形式
public String toString(){
return new String(getTemplateOfBoard());

$ b $ public void mouseListener(ActionEvent e,int moveMade){
//鼠标点击事件
//点击按钮后会发生什么

if(getTemplateOfBoard()[moveMade] ==''){//用户只能点击一下,所以字段上的字母如果为空
((JButton)e.getSource ))的setText(Character.toString(getUserTurn()))。 //当按钮被点击时,我们想要一个X放在那里
if(getUserTurn()=='X'){
UIManager.getDefaults()。put(Button.disabledText,Color。红); //当禁用时,测试会变成红色
}
else {
UIManager.getDefaults()。put(Button.disabledText,Color.BLUE);
}
//调用方法userTurn来确定下一步是谁
//问题在于需要一个字符串
//要覆盖toString方法

userMove(moveMade); //在moveMade中调用userMove,moveMade是用户放置X或者O
赢者()的索引; //我们要检查每一次以确保有/没有赢家

}

}


公共抽象赢家(){//确定谁是赢家


//下面的列表定义了所有可能的赢得组合
// X或O可以放置的位置的索引
//将位置放置为一个int值
int win1 = templateOfBoard [0] + templateOfBoard [1] + templateOfBoard [2];
int win2 = templateOfBoard [3] + templateOfBoard [4] + templateOfBoard [5];
int win3 = templateOfBoard [6] + templateOfBoard [7] + templateOfBoard [8];
int win4 = templateOfBoard [0] + templateOfBoard [3] + templateOfBoard [6];
int win5 = templateOfBoard [1] + templateOfBoard [4] + templateOfBoard [7];
int win6 = templateOfBoard [2] + templateOfBoard [5] + templateOfBoard [8];
int win7 = templateOfBoard [0] + templateOfBoard [4] + templateOfBoard [8];
int win8 = templateOfBoard [2] + templateOfBoard [4] + templateOfBoard [6];
$ b $ int [] win = new int [] {win1,win2,win3,win4,win5,win6,win7,win8};
//让数组经历所有可能的胜利
//可能的总赢数是8


for(int i = 0; i //循环赢得可能性


if(win [i] == 264){//如果其中一个组合等于' X','X','X'等于264,那么有一个赢家
System.out.println(X is the winner !!!);
System.out.println(游戏结束!);
number = i;
draw(); //调用draw方法



return this; //如果语句是真的,它会返回这个(gameOver)
}
else if(win [i] == 237){//如果其中一个组合等于'O','O ','O'等于234,那么有一个赢家
System.out.println(O is the winner !!!);
System.out.println(游戏结束!);
number = i;
// draw(); //调用draw方法




return this;



if(count == 9){
//如果以上任何一个语句都不是真的,它会自动完成到这里
//如果有9次移动并且没有胜利,那么这是一个平局


}

}

return this;
//将返回此方法;

$ b $ private void draw(){//在获奖位置绘制一条线


Graphics2D g1 =(Graphics2D)getFrame()。getGraphics (); //在我们的Jframe上声明图形
描边stroke3 =新的BasicStroke(12f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);如果(数字== 0){//语句将决定赢的位置,所以在win0,XXX,
g1.setStroke(stroke3); //我们将添加描边到我们的行
g1.drawLine(0,104,500,104); //画出从0,104开始的行并结束坐标500,104
}
else if(number == 1){
g1.setStroke(stroke3);
g1.drawLine(0,257,500,257);
}
else if(number == 2){
g1.setStroke(stroke3);
g1.drawLine(0,411,500,411);
}
else if(number == 3){
g1.setStroke(stroke3);
g1.drawLine(88,0,88,500);
}
else if(number == 4){
g1.setStroke(stroke3);
g1.drawLine(250,0,250,500);
}
else if(number == 5){
g1.setStroke(stroke3);
g1.drawLine(411,0,411,500);
}
else if(number == 6){
g1.setStroke(stroke3);
g1.drawLine(-22,0,500,500);


else if(number == 7){
g1.setStroke(stroke3);
g1.drawLine(520,0,0,500);
}
}

//希望能够访问私有变量
//所以我们将为我们需要的$ get get和setter方法b $ b public char getUserTurn(){//用于userTurn的getter方法
返回userTurn;
}

public void setUserTurn(char userTurn){// setter method
this.userTurn = userTurn;

$ b $ public char [] getTemplateOfBoard(){// getter method
return templateOfBoard;
}

public void setTemplateOfBoard(char [] templateOfBoard){// setter method
this.templateOfBoard = templateOfBoard;
}

}


解决方案

在组件顶部绘制可能会很麻烦,您不能覆盖包含组件的容器的 paintComponent 方法,因为这会在后台绘制,不能覆盖容器的 paint 方法,因为子组件可以被绘制而不通知父容器...



你可以在整个地方添加一个透明的组件,但是这会引入更多的复杂性,特别是当一个组件已经存在的时候...

  public class ConnectTheDots {

public static void main(String [] args){$ b $ new ConnectTheDots();

$ b public ConnectTheDots(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
尝试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception ex){
}

PaintPane pp = new PaintPane();

JFrame frame = new JFrame(Test);
frame.setGlassPane(pp);
pp.setVisible(true);
frame.setDefaultCloseOperation(JFrame );
frame.add(new DotsPane(pp));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true) ;
}
});
}

公共类PaintPane扩展JPanel {

private List< JButton []>连接;
私人JButton lastSelected;

public PaintPane(){
setOpaque(false);
connections = new ArrayList<>(25);


@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d =(Graphics2D)g.create();
if(lastSelected!= null){
g2d.setColor(Color.RED);
int x = lastSelected.getX()+((lastSelected.getWidth() - 8)/ 2);
int y = lastSelected.getY()+((lastSelected.getHeight() - 8)/ 2);
g2d.fillOval(x,y,8,8);
}
(JButton [] group:connections){
g2d.setColor(Color.BLUE);
Point startPoint = group [0] .getLocation();
Point endPoint = group [1] .getLocation();
startPoint.x + =(group [0] .getWidth()/ 2);
startPoint.y + =(group [1] .getHeight()/ 2);
endPoint.x + =(group [0] .getWidth()/ 2);
endPoint.y + =(group [1] .getHeight()/ 2);
g2d.draw(new Line2D.Float(startPoint,endPoint));
}
g2d.dispose();


保护无效buttonClicked(JButton btn){
if(lastSelected == null){
lastSelected = btn;
} else {
connections.add(new JButton [] {lastSelected,btn});
lastSelected = null;
}
revalidate();
repaint();
}
}

公共类DotsPane扩展JPanel {

私有PaintPane paintPane;

public DotsPane(final PaintPane pp){
paintPane = pp;
ActionListener al = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
JButton btn =(JButton)e.getSource();
paintPane.buttonClicked(btn);
}
};
setLayout(new GridLayout(6,6));
for(int index = 0; index< 6 * 6; index ++){
JButton btn = new JButton(。);
add(btn);
btn.addActionListener(al);
}
}

@Override
public Dimension getPreferredSize(){
return new Dimension(200,200);



看看如何使用根窗格了解更多详情


So I am making a simple tic tac toe game and ran into a problem at the last minute

I am trying to draw a line at the win location but on the final win location(index), the line gets hidden behind the JButton not entirly sure why it is doing this.

I know alot of people say do not use getGraphics(), and I am wondering if that is the source of my issues they say to override the paintComponent method but that is not working for me either

I have attached a pic of what the result is looking like and code snips of how I am trying to perform these actions

PS I am using a JFrame, if any more code is needed I will be glad to show it

if(win[i] == 264){ // if one of the the combinations equal 'X','X','X' which equals 264, then there is a winner 
            System.out.println("X is the winner!!!");   
            System.out.println("Game Over!");
            number = i;
            draw(); }// call draw method 

 private void draw(){   // drawing a line at winning location 


Graphics2D  g1 = (Graphics2D) GUI.getFrame().getGraphics(); // declaring graphics on our Jframe 
    Stroke stroke3 = new BasicStroke(12f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); // make our strokes cap off round 

    if(number == 0){ // statements will determine the win location, so at win0, XXX, 
        g1.setStroke(stroke3); // we will add stroke to our line 
        g1.drawLine(0,104,500,104); // draw the line starting at the 0,104 and end it at coordinates 500,104 
    }

here is a more runnable code, it is alot though

    import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class tic implements Runnable {
    final static int row = 3; // our rows 
    final static int col = 3; // our col 
    final static int sizeOfBoard = row * col; 
    // the size of our board is not going to change so we make it final
    static JButton[] clickButton;
    char[] templateOfBoard; // our board, TicTacToe field, static
    char userTurn; // users turn , only one letter, tracks whether it is a X or O 
    int count; // keeps track of user moves
    static JFrame frame; // our JFrame
    int number;


    public tic(JFrame frame) {

        tic.frame = new JFrame("TicTacToe GAME");  
        clickButton = new JButton[9];
        count = 0; // number of turns starts at 0;
        number = 0;

        setUserTurn('X'); // first turn will always be X
        setTemplateOfBoard(new char[sizeOfBoard]); // size of the board we are going to make it 


        try{
            for(int spaces=0; spaces<sizeOfBoard; spaces++){ // size of Board is in the GUI class

                getTemplateOfBoard()[spaces] = ' '; // the board is being created, looping through all rows and col

                //every index of the board not has a char value equal to a space 

                //determine if everything came out correctly 
                //should equal of a total of 9
                // 3x3
            }
            System.out.println("Board template created"); // means the board now has all spaces 
        }
        catch(Exception e){
            System.out.println("Could not initalize the board to empty char");
            e.printStackTrace();
        }
    }

    public static void main(String[] args){

        try{
            SwingUtilities.invokeLater(new tic(frame)); // run 
        }
        catch(Exception e){ // wanted to test to ensure that Runnable could be invoked 
            System.out.println("Could not excute Runnable application");
            e.printStackTrace();
        }
    }

    public void run()  {

        setup(); // going to run out setup method, what our game is made out of 
    } 

    public void setup() {
        // setting up the Board 
        // board is composed of JButton 
        // and a 3x3 frame 


        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when the user closes the window JFrame  will exit 

        //going to design the board now 
        //the dimensations of the board = sizeOfBoard

        getFrame().setLayout(new GridLayout(row, col)); // this is the outline rows * col 
        // sizes out row * col based on what we define those numbers as
        //i.e 3x3

        getFrame().setBounds(0,0,500,500); // location at 0,0, size 500 x 500 
        Border border = new LineBorder(Color.DARK_GRAY, 2); // color of JButton border 

        System.out.println("Your board game is being created!");

        try{
            getFrame().setVisible(true); // shows the board, 
            // this is going to display everything to the screen 
            System.out.println("Board is now visable");
        }
        catch(Exception e){
            System.out.println("Board was not displayed");
        }

        // 9 different buttons, for every index there will be a button 
        for(int i =0; i<sizeOfBoard;i++){ // going to fill the board with clickableButtons by looping through every index and placing a button there 
            final int move = i;

            clickButton[i] = new JButton(); // at a certain index there is a new button 
            clickButton[i].setSize(250,250); // size of each button 
            clickButton[i].setBackground(Color.WHITE); // color of the JButton 

            getFrame().add(clickButton[i]); // we are going to add the actual the button at that index on the frame 

            clickButton[i].setFont(new Font("Arial", Font.BOLD, 70)); // size of the text 
            clickButton[i].setBorder(border); // adding border 

            clickButton[i].getModel().addChangeListener(new ChangeListener() { //going to overRide what happens when we rollover and press a Butotn 

                public void stateChanged(ChangeEvent e) {
                    ButtonModel button = (ButtonModel) e.getSource(); // manages the state of the button, i.e lets me control what happens to the button 

                    if(clickButton[move] != null){ // if we do not include this argument 
                        // the buttons are not made yet on the new game, meaning clickButton[i] = null
                        //so boolean(!button.isRollover()) will return true, since on the new game you can not have your mouse hovered over 
                        // but when it returns true, it will return a null value, giving a null pointer exception 
                        // so best thing to do, is to only run these cases below when the buttons are not null

                        if (button.isRollover()) { // when the mouse hovers over the index 
                            clickButton[move].setBackground(Color.BLACK); // color will equal black 
                        }
                        else if(!button.isRollover()){ // when the button is not hovered over
                            clickButton[move].setBackground(Color.WHITE); // color will be whte, just like our background 
                        }

                    }
                }
            });


            clickButton[i].addActionListener(new ActionListener() { 

                //our click events, going to override to let it know what we want to happen
                //once we click on the button
                public void actionPerformed(ActionEvent e) {


                    clickButton[move].setEnabled(false); //going to disable the button after it is clicked 
                    //ORDER: button gets clicked first, then the test is added
                    mouseListener(e, move); // our mouseListenerEvent in game class 

                    //
                } 
            });
        }           
    }


    public static void playAgain() {

        try{
            System.out.println("NEW GAME");
            SwingUtilities.invokeLater(new tic(frame));  // run the run(class) again 
        }
        catch(Exception e){ // wanted to test to ensure that Runnable could be invoked 
            System.out.println("Could not excute Runnable application");
            e.printStackTrace();
        }
    }

    public static JFrame getFrame() {
        return frame;
    }

    public tic userMove(int moveMade){

        getTemplateOfBoard()[moveMade] = getUserTurn();
        // index of the board, or in simpler terms, where the user
        // inserts there turn i.e X or O, 0-8
        //System.out.println(userMove);

        //boolean statement to determine the turns 
        // So user X starts first
        //if the turn is X, the nextTurn is now O,

        if(getUserTurn() == 'X'){
            setUserTurn('O');   
        }
        else {
            setUserTurn('X');
        }

        count++; 

        return this; // going to return the userTurn
        // issue actually entering the userTurn is not giving right value, but using 'this' does 
    }


    // for some odd reason the toString is causing some issues, keep getting @hash code
    //saw online to override it like this 
    // will make the board out of emepty strings 
    // going to return a string representation of an object 
    public String toString(){
        return new String(getTemplateOfBoard());
    }

    public void mouseListener(ActionEvent e, int moveMade){ 
        // mouse click events 
        // what happens after a button is clicked 

        if(getTemplateOfBoard()[moveMade] == ' '){ // the user can only space a click, so an letter on the field if it is empty 
            ((JButton)e.getSource()).setText(Character.toString(getUserTurn())); // when the button is clicked, we want an X placed there 
            if (getUserTurn() == 'X'){
                UIManager.getDefaults().put("Button.disabledText",Color.RED); // when the but gets disabled the test will turn red      
            }
            else{
                UIManager.getDefaults().put("Button.disabledText",Color.BLUE);
            }
            //calling the method userTurn to determine who goes next
            //problem is that is expects a String
            //going to override the toString method 

            userMove(moveMade); // calling userMove in moveMade, moveMade is the index at which the user put either an X or a O
            winner(); // we want to check each time to ensure there was/was not a winner 

        } 

    }


    public tic winner() { // determines who is the winner


        //list below defines all the possible win combinations 
        // the index of where a X or O can be place
        // placed the locations to a int value 
        int win1 = templateOfBoard[0] + templateOfBoard[1] + templateOfBoard[2];    
        int win2 = templateOfBoard[3] + templateOfBoard[4] + templateOfBoard[5];
        int win3 = templateOfBoard[6] + templateOfBoard[7] + templateOfBoard[8];
        int win4 = templateOfBoard[0] + templateOfBoard[3] + templateOfBoard[6];
        int win5 = templateOfBoard[1] + templateOfBoard[4] + templateOfBoard[7];
        int win6 = templateOfBoard[2] + templateOfBoard[5] + templateOfBoard[8];
        int win7 = templateOfBoard[0] + templateOfBoard[4] + templateOfBoard[8];
        int win8 = templateOfBoard[2] + templateOfBoard[4] + templateOfBoard[6];

        int[] win = new int[]{win1,win2,win3,win4,win5,win6,win7,win8}; 
        // making a array to go through all the possibile wins 
        //possible total of wins is 8


        for(int i = 0;i<win.length;i++){     
            // looping through the win possibilities 


            if(win[i] == 264){ // if one of the the combinations equal 'X','X','X' which equals 264, then there is a winner 
                System.out.println("X is the winner!!!");   
                System.out.println("Game Over!");
                number = i;
                draw(); // call draw method 



                return this; // if statement is true, it will return this(gameOver)
            }
            else if(win[i] == 237 ){ // if one of the the combinations equal 'O','O','O' which equals 234, then there is a winner 
                System.out.println("O is the winner!!!");
                System.out.println("Game Over!");
                number = i;
                //draw(); // call draw method 




                return this;

            }

            if (count == 9) {
                // if none of the statements above are true, it automatically comes done to here
                //so if there is nine moves and no win, it is a draw 


            } 

        }

        return this; 
        // going to return this method ;
    } 

    private void draw(){    // drawing a line at winning location 


        Graphics2D  g1 = (Graphics2D) getFrame().getGraphics(); // declaring graphics on our Jframe 
        Stroke stroke3 = new BasicStroke(12f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); // make our strokes cap off round 

        if(number == 0){ // statements will determine the win location, so at win0, XXX, 
            g1.setStroke(stroke3); // we will add stroke to our line 
            g1.drawLine(0,104,500,104); // draw the line starting at the 0,104 and end it at coordinates 500,104 
        }
        else if(number == 1){
            g1.setStroke(stroke3);
            g1.drawLine(0,257,500,257);
        }
        else if(number == 2){
            g1.setStroke(stroke3);
            g1.drawLine(0,411,500,411); 
        }
        else if(number == 3){
            g1.setStroke(stroke3);
            g1.drawLine(88,0,88,500);   
        }
        else if(number == 4){
            g1.setStroke(stroke3);
            g1.drawLine(250,0,250,500);
        }
        else if(number == 5){
            g1.setStroke(stroke3);
            g1.drawLine(411,0,411,500);
        }
        else if(number == 6){
            g1.setStroke(stroke3);
            g1.drawLine(-22,0,500,500);

        }
        else if(number == 7){
            g1.setStroke(stroke3);
            g1.drawLine(520,0,0,500);
        }
    }

    // want to be able to access the private variables 
    //so we will make getter and setter methods for the ones that we need
    public char getUserTurn() { // getter method for userTurn
        return userTurn;
    }

    public void setUserTurn(char userTurn) { // setter method 
        this.userTurn = userTurn;
    }

    public char[] getTemplateOfBoard() { //getter method 
        return templateOfBoard;
    }

    public void setTemplateOfBoard(char[] templateOfBoard) { // setter method 
        this.templateOfBoard = templateOfBoard;
    }

}

解决方案

Painting over the top of components can be troublesome, you can't override the paintComponent method of the container which contains the components, because this paints in the background, you can't override the paint method of the container, as child components can be painted without the parent container been notified...

You could add a transparent component over the whole lot, but this just introduces more complexity, especially when a component already already exists ...

public class ConnectTheDots {

    public static void main(String[] args) {
        new ConnectTheDots();
    }

    public ConnectTheDots() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                PaintPane pp = new PaintPane();

                JFrame frame = new JFrame("Test");
                frame.setGlassPane(pp);
                pp.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new DotsPane(pp));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintPane extends JPanel {

        private List<JButton[]> connections;
        private JButton lastSelected;

        public PaintPane() {
            setOpaque(false);
            connections = new ArrayList<>(25);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (lastSelected != null) {
                g2d.setColor(Color.RED);
                int x = lastSelected.getX() + ((lastSelected.getWidth() - 8) / 2);
                int y = lastSelected.getY() + ((lastSelected.getHeight() - 8) / 2);
                g2d.fillOval(x, y, 8, 8);
            }
            for (JButton[] group : connections) {
                g2d.setColor(Color.BLUE);
                Point startPoint = group[0].getLocation();
                Point endPoint = group[1].getLocation();
                startPoint.x += (group[0].getWidth() / 2);
                startPoint.y += (group[1].getHeight()/ 2);
                endPoint.x += (group[0].getWidth() / 2);
                endPoint.y += (group[1].getHeight()/ 2);
                g2d.draw(new Line2D.Float(startPoint, endPoint));
            }
            g2d.dispose();
        }

        protected void buttonClicked(JButton btn) {
            if (lastSelected == null) {
                lastSelected = btn;
            } else {
                connections.add(new JButton[]{lastSelected, btn});
                lastSelected = null;
            }
            revalidate();
            repaint();
        }
    }

    public class DotsPane extends JPanel {

        private PaintPane paintPane;

        public DotsPane(final PaintPane pp) {
            paintPane = pp;
            ActionListener al = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JButton btn = (JButton) e.getSource();
                    paintPane.buttonClicked(btn);
                }
            };
            setLayout(new GridLayout(6, 6));
            for (int index = 0; index < 6 * 6; index++) {
                JButton btn = new JButton(".");
                add(btn);
                btn.addActionListener(al);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }
}

Take a look at How to Use Root Panes for more details

这篇关于无法在JButton上完成绘制线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆