只要花两个小时调试这一点,我想我知道了问题的原因,但我不明白它如何能产生一种它的结果。
我有一个基于Swing应用程序,我重写JPanel.paint(图形G)这样的
public void paint(Graphics g) {
<snipped code>
Insets is = getInsets();
Dimension sz = getSize();
g2.setClip(is.left + 1, is.top + 1, sz.width - is.right - is.left - 2, sz.height - is.top - is.bottom - 2);
int w = getWidth();
int h = getHeight();
double s = Math.min(sz.getWidth(), sz.getHeight());
AffineTransform mc = g2.getTransform();
AffineTransform m1 = new AffineTransform(mc);
m1.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
m1.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
m1.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));
AffineTransform m2 = new AffineTransform(mc);
m2.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
m2.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
m2.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));
try {
m_InverseViewTransform = m1.createInverse();
} catch (NoninvertibleTransformException e) {
AffineTransform m3 = new AffineTransform(mc);
m3.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
m3.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
m3.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));
System.out.println("m1 = " + m1);
System.out.println("m2 = " + m2);
System.out.println("m3 = " + m3);
AffineTransform m4 = new AffineTransform(mc);
System.out.println("m4 = " + m4);
m4.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
System.out.println("m4 = " + m4);
m4.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
System.out.println("m4 = " + m4);
m4.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));
System.out.println("m4 = " + m4);
System.out.println(w);
System.out.println(h);
System.out.println(s);
System.out.println(m_CenterX);
System.out.println(m_CenterY);
System.out.println(m_ScaleX);
System.out.println(m_ScaleY);
e.printStackTrace();
现在,神秘,有时当我启动应用程序,往往不是,说三次出来的四,NoninvertibleTransformException被抛出。
正如你所看到调试I输出违规矩阵和其他三个相同的计算矩阵和用于形成这些矩阵的变量。
而这正是它有趣的,看到下面的输出,所有矩阵中不具有相同的价值!
m1 = AffineTransform[[0.0, 0.0, 400.0], [0.0, -0.0, 289.0]]
m2 = AffineTransform[[0.0, 0.0, 400.0], [0.0, -0.0, 289.0]]
m3 = AffineTransform[[0.0, 0.0, 400.0], [0.0, -0.0, 289.0]]
m4 = AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
m4 = AffineTransform[[1.0, 0.0, -49.5], [0.0, 1.0, -0.362762953421903]]
m4 = AffineTransform[[5.254545454545455, 0.0, -260.1], [0.0, -587.9922126928986, 213.3017916655554]]
m4 = AffineTransform[[5.254545454545455, 0.0, 139.89999999999998], [0.0, -587.9922126928986, 502.3017916655554]]
800
578
578.0
49.5
0.36276295342190257
0.009090909090909092
1.0172875652126274
java.awt.geom.NoninvertibleTransformException: Determinant is 0
at java.awt.geom.AffineTransform.createInverse(AffineTransform.java:2706)
更有趣的东西,如果我适合移动调试输出/计算各地深入挖掘这个问题消失。
这种情况仅与jdk1.8.0_25.jdk JRE(在Mac OS X 10.8.5),不与Java 1.6或1.6。
好吧,我认为真正的罪魁祸首是JPanel的不是在事件分派线程创建的,一旦我这样做的例外是不会抛出没有任何不一致。
所以很显然是一个线程相关的时间依赖的问题,但我很好奇,怎么能这样呢,在Java的JVM“规则”所涉及的所有变量是本地的方法,并从该的AffineTransform矩阵方法不应该有副作用这么样很难让人理解线程的问题是如何导致这样的事情...
对于我的一片心意,我想明白是怎么回事。
作为一个副作用这个问题,可以帮助一些可怜的灵魂类似问题挣扎。
此外,如果有人设法针点那么明显缺陷的代码/调试/扣减我一直在这些线路现在盯着小时,我不介意。