![](/img/trans.png)
[英]How to perform a method of another class when I click the Accept Button of my Dialog which is located in another class?
[英]Somehow my GUI got stuck when I click on a button to perform a method call
我想通過點擊JButton來更新電路板配置。 但是,有時圖像會顯示在畫面上。 有時不是。 我點擊按鈕后每次都有明顯的延遲。 我試過調試,發現可能有一個無限循環:EventDispatchThread.class
(this is the class from java library)
void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
addEventFilter(filter);
doDispatch = true;
while (doDispatch && cond.evaluate()) {
if (isInterrupted() || !pumpOneEventForFilters(id)) {
doDispatch = false;
}
}
removeEventFilter(filter);
}
無限循環是上面的while循環。
以下是我的聽眾課程:
public class PlaceListener implements ActionListener{
private JTextField _text1;
private Board board;
private JTextField _text2;
private ArrayList<NewGUI> _guiList;
private int _numOfPlayer;
public PlaceListener(JTextField text1, JTextField text2, Board b,ArrayList<NewGUI> guiList, int numOfPlayer,NewGUI gui)
{
_text1 = text1;
_text2 = text2;
board = b;
_guiList = guiList;
_numOfPlayer = numOfPlayer;
}
@Override
public void actionPerformed(ActionEvent e) {
int x = Integer.parseInt(_text1.getText());
int y = Integer.parseInt(_text2.getText());
board.Place(y, x);
for(int j = 0;j<_numOfPlayer;j++)
{
NewGUI gui = _guiList.get(j);
gui.updateBoard();
gui.updateCurrTile();
gui.updateScore();
gui.updateTurn();
}
}
}
基本思想是:我有一個GUI數組。 每次單擊后,偵聽器將調用陣列中的所有GUI以更新其配置。
我還嘗試直接更新GUI類中的板配置,結果表明它運行良好。 我非常困惑! 誰能幫我嗎? 謝謝!!
這是主要的GUI類:
public class NewGUI {
private JFrame _frame;
private Board _board;
private JLabel _turnLabel;
private JTextArea _textArea;
private JLabel _currTileLabel;
private JPanel _boardPanel;
public NewGUI(Board board,int whos,ArrayList<NewGUI> guiList,int numOfPlayer)
{
_board = board;
_frame = new JFrame("Metro");
//turnLabel
_turnLabel = new JLabel();
_turnLabel.setText("Current player is: "+_board.getCurrPlayer());
_turnLabel.setSize(110, 40);
_turnLabel.setLocation(0, 0);
_frame.add(_turnLabel);
//mainPlayerLabel
JLabel mainPlayerLabel = new JLabel("Player"+whos+" 's window");
mainPlayerLabel.setSize(120, 20);
mainPlayerLabel.setLocation(400,0);
_frame.add(mainPlayerLabel);
//JTextArea to hold scores
_textArea = new JTextArea();
_textArea.setText(_board.displayScore());
_textArea.setSize(160,140);
_textArea.setLocation(730, 170);
_frame.add(_textArea);
_boardPanel = new JPanel();
_boardPanel.setSize(560, 560);
_boardPanel.setLocation(170, 80);
_boardPanel.setLayout(null);
// _boardPanel.setBackground(java.awt.Color.BLACK);
_frame.add(_boardPanel);
//Button Panel
JPanel buttonPanel = new JPanel();
buttonPanel.setSize(300, 150);
buttonPanel.setLocation(280, 650);
buttonPanel.setBackground(java.awt.Color.blue);
_frame.add(buttonPanel);
//Current Tile Label
_currTileLabel = new JLabel("Current Tile is: ");
_currTileLabel.setIcon(new ImageIcon(NewGUI.class.getResource(_board.getCurrTile().tileType()+".png")));
_currTileLabel.setSize(170, 60);
_currTileLabel.setLocation(20, 620);
_frame.add(_currTileLabel);
//2 input JTextField
JTextField text1 = new JTextField(3);
JTextField text2 = new JTextField(3);
text1.setSize(20, 20);
text2.setSize(20, 20);
text1.setLocation(620, 680);
text2.setLocation(640, 680);
_frame.add(text1);
_frame.add(text2);
//Buttons
JButton buttonPlace = new JButton("Place");
JButton buttonCommit = new JButton("Commit");
JButton buttonRemove = new JButton("Remove");
JButton buttonResign = new JButton("Resign");
buttonPlace.addActionListener(new PlaceListener(text1,text2,_board,guiList,numOfPlayer,this));
buttonCommit.addActionListener(new CommitListener(_board,guiList,numOfPlayer));
buttonRemove.addActionListener(new RemoveListener(_board,guiList,numOfPlayer,this));
buttonResign.addActionListener(new ResignListener(_board));
//Add buttons onto buttonPanel
buttonPanel.add(buttonCommit);
buttonPanel.add(buttonResign);
buttonPanel.add(buttonRemove);
buttonPanel.add(buttonPlace);
buttonPanel.setLayout(new FlowLayout());
_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
_frame.setSize(900, 900);
_frame.setLayout(null);
_frame.setVisible(true);
}
public void updateBoard()
{
_boardPanel.removeAll();
//scan and refresh the board configuration.
for(int i = 1; i<13;i++)
{
for(int j = 1; j<13;j++)
{
if(_board.getBoard()[i][j]!=null)
{
for(int e = 65; e<89;e++){
char temp = (char)e;
if(_board.getBoard()[i][j].tileType()==temp)
{
JLabel label = new JLabel(new ImageIcon(NewGUI.class.getResource(temp+".png")));
label.setSize(40,40);
label.setLocation(40+(i-1)*40, 40+(j-1)*40);
_boardPanel.add(label);
break;
}
}
}
}
}
}
public void updateTurn()
{
_turnLabel.setText("Current player is: "+_board.getCurrPlayer());
}
public void updateScore()
{
_textArea.setText(_board.displayScore());
}
public void updateCurrTile()
{
_currTileLabel.setIcon(new ImageIcon(NewGUI.class.getResource(_board.getCurrTile().tileType()+".png")));
}
public static void main(String[] args)
{
Board b = new Board(3,true);
NewGUI gui = new NewGUI(b,1);
b.Place(4, 4);
b.Commit();
b.Place(12, 12);
b.Commit();
b.Place(3, 3);
gui.updateBoard();
}
}
看到最后一個靜態主類? 當我測試它時,所有的更新方法都運行良好! 但是當我使用監聽器來執行所有方法時。 updateBoard拒絕工作。
所以看起來你的代碼可能就是這里的問題。 同樣,EventDispatchThread使用無限循環來處理事件,這很明顯,並且可以忽略為實際問題。 你的問題來自於使用removeAll(),每次點擊按鈕時實例化幾千個標簽(什么是13 x 13 x 89-65?4056!)。 這將導致大量重繪和不必要的重新布局。 所以你看到的暫停是代碼的性能,因為它效率不高。 不要相信嘗試這個:
public void updateBoard() {
long start = System.currentTimeInMillis();
// existing code goes here
long duration = System.currentTimeMillis() - start;
System.out.printf("UpdateBoard timing: %,d ms%n", duration );
}
如果您的代碼超過10-100毫秒,那將會感到毛病。 實際上,100ms是緩慢的,人類可以檢測到100ms的延遲。
您可能需要重新評估您的設計,並重用現有標簽並簡單地調用setImage()來更改它們。 畢竟,使用持久性UI組件模型而不是使用原始繪制調用的重點。 實例化它們一次並重用。
您也可以使用新的ImageIcon()調用創建數千個圖像。 您可能只需要一個圖標,只需將所有標簽指向同一圖像,這將大大減少您的內存使用量。 事實上,如果你遵循我的建議,我認為你會看到顯着的速度和內存改進。
如果找不到合適的方法來重用JLabel,那么考慮通過繼承JComponent或JPanel(如果您打算使用容器)並覆蓋paintComponent()來編寫自己的組件。 我看到你沒有使用LayoutManager而是選擇使用絕對定位來做所有事情。 如果你要做絕對定位,你可能想要自己畫畫。 繪畫是更低級別的界面,但你有完全的控制。 你必須自己處理定位,自動換行。 但是,它將非常高效,您可以從數據模型重繪。
由於您所做的一切都是以網格模式繪制圖像,我認為使用Java2D api繪制圖像比實例化許多JLabel和ImageIcons更好。 如果你是JPanel的子類,你可以在面板中添加JComponents來獲取得分等等。但是,在paintComponent()方法中繪制網格。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.