2016-01-30 17 views
0

我遇到了我的JButton的paintComponent()方法的問題。我想編程自己的掃雷遊戲,當我嘗試重新繪製我的Tiles(它擴展了JButton)時,它們似乎沒有更新。這裏是我的瓷磚類:我無法讓JButton上的paintComponent()正常工作

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(); 
} 
} 

不介意未使用的導入。 所以我的問題是:當我點擊一個瓷磚我看到我點擊它,我不能再次點擊它,但它看起來像以前一樣。 我在做什麼錯,請幫忙。

+0

除非你自己創建了'Graphics'的實例,否則不要調用'g.dispose();'你有沒有考慮過使用'JToggleButton'? – MadProgrammer

+0

此外,請考慮使用'setExtendedState'來設置窗口爲最大化狀態,而不是您似乎正在使用的hacky'setSize'過程 – MadProgrammer

+0

您還應該考慮使用'GridLaout'或'GridBagLayout',您通常會變得更好結果 – MadProgrammer

回答

2

有許多事情我蹦出來,但你的主要問題是這樣的......

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

你從來沒有真正分配將當前模式的paintMode變量賦值是倒退。

我推薦使用JFrame#setExtendedState來設置框架MAXIMIZED_BOTH狀態通過你目前使用的setSize黑客,它至少會減少代碼量。

我還建議任何一天使用GridLayoutGridBagLayout佈局null佈局。

你有沒有考慮過使用JToggleButton,這基本上是你現在在做什麼?

+0

感謝您的幫助。現在它與setPaintMode()一起工作。我並沒有真正看過大多數的搖擺文件,所以我甚至不知道setExtendedState或JToggleButton是一件事情。此外,我從來沒有使用過與BorderLayout不同的LayoutManager,所以我也得看看這個。 – Skrelp