亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使 JLabel 上的 ImageIcon 更新更快,延遲更少

如何使 JLabel 上的 ImageIcon 更新更快,延遲更少

千萬里不及你 2022-07-20 17:04:24
我正在嘗試更新位于 JLayeredPane 上的 JLabel 上的 ImageIcon,但是在設置線程將正確狀態發送到 JLabel 對象和 GUI 顯示正確狀態的 ImageIcon 之間存在很多延遲。以下代碼是該問題的示例,請查看按鈕的打印打開/關閉與顯示的圖標變亮/變暗之間的時間差異。設置線程:new Thread(new Runnable() { // setting thread        @Override        public void run() {            // TODO Auto-generated method stub            try {                while(true) {                    System.out.println("testButton on"); // print that the button is on                    testButton.updateState(1); // set button state to on                    Thread.sleep(70 + random.nextInt(500)); //sleep between 70 and 570 milliseconds                    System.out.println("testButton off");// print that the button is off                    testButton.updateState(0); // set button state to off                    Thread.sleep(70 + random.nextInt(500)); // sleep between 70 and 570 milliseconds                }            } catch(Exception e) {                e.printStackTrace();            }        }    }).start();按鈕對象:class Button extends JLabel {ImageIcon released;ImageIcon pressed;String text;public Button(int x, int y, String text) {    released = new ImageIcon("src/components/images/button.png");    pressed = new ImageIcon("src/components/images/buttonDown.png");    setBounds(x,y, 100, 100);    this.text = text;    setIcon(released);}public void updateState(int data) {    if (data == 1) {        setIcon(pressed);    }    else {        setIcon(released);    }}}ImageIcons 只有 325 字節,那么可能導致延遲的原因是什么?我查閱了 Event Dispatcher Thread,許多人說繪制圖像應該是即時的。最終目標:屏幕上有許多按鈕對象,設置線程根據隨機發生的動作調用它們進行更新。特定按鈕對象的顯示圖標應立即更改,因為它在函數中設置。設置線程不會一直循環,而是為每個發送的動作循環一次(這里是兩次只是為了顯示問題)。任何建議或嘗試的事情我都會盡快測試。編輯:最后,獲取信息的線程將調用 Linux 中的設備驅動程序,在那里它將等待響應,只有當它得到響應時才需要更新窗口。據我所知,計時器用于定期更新某些內容,但我可能錯了。
查看完整描述

1 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

正如在The Event Dispatch Thread上運行長進程的評論中所解釋的那樣,它會阻塞它,因此它不會響應更改。
此外,您不應該從其他(不是 EDT)線程更新 Swing 組件。
您需要使用 Swing 工具,例如SwingWorkerTimer。下面的mcve演示了一個使用 Timer 的簡單幻燈片:

import java.awt.BorderLayout;

import java.io.IOException;

import java.net.URL;

import java.util.Random;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.SwingConstants;

import javax.swing.Timer;


public class ChangeButtonIcon extends JPanel{


    private final URL[] urls = {

            new URL("https://findicons.com/files/icons/345/summer/128/cake.png"),

            new URL("http://icons.iconarchive.com/icons/atyourservice/service-categories/128/Sweets-icon.png"),

            new URL("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS_FkBgG3_ux0kCbfG8mcRHvdk1dYbZYsm2SFMS01YvA6B_zfH_kg"),

    };


    private int iconNumber = 0;

    private final JButton button;

    private boolean stop = true;

    private final Random random;

    private static final int MIN_DELAY = 70, DELAY = 500;

    private Timer timer;


    public ChangeButtonIcon() throws IOException {


        random = new Random();

        button = new JButton();

        button.setIcon(new ImageIcon(urls[iconNumber]));

        button.setHorizontalTextPosition(SwingConstants.CENTER);

        button.addActionListener(e -> startStopSlideShow());

        add(button);

    }


    private void startStopSlideShow(){


        stop = ! stop;

        if(stop){

            timer.stop();

            return;

        }


        timer = new Timer( MIN_DELAY+ random.nextInt(DELAY), (e)->swapIcon());

        timer.start();

    }


    private void swapIcon() {

        iconNumber = iconNumber >= urls.length -1 ? 0 : iconNumber+1;

        button.setIcon(new ImageIcon(urls[iconNumber]));

    }


    public static void main(String[] args) throws IOException{

        JFrame window = new JFrame();

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        window.add(new ChangeButtonIcon());

        window.add(new JLabel("Click image to start / stop"), BorderLayout.PAGE_END);

        window.pack();

        window.setVisible(true);

    }

}

https://i.stack.imgur.com/rTYb0.gif

查看完整回答
反對 回復 2022-07-20
  • 1 回答
  • 0 關注
  • 123 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號