java - shape.intersects 函数 - 行为

标签 java

我有这个代码:

public class Intersect extends JFrame {
private boolean collision = false;

public Intersect() {
    add(new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
            Shape oval = new Ellipse2D.Double(50, 50, 200, 200);
            Shape rect = new Rectangle2D.Double(200, 200, 200, 200);
            Graphics2D g2 = (Graphics2D) g;
            g2.draw(oval);
            g2.draw(rect);
            if(oval.intersects(rect.getBounds())) {
                System.out.println("contact");
                collision = true;
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    });
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
}

public static void main(String[] args) {
    Intersect i = new Intersect();
    i.setVisible(true);
    if(i.collision == true)
        System.out.println("boom");
    else System.out.println("no boom");
}

} 控制台结果:” 没有繁荣 接触 接触 接触” 程序一直在变量碰撞中保留假值,但是如果不将变量碰撞更改为真,为什么它会打印“接触”? (条件 if(oval.intersects(rect.getBounds())))

最佳答案

绘制是异步发生的,以响应操作系统绘制窗口的请求。当您调用 setVisible(true); 时,它不会立即发生。

所以它确实collision变量设置为true。只是在 main 中的代码运行时,它还没有发生。这就是为什么在“nooom”之后打印“contact”的原因。

编辑:我建议修复它的方法是将碰撞逻辑与绘画代码分开。例如,将形状声明为框架上的字段,以便它们在绘制方法之外可用:

class Intersect extends JFrame {
    private Shape oval = new Ellipse2D.Double(50, 50, 200, 200);
    private Shape rect = new Rectangle2D.Double(200, 200, 200, 200);

面板的绘制方法变得简单:

@Override
protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.draw(oval);
    g2.draw(rect);
}

然后删除碰撞变量并将其设为一个方法,以便您可以随时调用它:

boolean collision() {
    return oval.intersects(rect.getBounds());
}

public static void main(String[] args) {
    Intersect i = new Intersect();
    i.setVisible(true);
    if (i.collision())
        System.out.println("boom");
    else System.out.println("no boom");
}

注意:此代码还有另一个(潜在的)问题。所有与 GUI 相关的 Activity 都应该发生在专用线程(事件调度线程)上。 The main method should switch to the event dispatch thread before creating the GUI.为此,请将 main 的开头更改为:

public static void main(final String[] args) {
    if (!SwingUtilities.isEventDispatchThread()) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                main(args);
            }
        });
        return;
    }

    Intersect i = new Intersect();
    ...

这将重新调用 GUI 线程上的 main。

关于java - shape.intersects 函数 - 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20292258/

相关文章:

java - 如何全局设置我的 JEE REST 客户端 header ?

Java 优先级队列

java - 简单的文件删除代码在 Java 中不起作用

java - 改进java模式匹配函数以不同的顺序打印,可能的链表操作

java - docx4j打开odt文件

java - xsd:soapUI 中包含异常:org.apache.xmlbeans.XmlException:org.apache.xmlbeans.XmlException:错误:null 后出现意外的文件结尾

java - 检查类是否被 CDI 1.2 代理

java - 将 Guice 与自定义类一起使用?

java - 关于 Java 中的 clone() 、对象类和 Cloneable 接口(interface)的混淆

java - 无法在数据库中保存 clob 数据类型(Struts、Spring、Hibernate)