2017-05-06 33 views
-1

我試圖讓國際象棋程序在那裏我有JPanels這都需要一個addMouseListener將但在這addMouseListener將我需要利用數組的索引,它的工作,像這樣的一個8x8的陣列:如何在JPanel數組的元素上使用addMouseListener而不將其添加到每個單個元素。

panels[0][0].addMouseListener(new MouseAdapter() { 

     public void mousePressed(MouseEvent e) { 
      panels[0][0].setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); 
     } 

     public void mouseReleased(MouseEvent e) { 

     } 
    }); 

由於我有64個JPanel,這意味着我需要複製這63次,可能的更改也需要複製。有沒有更好,更有效的方法來實現這一目標?

+1

1)*「自我有64個JPanels「*使用'JButton'組件代替面板,使用'ActionListener'而不是'MouseListener',以及一個工廠方法來將偵聽器添加到每個按鈕。 .2)另請參見[製作健壯的,可調整大小的Swing Chess GUI](http://stackoverflow.com/q/21142686/418556)。 –

回答

2

您應該使用一個循環是:

for (int r = 0; r < panels.length; ++r) { 
    for (int c = 0; c < panels[r].length; ++c) { 
     // Do this to fix the "must be final" error: 
     final int row = r; 
     final int col = c; 
     panels[row][col].addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       panels[row][col].setBorder(.....); 
      } 
      // ..... more 
     }); 
    } 
} 

然而,也有一些其他附加的方式去了解這一點。其中之一是,你可以寫一個class節省了面板的位置:

class MyMouseListener extends MouseAdapter { 
    int panelRow; 
    int panelCol; 

    MyMouseListener(int panelRow, int panelCol) { 
     this.panelRow = panelRow; 
     this.panelCol = panelCol; 
    } 
    //..... 
} 

這基本上就是使用匿名類的例子做幕後。您也可以保存對面板本身的引用。

或者你可以使用getSource()方法上MouseEvent

@Override 
public void mousePressed(MouseEvent e) { 
    JPanel panelWhichWasClicked = (JPanel) e.getSource(); 
    // ..... 
} 

在這種情況下,你只需要1個鼠標監聽器,您可以添加到每個面板。

+0

第一個不起作用,我知道,因爲我已經嘗試過。我得到的錯誤是變量'row'和'col'需要是最終的。 – tomishomo

+0

請參閱我的編輯以瞭解如何解決該問題。這只是我的一個疏忽。他們改變了Java 8的工作原理,出於某種原因,我認爲這不是必需的。 – Radiodef

3

因爲我有64個JPanels這意味着我需要複製這個63倍

你可以寫一個通用的聽衆

MouseListener ml = new MouseAdapter() 
{ 
    @Override 
    public void mousePressed(MouseEvent e) 
    { 
     JPanel panel = (JPanel)e.getSource(); 
     panel.setBorder(...); 
    } 
}; 

然後在你的循環代碼,你只是做:

panels[?][?].addMouseListener(ml); 

您應該始終嘗試編寫泛型監聽器,以便代碼可以重用。

+0

這看起來不錯,但我認爲它仍然行不通,因爲我直接需要代碼中的索引。我在mousePressed()方法中調用一個方法,該方法接受兩個整數,即行和列,它們是JPanel的索引。任何想法如何解決這個問題? – tomishomo

+0

我現在在mousePressed()方法內執行一個for循環,在該方法中,當我的面板數組元素等於(JPanel)e.getSource()時,然後傳遞行和列整數。它似乎在工作,但我想知道你是否可以強調這是否正確。 – tomishomo

+1

@borisverwoerd,'這看起來很棒 - - 爲什麼你不試試?你爲什麼認爲你需要行/列? – camickr

0

當你有一個數組時,你必須採取不同的方法。

第一類應該實現的MouseListener其中有5種抽象方法,但你可能感興趣的mouseClicked:

public class Example implements MouseListener{ 

@Override 
public void mouseClicked(MouseEvent e) { 
    JPanel panel = (JPanel) e.getSource(); // finding which panel is clicked on 
} 

@Override 
public void mousePressed(MouseEvent e) {} 
@Override 
public void mouseReleased(MouseEvent e) {} 
@Override 
public void mouseEntered(MouseEvent e) {} 
@Override 
public void mouseExited(MouseEvent e) {} 
} 

然後某處你的類裏面,你會做的事:

for(int i = 0; i < panels.length; i++){ 
    for(int j = 0; j < panels[0].length; j++){ 
     panels[0][0].addMouseListener(this); 
    } 
} 
相關問題