gpt4 book ai didi

java - GUI 更新可以在 IDE 中工作,但并不总是从 jar 文件中进行

转载 作者:行者123 更新时间:2023-12-01 13:47:09 25 4
gpt4 key购买 nike

我在运行 OSX 10.7.5 的 Mac 上使用 Eclipse IDE 进行开发。该程序构造了一个 JPanel 数组,当用户单击一个面板时,同一行或同一列上的所有其他面板都会改变颜色,鼠标左键为蓝色,右键为红色。当我从 IDE 运行时,一切正常,至少我从未见过它失败。但是,当我创建一个 .jar 文件并通过双击该文件运行时,大多数时候它工作正常,但偶尔它不会改变其他一些面板的颜色。

为了测试,我选择一个方 block ,然后右键单击和左键单击它。正如我所说,大多数时候它都能工作,同一行或同一列中的所有其他面板都会改变颜色。但是,如果我右键单击一个正方形并且某些面板保持蓝色,那就是失败。如果我再次右键单击同一个方 block ,它不会改变显示;失败的面板保持蓝色。就好像经理认为一切都是正确的颜色并且懒得更新显示。

如果我调整面板大小或使用任一按钮单击任何其他方 block ,所有面板都会翻转为正确的颜色。这段代码没有显式调用 repaint() 但我已经尝试过,但它没有解决问题。我尝试阅读有关重绘管理器的内容,但尚未找到使显示可靠更新的方法。正如我所说,在运行 IDE 时我从未见过这种情况发生,而且大多数时候它也作为应用程序运行。刚才大概点击了50次就失败了。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GUITest extends JPanel {

final static int NROWS = 81;
final static int TOTAL_SQ = NROWS * NROWS;
Square[] square = new Square[TOTAL_SQ];

public GUITest() {
setLayout(new GridLayout(NROWS, NROWS));
for (int i = 0; i < TOTAL_SQ; i++) {
square[i] = new Square(i);
add(square[i]);
}

}

public void squareClicked(int id, int button) {
// determine which row and column
int row = id / NROWS;
int col = id % NROWS;
// change background color of all squares on same row or column
for (int i = 0; i < TOTAL_SQ; i++) {
if ((row == i / NROWS) || (col == i % NROWS))
if (button == MouseEvent.BUTTON3)
square[i].setBackground(Color.RED);
else
square[i].setBackground(Color.BLUE);
}
} // squareClicked

class Square extends JPanel implements MouseListener {
int id = 0; // which square this is

public Square(int id) {
this.id = id;
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseListener(this);
} // Square constructor

public void mouseClicked(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {
}

public void mouseReleased(MouseEvent e) {
squareClicked(id, e.getButton());
}
} // Square

public static void main(String[] args) {
JFrame frame = new JFrame("GUI Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

GUITest app = new GUITest();
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(app, BorderLayout.CENTER);
frame.setVisible(true);
}
}

我有第二个问题可能相关。 IDE 显示速度比应用程序快得多。 IDE 更新很快。该应用程序单独更新每个面板,速度明显较慢。我猜想 IDE 使用的是双缓冲显示。我也读到了这一点,但不知道如何让它推迟更新,直到整个显示器准备好。

提前致谢。

最佳答案

我没有发现您的逻辑有任何问题,并且当我在 Windows 7 上使用 JDK7 从命令行运行代码时,我无法重复您的问题。

但是,当我运行代码时,框架加载时确实出现异常:

C:\Java>java GUITest
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(Unknown Source)
at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(Unknown Source)
at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(Unknown Source)

我尝试的第一件事是确保所有代码都在 EDT 上执行:

EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new JFrame("GUI Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

GUITest app = new GUITest();
frame.getContentPane().add(app, BorderLayout.CENTER);
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});

我仍然遇到异常。因此,我尝试更改代码以减少单个面板上显示的组件数量:

setLayout( new GridLayout(NROWS,1) );
int squares = 0;

for (int i = 0; i < NROWS; i++)
{
JPanel panel = new JPanel( new GridLayout(1, NROWS) );

for (int j = 0; j < NROWS; j++)
{
square[squares] = new Square(squares);
panel.add( square[squares] );
squares++;
}

add( panel );
}

我不再遇到异常。不知道这是否有帮助。

此外,Swing 默认情况下是双缓冲的,因此我不确定为什么每个组件都要单独更新。 Swing 应该合并各个组件的重绘请求,以便一次性完成这些请求,但可能只重绘一组组件。

解决这个问题的唯一方法是不使用组件,而是创建自己的组件来对每个矩形进行自定义绘制。当然,这会更加复杂,因为您还需要进行自己的“点击检测”来确定单击了哪个矩形。

关于java - GUI 更新可以在 IDE 中工作,但并不总是从 jar 文件中进行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20277930/

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