2012-04-22 4 views
4

Я работаю над своим заданием, чтобы часть его потребовала, чтобы я поставил красный блок в макете сетки в JFrame. После этого пользователь должен иметь возможность изменять положение этого красного блока с помощью клавиш со стрелками.getContentPane(). Добавить не работает?

До сих пор я мог добавить красный блок в макет сетки. Проблема в том, что я не могу ее переместить.

Это моя Main.java. Он требует JFrame в Panel.java ниже:

import java.awt.GridLayout; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 


public class Main { 

public static void main(String[] args) { 

    Panel p = new Panel(); 

    p.setSize(870, 780); 
    p.setVisible(true); 
    p.setResizable(true); 
    p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

}//END main 

}//END Main 

Panel.java. И вот код с KeyListener для перемещения красного блока. Но это не работает.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 


public class Panel extends JFrame implements Runnable{ 

static final int GWIDTH = 200, 
        GHEIGHT = 200; 

static final Dimension gameDim = new Dimension(GWIDTH, GHEIGHT); 


Icon bg = new ImageIcon(getClass().getResource("empty.jpg")); 
Icon red = new ImageIcon(getClass().getResource("actor.jpg")); 
Icon blue = new ImageIcon(getClass().getResource("blue.jpg")); 

JLabel[] labels = new JLabel[48]; 

private int redPoint; 

//Player navigation 
private int i, j; 



public Panel() { 

    i = 1; 
    j = 1; 

    setPreferredSize(gameDim); 
    setFocusable(true); 
    requestFocus(); 
    setTitle("LabWork 10"); 
    setLayout(new GridLayout(6, 8, 10, 10)); 

    redPoint = (i*8)+j; 


    for(int i=0 ; i<48 ; i++) 
     labels[i] = new JLabel(bg); 


    labels[redPoint] = new JLabel(red); 


    for(int i=0 ; i<48 ; i++) 
     getContentPane().add(labels[i]); 


    addKeyListener(new KeyListener() { 

     @Override 
     public void keyTyped(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyPressed(KeyEvent e) { 

      if(e.getKeyCode() == KeyEvent.VK_LEFT) { 
       j--; 
       labels[redPoint] = new JLabel(bg); 
       getContentPane().add(labels[redPoint]); 
       redPoint = (i*8)+j; 
       labels[redPoint] = new JLabel(red); 
       getContentPane().add(labels[redPoint]); 
      } 

      if(e.getKeyCode() == KeyEvent.VK_RIGHT) { 
       j++; 
       labels[redPoint] = new JLabel(bg); 
       getContentPane().add(labels[redPoint]); 
       redPoint = (i*8)+j; 
       labels[redPoint] = new JLabel(red); 
       getContentPane().add(labels[redPoint]); 
      } 

      if(e.getKeyCode() == KeyEvent.VK_UP){ 
       i--; 
       labels[redPoint] = new JLabel(bg); 
       getContentPane().add(labels[redPoint]); 
       redPoint = (i*8)+j; 
       labels[redPoint] = new JLabel(red); 
       getContentPane().add(labels[redPoint]); 
      } 

      if(e.getKeyCode() == KeyEvent.VK_DOWN){ 
       i++; 
       labels[redPoint] = new JLabel(bg); 
       getContentPane().add(labels[redPoint]); 
       redPoint = (i*8)+j; 
       labels[redPoint] = new JLabel(red); 
       getContentPane().add(labels[redPoint]); 
      } 

     }//end keyPressed 

    });//end addKeyListener 

}//END panel 







@Override 
public void run() { 



} 

} 

В чем причина того, что код в KeyListener неспособен переместить красный блок?

Edit 1:

Вот код с работой движущихся плитки. Также с предотвращением выхода за пределы.

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 


public class Panel extends JFrame implements Runnable{ 

static final int GWIDTH = 200, 
        GHEIGHT = 200; 

static final Dimension gameDim = new Dimension(GWIDTH, GHEIGHT); 


Icon bg = new ImageIcon(getClass().getResource("empty.jpg")); 
Icon red = new ImageIcon(getClass().getResource("actor.jpg")); 
Icon blue = new ImageIcon(getClass().getResource("blue.jpg")); 

JLabel[] labels = new JLabel[48]; 

private int redPoint; 

//Player navigation 
private int i, j; 



public Panel() { 

    i = 1; 
    j = 1; 

    setSize(870, 780); 
    setVisible(true); 
    setResizable(true); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setPreferredSize(gameDim); 
    setFocusable(true); 
    requestFocus(); 
    setTitle("LabWork 10"); 
    setLayout(new GridLayout(6, 8, 10, 10)); 
    setFocusable(true); 
    requestFocusInWindow(); 

    redPoint = (i*8)+j; 


    for(int i=0 ; i<48 ; i++) 
     labels[i] = new JLabel(bg); 


    labels[redPoint] = new JLabel(red); 


    for(int i=0 ; i<48 ; i++) 
     getContentPane().add(labels[i]); 


    addKeyListener(new KeyListener() { 

     @Override 
     public void keyTyped(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyPressed(KeyEvent e) { 

      if (e.getKeyCode() == KeyEvent.VK_LEFT) 
       j--; 

      if (e.getKeyCode() == KeyEvent.VK_RIGHT) 
       j++; 

      if (e.getKeyCode() == KeyEvent.VK_UP) 
       i--; 

      if (e.getKeyCode() == KeyEvent.VK_DOWN) 
       i++; 

      run(); 

      //for preventing going out of bounds 
      int oldRedPoint = redPoint; 
      int old_i = i; 
      int old_j = j; 

      redPoint = (i * 8) + j; 

      if(redPoint > 47 || redPoint < 0) { 
       redPoint = oldRedPoint; 
       i = old_i; 
       j = old_j; 
      } 

      labels[oldRedPoint].setIcon(bg); 
      labels[redPoint].setIcon(red); 
     } 

    });//end addKeyListener 

}//END panel 



@Override 
public void run() { 

    try { 

    } catch (Exception e) { 
     // TODO: handle exception 
    } 

} 

} 
+1

Похоже, вы делаете все неправильно, вы инициализируете свой 'JLabel' снова и снова, так что предыдущей, который добавляется к' Content Pane' получает отброшен, и Бог знает, что происходит, слишком много инициализаций 'нового JLabel()' время от времени, просто измените фон упомянутого 'JLabel' вместо добавления новой' JLabel' к уже заложенной 'Grid' –

+1

'Панель расширяет JFrame' Кому нужен обфускатор, когда вы можете написать такой код? ;) –

ответ

5

Проблема с KeyListener, вероятно, является одной из задач, поскольку KeyListeners работают только для компонентов, имеющих фокус. Одно из решений заключается в том, чтобы вы прослушивали компонент, настраиваемый с помощью метода setFocusable (...), а затем после этого он запрашивалFocusInWindow().

Другим более элегантным решением является использование Key Bindings вместо KeyListener и привязка к соответствующей InputMap, которая соответствует JComponent.WHEN_IN_FOCUSED_WINDOW. Тогда вам не придется беспокоиться о проблемах фокуса.

Есть много отличных примеров того, как использовать ключевые привязки на этом сайте, которые вы можете искать, и некоторые не очень большие, которые были написаны мной.

Редактировать
Это не проблема фокусировки, я исправлюсь. Проанализировать далее ...

Edit 2
Я думаю, что ваша проблема в том, что вы пытаетесь добавить новые компоненты JLabel к ContentPane, когда вы не должны делать это. Вместо этого вы должны обменивать ImageIcons в существующих JLabels, так как это то, что вы хотите, - изображение для перемещения, а не JLabel.

Редактировать 3
Да, это все. Вам нужно упростить вещи. Например:

