2015-05-12 4 views
0

Я (начинающий программист) пытаюсь нарисовать овал над JPanel. Я пытаюсь использовать метод paint. Однако для этого требуется аргумент Graphics. Я получаю исключение NullPointerException, когда я включаю свою графику в качестве аргумента, потому что она равна нулю, но я не знаю, как еще рисовать овал. Я попробовал перерисовать, но ничего не произошло. Любая помощь будет оценена по достоинству. Вот мой основной класс:Как нарисовать поверх JPanel?

public class Checkers extends JPanel{ 
public static final int BOARDSQUARES = 8; 
public static final int BOARDSIZE = 75; 
    private JPanel[][] board; 
    private final Point point1; 
    private final LineBorder border1; 
    public JFrame frame; 
    checkerPiece piece = new checkerPiece(this); 
    Graphics g; 

public Checkers(){ 
    board = new JPanel[BOARDSQUARES][BOARDSQUARES]; 
    point1 = new Point (BOARDSIZE,BOARDSIZE); 
    border1=new LineBorder(Color.BLACK, 1); 

} 


/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 

    Checkers checkers = new Checkers(); 
    checkers.frame=checkers.createJFrame(); 

    checkers.board =checkers.createBoard(checkers.board, checkers.point1, checkers.border1); 

    for (int y=0;y<BOARDSQUARES;y++){ 
     for (int x = 0;x<BOARDSQUARES;x++){ 
     checkers.frame.getContentPane().add(checkers.board[y][x]); 

     } 

    } 

    checkers.paint(checkers.g); 
} 

private JPanel[][] createBoard (JPanel[][] board, Point point, LineBorder border1){ 
    for (int row = 0; row<BOARDSQUARES;row++){ 
     point.y=BOARDSIZE; 
     for (int col = 0; col <BOARDSQUARES;col++){ 

      board[row][col] = new JPanel(); 
      board[row][col].setLocation(point); 
      board[row][col].setVisible(true); 
      board[row][col].setSize(BOARDSIZE,BOARDSIZE); 
      board[row][col].setOpaque(true); 
      if ((row%2==0&&col%2==0)||(row%2==1&&col%2==1)){ 
       board[row][col].setBackground(new Color (230,200,150)); 
      } else if ((row%2==0&&col%2==1)||(row%2==1&&col%2==0)) { 

       board[row][col].setBackground(new Color (165, 42,42)); 
      } 
      board[row][col].setBorder(border1); 
          point.y = point.y+BOARDSIZE; 
     } 
     point.x=point.x+BOARDSIZE; 
    } 

    return board; 
} 

private JFrame createJFrame(){ 
    JFrame mainFrame = new JFrame("Checkers"); 
    mainFrame.setSize(1000,1000); 
    mainFrame.setVisible(true); 
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    mainFrame.add(new Checkers()); 
return mainFrame; 
} 
@Override 
public void paint (Graphics g){ 
    System.out.println("hi"); 
    super.paint(g); 
    Graphics2D g2d = (Graphics2D) g; 

    piece.paint(g2d,board[0][0].getLocation().x,board[0][0].getLocation().y,Color.BLACK); 

    } 
} 

Необходимый фрагмент из другого класса (cherkerPiece шт):

public void paint (Graphics2D g, int x, int y, Color color){ 
    g.setColor(color); 
    g.fillOval(x, y, DIAMETER, DIAMETER); 
} 

Спасибо за вашу помощь

+0

Вы видите сообщение «привет» в консоли? – ControlAltDel

+0

Вы покрыли свою доску JPanels. Не пытайтесь добавить их и посмотреть, сможете ли вы увидеть свои фигуры. – ControlAltDel

+2

«Swing-программы должны переопределять' paintComponent() 'вместо переопределения' paint() '." - [* Живопись в AWT и Swing: методы Paint *) (http: //www.oracle.com/technetwork/java/painting-140037.html#callbacks). – trashgod

ответ

0

