gpt4 book ai didi

java - 当我单击按钮执行方法调用时,我的 GUI 以某种方式卡住了

转载 作者:行者123 更新时间:2023-11-29 06:00:23 24 4
gpt4 key购买 nike

我想通过单击 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 毫秒,就会让人感觉有问题。事实上,100 毫秒是慢的一面,人类可以检测到 100 毫秒的延迟。

您可能需要重新评估您的设计,或者重用现有标签并简单地调用 setImage() 来更改它们。毕竟,这就是使用持久 UI 组件模型而不是使用原始绘制调用的全部意义所在。将它们实例化一次并重复使用。

您还使用新的 ImageIcon() 调用创建了数以千计的图像。您可能只需要一个图标,并且让所有标签都指向同一张图像,这也将大大减少您的内存使用量。事实上,如果您听从我的建议,我认为您会看到显着的速度和内存改进。

如果找不到重用 JLabel 的合适方法,请考虑通过子类化 JComponent 或 JPanel(如果您计划使用容器)并覆盖 paintComponent() 来编写自己的组件。我看到您没有使用 LayoutManager,而是选择使用绝对定位来完成所有操作。如果你打算做绝对定位,你可能只想自己画。绘画是更底层的界面,但你有完全的控制权。您必须自己处理定位、自动换行。但是,它会非常高效,您可以从数据模型中重绘。

由于您所做的只是以网格模式绘制图像,我认为使用 Java2D api 绘制图像比实例化那么多 JLabel 和 ImageIcon 更好。如果您对 JPanel 进行子类化,则可以将 JComponents 添加到面板以用于得分等。但是,在 paintComponent() 方法中绘制网格。

关于java - 当我单击按钮执行方法调用时,我的 GUI 以某种方式卡住了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10375774/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com