【Java用法】一个Java小程序玩法哦

简介: 【Java用法】一个Java小程序玩法哦

多进程与多线程的区别?本质的区别在于每个进程拥有自己的一整套变量,而线程则共享数据。共享变量使线程之间的通信比进程之间的通信更有效、更容易。

此外,在有些操作系统中,与进程相比较,线程更“轻量级”,创建、撤销一个线程比启动新进程的开销要小得多。

这里从察看一个没有使用多线程的程序开始。用户很难让它执行多个任务。在对其进行剖析之后,将展示让这个程序运行几个彼此独立的多个线程是很容易的。这个程序采用不断地移动位置的方式实现球跳动的动画效果, 如果发现球碰到墙壁, 将进行重绘(见下图所示 )。

当点击开始按钮时, 程序将从屏幕的左上角弹出一个球, 这个球便开始弹跳。开始按钮的处理程序将调用 addBall 方法。这个方法循环运行 1000 次 move。 每调用一次 move,球就会移动一点, 当碰到墙壁时, 球将调整方向,并重新绘制面板。

如果运行这个程序, 球就会自如地来回弹跳, 但是, 这个程序完全控制了整个应用程序。如果你在球完成 1000 次弹跳之前已经感到厌倦了,并点击 关闭 按钮会发现球仍然还在弹跳。在球自己结束弹跳之前无法与程序进行交互。

显然,这个程序的性能相当糟糕。人们肯定不愿意让程序用这种方式完成一个非常耗时的工作。 毕竟,当通过网络连接读取数据时, 阻塞其他任务是经常发生的, 有时确实想要中断读取操作。 例如,假设下载一幅大图片。当看到一部分图片后,决定不需要或不想再看剩余的部分了, 此时,肯定希望能够点击 Stop 按钮或 Back 按钮中断下载操作。下一节将介绍如何通过运行一个线程中的关键代码来保持用户对程序的控制权。

程序清单给出了这个程序的代码。可以直接使用的代码哦~~~

public class Bounce {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new BounceFrame1();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
/**
 * 拥有小球组件和按钮的框架
 */
class BounceFrame1 extends JFrame {
    private BallComponent component;
    public static final int STEPS = 1000;
    public static final int DELAY = 3;
    /**
     * Constructs the frame with the component for showing the bouncing ball and “开始” and “关闭” buttons
     */
    public BounceFrame1() {
        setTitle("Bounce");
        component = new BallComponent();
        add(component, BorderLayout.CENTER);
        JPanel buttonPanel = new JPanel();
        addButton(buttonPanel, "开始", event -> addBall());
        addButton(buttonPanel, "关闭", event -> System.exit(0));
        add(buttonPanel, BorderLayout.SOUTH);
        pack();
    }
    /**
     * 向容器中添加一个按钮
     *
     * @param c        容器
     * @param title    按钮标题
     * @param listener 按钮监听事件
     */
    public void addButton(Container c, String title, ActionListener listener) {
        JButton button = new JButton(title);
        c.add(button);
        button.addActionListener(listener);
    }
    public void addBall() {
        try {
            Ball ball = new Ball();
            component.add(ball);
            for (int i = 1; i <= STEPS; i++) {
                ball.move(component.getBounds());
                component.paint(component.getGraphics());
                Thread.sleep(DELAY);
            }
        } catch (Exception e) {
            System.out.println("出错啦~~~~");
        }
    }
}
/**
 * 画小球的组件
 */
class BallComponent extends JPanel {
    private static final int DEFAULT_WIDTH = 450;
    public static final int DEFAULT_HEIGHT = 350;
    List<Ball> balls = new ArrayList<>();
    /**
     * 向组件中添加小球
     *
     * @param ball 小球
     */
    public void add(Ball ball) {
        balls.add(ball);
    }
    @Override
    public void paintComponent(Graphics graphics) {
        // erase background
        super.paintComponent(graphics);
        Graphics2D g2 = (Graphics2D) graphics;
        for (Ball ball : balls) {
            g2.fill(ball.getShape());
        }
    }
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
}
/**
 * A ball that moves and bounces off the edges of a rectangle
 */
class Ball {
    public static final int XSIZE = 15;
    public static final int YSIZE = 15;
    private double x = 0;
    private double y = 0;
    private double dx = 1;
    private double dy = 1;
    /**
     * Moves the ball to the next position, reversing direction if it hits one of the edges
     *
     * @param bounds
     */
    public void move(Rectangle2D bounds) {
        x += dx;
        y += dy;
        if (x < bounds.getMinX()) {
            x = bounds.getMinX();
            dx = -dx;
        }
        if (x + XSIZE >= bounds.getMaxX()) {
            x = bounds.getMaxX() - XSIZE;
            dx = -dx;
        }
        if (y < bounds.getMinY()) {
            y = bounds.getMinY();
            dy = -dy;
        }
        if (y + YSIZE >= bounds.getMaxY()) {
            y = bounds.getMaxY() - YSIZE;
            dy = -dy;
        }
    }
    /**
     * Gets ths shape of the ball at its current position
     *
     * @return
     */
    public Ellipse2D getShape() {
        return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
    }
}

 

完结!


相关文章
|
4月前
|
Java
Java中的equals()与==的区别与用法
【7月更文挑战第28天】
67 12
|
7天前
|
小程序 前端开发 算法
|
15天前
|
存储 安全 Java
深入理解Java中的FutureTask:用法和原理
【10月更文挑战第28天】`FutureTask` 是 Java 中 `java.util.concurrent` 包下的一个类,实现了 `RunnableFuture` 接口,支持异步计算和结果获取。它可以作为 `Runnable` 被线程执行,同时通过 `Future` 接口获取计算结果。`FutureTask` 可以基于 `Callable` 或 `Runnable` 创建,常用于多线程环境中执行耗时任务,避免阻塞主线程。任务结果可通过 `get` 方法获取,支持阻塞和非阻塞方式。内部使用 AQS 实现同步机制,确保线程安全。
|
1月前
|
小程序 Java
小程序访问java后台失败解决方案
小程序访问java后台失败解决方案
42 2
|
1月前
|
小程序 JavaScript Java
小程序访问java后台
小程序访问java后台
26 1
|
2月前
|
Java
Java 正则表达式高级用法
Java 中的正则表达式是强大的文本处理工具,用于搜索、匹配、替换和分割字符串。`java.util.regex` 包提供了 `Pattern` 和 `Matcher` 类来高效处理正则表达式。本文介绍了高级用法,包括使用 `Pattern` 和 `Matcher` 进行匹配、断言(如正向和负向前瞻/后顾)、捕获组与命名组、替换操作、分割字符串、修饰符(如忽略大小写和多行模式)及 Unicode 支持。通过这些功能,可以高效地处理复杂文本数据。
|
2月前
|
存储 Java 数据处理
Java 数组的高级用法
在 Java 中,数组不仅可以存储同类型的数据,还支持多种高级用法,如多维数组(常用于矩阵)、动态创建数组、克隆数组、使用 `java.util.Arrays` 进行排序和搜索、与集合相互转换、增强 for 循环遍历、匿名数组传递以及利用 `Arrays.equals()` 比较数组内容。这些技巧能提升代码的灵活性和可读性,适用于更复杂的数据处理场景。
|
1月前
|
小程序
java--微信小程序发送模板消息
java--微信小程序发送模板消息
92 0
|
1月前
|
小程序 前端开发 Java
java 生成小程序二维码
java 生成小程序二维码
14 0
|
1月前
|
小程序 Java
小程序通过get请求提交数据到java后台
小程序通过get请求提交数据到java后台
28 0