Чтобы создать что-то, как комплекс, как шашки игры, вы должны следовать model/view/controller pattern при создании графического интерфейса Java Swing.

Checker Board GUI

Я создал класс модели для квадрата шахматной доски и другая модель класса для клетчатой ​​части. Я создал модельный класс для контрольной панели и еще один модельный класс, чтобы держать все элементы проверки.

Я создал класс представления, чтобы нарисовать контрольную панель. Я создал другой класс представления для создания главного окна.

Я не создал никаких классов контроллеров. Этот код просто показывает вам, как рисовать контрольную панель. Я собрал все классы, чтобы упростить вставку кода. Вы должны разделить классы на отдельные файлы Java.

package com.ggl.testing; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class CheckerBoard implements Runnable { 

    private Board board; 

    private CheckerBoardPanel checkerBoardPanel; 

    private JFrame frame; 

    private Pieces pieces; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new CheckerBoard()); 
    } 

    public CheckerBoard() { 
     this.board = new Board(); 
     this.pieces = new Pieces(); 
    } 

    @Override 
    public void run() { 
     frame = new JFrame("Checker Board"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     checkerBoardPanel = new CheckerBoardPanel(board, pieces); 
     frame.add(checkerBoardPanel); 

     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public class CheckerBoardPanel extends JPanel { 

     private static final long serialVersionUID = 3770663347384271771L; 

     private Board board; 

     private Pieces pieces; 

     public CheckerBoardPanel(Board board, Pieces pieces) { 
      this.board = board; 
      this.pieces = pieces; 
      this.setPreferredSize(board.getPreferredSize()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      Square[][] checkerBoard = board.getBoard(); 

      for (int row = 0; row < checkerBoard.length; row++) { 
       for (int column = 0; column < checkerBoard[row].length; column++) { 
        Square square = checkerBoard[row][column]; 
        Rectangle drawingRectangle = square.getDrawingRectangle(); 
        g.setColor(square.getColor()); 
        g.fillRect(drawingRectangle.x, drawingRectangle.y, 
          drawingRectangle.width, drawingRectangle.height); 
       } 
      } 

      List<Piece> checkerPieces = pieces.getPieces(); 

      for (Piece checkerPiece : checkerPieces) { 
       Point coordinate = checkerPiece.getCoordinate(); 
       Rectangle drawingRectangle = checkerBoard[coordinate.x][coordinate.y] 
         .getDrawingRectangle(); 

       int x = drawingRectangle.x + drawingRectangle.width/2; 
       int y = drawingRectangle.y + drawingRectangle.height/2; 
       int radius = board.getSquareWidth() * 2/6; 

       g.setColor(checkerPiece.getColor()); 
       g.fillOval(x - radius, y - radius, radius + radius, radius 
         + radius); 
      } 
     } 
    } 

    public class Board { 

     private static final int BOARD_WIDTH = 8; 
     private static final int SQUARE_WIDTH = 64; 

     private Square[][] board; 

     public Board() { 
      this.board = initalizeBoard(BOARD_WIDTH, SQUARE_WIDTH); 
     } 

     private Square[][] initalizeBoard(int boardWidth, int squareWidth) { 
      Square[][] board = new Square[boardWidth][boardWidth]; 

      int x = 0; 
      int y = 0; 

      for (int row = 0; row < boardWidth; row++) { 
       for (int column = 0; column < boardWidth; column++) { 
        Square square = new Square(); 
        if (isLightSquare(row, column)) { 
         square.setColor(Color.WHITE); 
        } else { 
         square.setColor(Color.LIGHT_GRAY); 
        } 

        square.setCoordinate(new Point(row, column)); 
        square.setDrawingRectangle(new Rectangle(x, y, squareWidth, 
          squareWidth)); 

        board[row][column] = square; 

        x += squareWidth; 
       } 
       x = 0; 
       y += squareWidth; 
      } 

      return board; 
     } 

     public boolean isLightSquare(int row, int column) { 
      if (row % 2 == 0) { 
       if (column % 2 == 0) { 
        return true; 
       } else { 
        return false; 
       } 
      } else { 
       if (column % 2 == 0) { 
        return false; 
       } else { 
        return true; 
       } 
      } 
     } 

     public Dimension getPreferredSize() { 
      int width = SQUARE_WIDTH * 8 + 1; 
      return new Dimension(width, width); 
     } 

     public Square[][] getBoard() { 
      return board; 
     } 

     public int getSquareWidth() { 
      return SQUARE_WIDTH; 
     } 

    } 

    public class Square { 

     private Color color; 

     private Point coordinate; 

     private Rectangle drawingRectangle; 

     public Point getCoordinate() { 
      return coordinate; 
     } 

     public void setCoordinate(Point coordinate) { 
      this.coordinate = coordinate; 
     } 

     public Rectangle getDrawingRectangle() { 
      return drawingRectangle; 
     } 

     public void setDrawingRectangle(Rectangle drawingRectangle) { 
      this.drawingRectangle = drawingRectangle; 
     } 

     public Color getColor() { 
      return color; 
     } 

     public void setColor(Color color) { 
      this.color = color; 
     } 

    } 

    public class Pieces { 

     private List<Piece> pieces; 

     public Pieces() { 
      this.pieces = addPieces(); 
     } 

     private List<Piece> addPieces() { 
      List<Piece> pieces = new ArrayList<Piece>(); 

      Piece piece = new Piece(); 
      piece.setColor(Color.RED); 
      piece.setCoordinate(new Point(2, 1)); 
      pieces.add(piece); 

      piece = new Piece(); 
      piece.setColor(Color.BLACK); 
      piece.setCoordinate(new Point(5, 0)); 
      pieces.add(piece); 

      // Add the rest of the red and black pieces here 

      return pieces; 
     } 

     public List<Piece> getPieces() { 
      return pieces; 
     } 

     public void addPiece(Piece piece) { 
      this.pieces.add(piece); 
     } 
    } 

    public class Piece { 

     private Color color; 

     private Point coordinate; 

     public Color getColor() { 
      return color; 
     } 

     public void setColor(Color color) { 
      this.color = color; 
     } 

     public Point getCoordinate() { 
      return coordinate; 
     } 

     public void setCoordinate(Point coordinate) { 
      this.coordinate = coordinate; 
     } 

    } 

} 
+0

Привет - спасибо за полезный ответ. У меня есть несколько вопросов, если вы не возражаете. – rosseg

+0

1. Почему вы можете сделать объект класса без аргументов, подобных этому: private Board board = new Board(); – rosseg

+0

2. В чем разница между использованием run и main? (У меня есть опыт работы с методом run) – rosseg

-1

вам нужно добавить класс, который расширяет Canvas и сделайте всю свою живопись в этом классе. как это

public class FirstWindow extends JFrame 
{ 
/** 
* 
*/ 
    private static final long serialVersionUID = 1L; 

public FirstWindow() 
{ 
    super("Kayte does not go to water parks"); 
    setSize(500, 500); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setResizable(false); 
} 
} 

public class Start extends Canvas implements Runnable 

public class Main 
{ 

public static void main(String arg[]) 
{ 
    FirstWindow fw = new FirstWindow(); 

    Start game = new Start(500, 500); 
    fw.add(game); 
    fw.setVisible(true); 
    new Thread(game).start(); 
} 

} 
+0

Не могли бы вы объяснить, что это за класс. Является ли FirstWindow основным классом? Что такое serialvetsion? – rosseg

+0

уверен, класс FristWindow устанавливает окно. затем я создал класс под названием start, в котором вся моя краска для этого окна завершена. не беспокойтесь о потоке и serialVersionUID. – ZergRushJoe

+0

В начале у меня есть мой пробег, тик и краска. Я использую цикл в run для вызова tick/update, логики игры и красок, рисует, что произошло. то в своем классе вы добавляете метод красок и меток для управления каждой частью. – ZergRushJoe

Смежные вопросы