我无法让JButton上的paintComponent()正常工作

时间:2016-01-30 20:34:28

标签: java swing jframe jbutton paintcomponent

我的JButton的paintComponent()方法有问题。我想编写自己的Minesweeper游戏,当我尝试重新绘制我的Tiles(扩展JButton)时,它们似乎没有更新。这是我的瓷砖类:

package mineSweeper;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;

public class Tile extends JButton{
/**
 * 
 */
private static final long serialVersionUID = 5476927382697663397L;
public static final int UNPRESSED = 0;
public static final int PRESSED = 1;
public static final int FLAG = 2;
public static final int BOMB = 3;
public static final int XBOMB = 4;
public static final int HEIGHT = 16;
public static final int WIDTH = 16;
private int paintMode = UNPRESSED;

public Tile(int x, int y){
    super();
    setBounds(x*WIDTH, y*HEIGHT, WIDTH, HEIGHT);
    setPreferredSize(new Dimension(WIDTH, HEIGHT));
    setMargin(new Insets(0, 0, 0, 0));
    setBorder(BorderFactory.createEmptyBorder());
    addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            setEnabled(false);
            setPaintMode(PRESSED);
            repaint();
        }
    });
}

public void reset(){
    setEnabled(true);
    setPaintMode(UNPRESSED);
    repaint();
}

@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    if (getPaintMode()==UNPRESSED)
    {
        setBackground(Color.LIGHT_GRAY);
        g.setColor(Color.WHITE);
        g.drawLine(0, 0, WIDTH-1, 0);
        g.drawLine(0, 1, WIDTH-2, 1);
        g.drawLine(0, 0, 0, HEIGHT-1);
        g.drawLine(1, 0, 1, HEIGHT-2);
        g.setColor(Color.GRAY);
        g.drawLine(WIDTH, HEIGHT, 1, HEIGHT);
        g.drawLine(WIDTH, HEIGHT-1, 2, HEIGHT-1);
        g.drawLine(WIDTH, HEIGHT, WIDTH, 1);
        g.drawLine(WIDTH-1, HEIGHT, WIDTH-1, 2);
    }
    if (getPaintMode()==PRESSED)
    {
        setBackground(Color.LIGHT_GRAY);
        g.drawLine(0, 0, WIDTH, 0);
        g.drawLine(0, 0, 0, HEIGHT);
    }
    g.dispose();
}

public int getPaintMode() {
    return paintMode;
}

public void setPaintMode(int mode) {
    mode = paintMode;
}
}

和班级董事会

package mineSweeper;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Board extends JFrame{

/**
 * 
 */
private static final long serialVersionUID = 2769769568511334271L;

public static Tile[][] tile;
public JPanel panel = new JPanel(null);
public JButton resetButton = new ResetButton("Click here to Reset");
String input;
private static int screenWidth = 400;
private static int screenHeight = 400;
private static final int MAXROWS = 60;
private static final int MAXCOLUMS = 60;
private static final int MINROWS = 2;
private static final int MINCOLUMS = 6;
private static final int RESETBUTTONSIZE = 40;

public Board(){
    super("MineSweeper");
    askForInputs();
    resetButton.setBounds(0, screenHeight, screenWidth, RESETBUTTONSIZE);
    tile = new Tile[getColums()][getRows()];
    pack();
    setSize(screenWidth + getInsets().left + getInsets().right, screenHeight + getInsets().top + getInsets().bottom + RESETBUTTONSIZE);
    getContentPane().add(panel);
    panel.add(resetButton);
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    for (int x = 0; x < getColums(); x++)
    {
        for (int y = 0; y < getRows(); y++)
        {
            tile[x][y] = new Tile(x,y);
            panel.add(tile[x][y]);
        }
    }
    setVisible(true);
}

private void askForInputs() {
    try{
    input = JOptionPane.showInputDialog(null, "Enter number of rows ( Maximum " + MAXROWS + " / Minimum " + MINROWS +")" );
    Integer.parseInt(input);
    }
    catch(Exception ex){input = "";}
    if (!(input == null) && !(input.isEmpty()) && !(Integer.parseInt(input) < MINROWS)){
        if (Integer.parseInt(input) > MAXROWS)
            screenHeight = MAXROWS * Tile.HEIGHT;
    }
    else input = String.valueOf(MAXROWS/4);
    screenHeight = Integer.parseInt(input) * Tile.HEIGHT;

    try{
    input = JOptionPane.showInputDialog(null, "Enter number of colums ( Maximum " + MAXCOLUMS + " / Minimum " + MINCOLUMS + ")" );
    Integer.parseInt(input);
    }
    catch(Exception ex){input = "";}
    if (!(input == null) && !(input.isEmpty()) && !(Integer.parseInt(input) < MINCOLUMS))
    {
    if (Integer.parseInt(input) > MAXCOLUMS)
        screenWidth = MAXCOLUMS * Tile.WIDTH;
    }
    else input = String.valueOf(MAXCOLUMS/4);
    screenWidth = Integer.parseInt(input) * Tile.WIDTH;
}

public static void reset(){
    for (int x = 0; x < getColums(); x++)
    {
        for (int y = 0; y < getRows(); y++)
        {
            tile[x][y].reset();
        }
    }
}

public static int getScreenWidth() {
    return screenWidth;
}
public static void setScreenWidth(int screenWidth) {
    Board.screenWidth = screenWidth;
}
public static int getScreenHeight() {
    return screenHeight;
}
public static void setScreenHeight(int screenHeight) {
    Board.screenHeight = screenHeight;
}
public static  int getColums(){
    return getScreenWidth() / Tile.WIDTH;
}
public static  int getRows(){
    return getScreenHeight() / Tile.HEIGHT;
}
public static void main (String args[]){
    new Board();
}
}

不介意未使用的进口商品。 所以我的问题是:当我点击Tile时,我看到我点击它,我不能再点击它,但它看起来像以前一样。 我做错了什么,请帮忙。

1 个答案:

答案 0 :(得分:2)

我身上出现了很多东西,但你的主要问题是......

public class Tile extends JButton {
    //...
    public void setPaintMode(int mode) {
        mode = paintMode;
    }
}

您实际上从未将当前模式分配给paintMode变量,分配是向后的。

我建议使用JFrame#setExtendedState在您当前使用的MAXIMIZED_BOTH黑客上设置框架setSize状态,这至少会减少代码量。

我还建议您每天使用GridLayoutGridBagLayout null布局。

您是否考虑使用JToggleButton,它基本上就是您现在正在做的事情?