источник мышиного адаптера Java не найден - PullRequest
0 голосов
/ 31 января 2010

У меня есть массив JPanel с, и я пытаюсь добавить мышиный адаптер к каждому из них, чтобы можно было определить, какой из них был нажат, а затем изменить его цвет фона. Кажется, все работает нормально, кроме случаев, когда я запускаю его из eclipse, когда появляется страница, на которой написано EventDispatchThread.run() строка: недоступно, источник не найден, а в окне отладки написано:

  Thread [AWT-Shutdown] (Running) 
  Daemon Thread [AWT-Windows] (Running) 
  Thread [AWT-EventQueue-0] (Suspended (exception ArrayIndexOutOfBoundsException)) 
   EventDispatchThread.run() line: not available 
  Thread [DestroyJavaVM] (Running) 
  Thread [AWT-EventQueue-0] (Running) 

Это код:

private void drawBoard() {
  LayoutManager layout = new GridLayout(NUMBER_OF_ROWS, NUMBER_OF_COLS);
  boardPanel.setLayout(layout);
  boardPanel.setPreferredSize(new Dimension(200, 400));
  chessBoard = new JPanel[NUMBER_OF_ROWS][NUMBER_OF_COLS];
  MoveArrays move = new MoveArrays();
  move.initialisePieceMoves();
  for (int i = 0; i < NUMBER_OF_ROWS; i++) {
   for (int j = 0; j < NUMBER_OF_COLS; j++) {
    int index = i * 4 + j;
    chessBoard[i][j] = new JPanel();
    chessBoard[i][j].addMouseListener(clickSquare(j, i, index, move));
    chessBoard[i][j].setBackground(getColor(i,j));
    if (!(boardArray.chessBoard[index].square.isEmpty())) {
     Piece piece = (Piece) boardArray.chessBoard[index].square.firstElement();
     JLabel pieceString = new JLabel(piece.toString()); 
     chessBoard[i][j].add(pieceString);
    }
    boardPanel.add(chessBoard[i][j]);
   }
  }
 } // drawBoard()

 private MouseAdapter clickSquare(final int xCo, final int yCo, final int index, final MoveArrays move) {
  return new MouseAdapter() {
   public void mousePressed(MouseEvent me) {
    resetColors();
    JPanel selectedSquare = (JPanel) me.getSource();
    selectedSquare.setBackground(selectedColor());
    System.out.println("xCo: " + xCo + " yCo: " + yCo);
    Vector validMoves = move.DroneMovesNorth[index].Moves;
    int totalMoves = move.DroneTotalMovesNorth[index];
    if (!validMoves.isEmpty()) {
     for (int n = 0; n <= totalMoves; n++) {
      String stringMove = validMoves.elementAt(n).toString();
      int intMove = Integer.parseInt(stringMove);
      System.out.println("intMove: " + intMove);
     }
    }
   }
  };
 }

Я думаю, это может быть тот факт, что я преобразовал me.getSource в JPanel, но не должен ли он быть в любом случае? Если я не ставлю приведение, он говорит, что не может связать «Объект» с JPanel, когда я выполняю System.out.print(me.getSource()), он печатает строку, говорящую, что это JPanel, поэтому я не понимаю, в чем проблема является. Любая помощь будет высоко ценится!

1 Ответ

4 голосов
/ 31 января 2010

Похоже, проблема не в источнике события мыши. На самом деле, я думаю, что здесь есть две разные вещи, называемые «источником», и вы смешиваете их вместе. Я думаю, что сообщение:

EventDispatchThread.run() line: not available, Source not found

Eclipse сообщает вам, что к библиотеке не присоединен исходный код code , поэтому она не может найти номера строк или показать вам исходный код. Проблема, похоже, не с me.getSource().

Проблема в том, что вы пытаетесь сослаться на индекс внутри массива, который находится за пределами массива (отсюда ArrayIndexOutOfBoundsException в трассировке стека).

Поскольку трассировка стека находится в потоке очереди событий AWT, вероятно, исключение происходит из-за метода mousePressed() вашего MouseAdapter. Поскольку вы уже используете Eclipse, я предлагаю вам познакомиться с отладчиком, который чрезвычайно полезен. Поместите точку останова в эти строки:

Vector validMoves = move.DroneMovesNorth[index].Moves;
int totalMoves = move.DroneTotalMovesNorth[index];

И убедитесь, что оба поля массива move достаточно велики, чтобы ссылаться на элемент в индексе. Если вы не хотите использовать отладчик (я бы действительно рекомендовал именно так), то вы можете заключить эти две строки в ловушку исключения, например:

try {
    Vector validMoves = move.DroneMovesNorth[index].Moves;
    int totalMoves = move.DroneTotalMovesNorth[index];
catch(ArrayIndexOutOfBoundsException e) {
    System.out.println("Exception thrown: index = " + index + 
        "Array lengths: " + move.DroneMovesNorth.length + ", " +
        move.DroneTotalMovesNorth.length);
}

Когда / если исключение обнаружено, вы хотите выяснить , почему индекс больше, чем размер каждого из этих массивов. Это оставлено как упражнение; -)


Редактировать: там есть какой-то другой код, который выглядит подозрительно.

Сначала вы объявляете массив для шахматной доски:

chessBoard = new JPanel[NUMBER_OF_ROWS][NUMBER_OF_COLS];

Затем вы начинаете итерацию для каждого квадрата на доске:

for (int i = 0; i < NUMBER_OF_ROWS; i++) {
   for (int j = 0; j < NUMBER_OF_COLS; j++) {

Обратите внимание, что i будет достигать значения NUMBER_OF_ROWS, которое является длиной массива шахматной доски. Тогда по какой-то причине я не понимаю, вы меняете значение index на то, что может быть в 4 раза больше длины массива:

int index = i * 4 + j;

А позже попробуйте указать эту позицию в массиве шахматной доски:

if (!(boardArray.chessBoard[index].square.isEmpty())) {

Это означает, что index может иметь значение выше NUMBER_OF_ROWS, и если вы попытаетесь получить доступ к элементу с этим индексом массива, он выдаст ArrayIndexOutOfBoundsException.

Итак, мое второе предложение было бы еще раз взглянуть на логику, используемую в:

int index = i * 4 + j;

... так как это тоже может быть проблемой.

P.S. отладчик в Eclipse потрясающий, вы должны его использовать; -)

...