 @Override 
    public void keyPressed(KeyEvent e) { 
     int oldRedPoint = redPoint; 
     if (e.getKeyCode() == KeyEvent.VK_LEFT) { 
      j--; 
     } 

     if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 
      j++; 
     } 

     if (e.getKeyCode() == KeyEvent.VK_UP) { 
      i--; 
     } 

     if (e.getKeyCode() == KeyEvent.VK_DOWN) { 
      i++; 
     } 
     redPoint = (i * 8) + j; 
     labels[oldRedPoint].setIcon(bg); 
     labels[redPoint].setIcon(red); 
    } 

Хотя я должен заявить, что для записи я предпочитаю Key Bindings для прослушивания ключевых слов.

Edit 4
Кроме того, вы бы лучше поместить в код, чтобы предотвратить ваш редпоинт от опуститесь ниже 0 или выше labels.length.

Кроме того, если вы задали аналогичный вопрос, спасибо за публикацию соответствующего кода, но, пожалуйста, отправьте код, который не зависит от внешних ресурсов, таких как изображения.Мне пришлось создать свои собственные изображения для вашего кода для работы:

private Icon createIcon(Color color) { 
    BufferedImage img = new BufferedImage(IMG_W, IMG_H, 
     BufferedImage.TYPE_INT_ARGB); 
    Graphics g = img.getGraphics(); 
    g.setColor(color); 
    g.fillRect(0, 0, IMG_W, IMG_H); 
    g.dispose(); 
    return new ImageIcon(img); 
} 
+1

@ Вы можете увидеть, правильно ли вы получили ключевые события. Просто поставьте простой System.out.println() в начале каждого кода, который вам нужен, если он будет выполнен или нет. –

+0

Спасибо, оцените. :) Я пробовал это раньше, и это работает. Проблема, вероятно, связана с фокусировкой. –

+0

@Can: Нет, это не проблема. Я стою исправлено. –