我在这个论坛上发现了类似的问题,但它们并不是我的问题。我有一个带有绝对布局的JPanel,在该面板上,我有两个JButton。一个被称为 swapButton ,它在同一个面板上交换两个按钮的位置,另一个是 openButton ,这会打开一个图像,对该图像进行一些处理,并使用一些按钮相同的面板,然后调用 swapButton.doClick()。
openButton执行的操作代码:
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {
FileDialog filedialog = new FileDialog(GameFrame.this,"Open File",FileDialog.LOAD);
filedialog.setVisible(true);
try{
if(filedialog.getFile() != null){
filename = filedialog.getDirectory() + filedialog.getFile();
file = new File(filename);
File deleteFile = new File(defaultPath.toString());
deleteFile.delete();
Files.copy(file.toPath(),defaultPath);
file = new File(defaultPath.toString());
imageSelected = true;
newGame = true;
cropImage();
setImage();
}
}
catch(IOException e){}
if(imageSelected){
setCombination();
swapButton.doClick();
moves = 0;
msgLabel.setText("");
}
}
swapButton执行的操作代码:
private void swapButtonActionPerformed(java.awt.event.ActionEvent evt) {
int n = Integer.valueOf(numText.getText()); //gets value from a text area
swapButton(n);
}
swapButton方法的代码:
void swapButton(int i)
{
javax.swing.JButton button1 = buttonList[i], button2 = emptyButton;
int x1 = button1.getX(), y1 = button1.getY();
int x2 = button2.getX(), y2 = button2.getY();
button1.setLocation(x2, y2);
button2.setLocation(x1, y1);
int p1 = pos[i], p2 = pos[8];
pos[i] = p2;
pos[8] = p1;
arr[p1] = 8;
arr[p2] = i;
moves++;
}
我将swapButton执行的操作编码为一个单独的方法。
问题是,当我点击 openButton 时,该按钮的所有操作都能正常工作,并且还会调用 swapButton.doClick(),但按钮的位置在我的JPanel中保持不变,而不是在 swapButton()方法中调用 setLocation()方法。但是当我点击 swapButton 时, swapButton()方法中的所有操作都可以正常工作。我也尝试从代码的其他区域调用 swapButton.doClick(),它工作正常。
我使用 getLocation()方法在 swapButton()方法中调用 setLocation()方法后打印按钮的位置,它显示这些按钮的新位置,但我的JFrame中这些按钮的位置没有变化。我也尝试使用 setBounds()和 getBounds()方法并得到相同的结果。
这是一些错误吗?或者我做错了什么?
答案 0 :(得分:1)
首先,绝对布局表示没有布局管理器或null布局管理器。这绝对是不推荐。对于那里的任何初级或中级Swing程序员,你基本上不应该使用绝对布局。如果我这样做,我可能会创建自己的java.awt.LayoutManager接口的自定义实现,并为该实现提供swap()方法。这将保留所有位置交换的东西封装在我的自定义布局管理器中。但那不是你提出的问题。
如果没有更多详细信息,很难回答您的问题,但是您是否有理由需要调用swapButton的doClick()方法?如果用户看到按钮似乎被按在屏幕上是很重要的话,你会打电话给它。 [doClick()默认的屏幕推送长度是68毫秒,顺便说一句,在此期间EDT *将被冻结。]如果你只关心调用swapButton的ActionListener方法,那么直接调用该方法可能会更好。这样, openButton 的东西不依赖于 swapButton 的监听器何时被注册等等。
如果用swapButtonActionPerformed()替换swapButton.doClick()会更好吗?
要注意的是,您正在事件发送线程(EDT)上进行所有这些位置交换。根据您的说明,没有迹象表明您在EDT上不,但我们无法在不看其余代码的情况下确定。因此,SSCCE的用处。
*脚注:除非你没有从EDT调用它,这是它自己的问题