>source

작업중인 코드가 있고 간단한 예제를 준비했습니다.

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Example extends JFrame implements ActionListener {
    public static void main(String[] args) {
        Example e = new Example();
        e.setVisible(true);
    }
    private JButton button;
    public Example() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(600, 400);
        this.setLayout(null);
        button = new JButton("button");
        button.setBounds(200, 150, 200, 50);
        button.addActionListener(this);
        this.add(button);
    }
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        button.setEnabled(false);
        
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

pooint는, 우리는 actionPerformed 두 가지 동작이있는 함수 : 버튼을 비활성화하고 실행 sleep 내가하는 일을 모방하기 위해.

내 문제는 버튼이 비활성화된다는 것입니다. actionPerformed 즉,이 5 초의 수면 후에는 더 일찍 비활성화 할 수 없습니다. 뭔가 해보려고했지만 지금까지 변해 button.setEnabled(false); ...에 button.setEnabled(false); this.repaint(); this.validate(); 아무것도하지 않습니다.

내 질문은 : 어떻게 작업을 스윙에서 수행합니까, 먼저 비활성화 버튼이 필요한 곳에서 시간이 많이 걸리는 작업 (예 : 절전)을 수행하고 작업이 완료되면 버튼을 활성화합니까?

  • 답변 # 1

    당신이 할 수 없기 때문입니다 Thread.sleep() UI가 생성되는 동일한 스레드에서 그렇지 않으면 UI가자다은 끝났어.

    당신이하고 싶은 것은 아마도 스윙 타이머 나 스윙 워커를 대신 사용하는 것입니다.

    기타 사항 :

    연장하지 마십시오 JFrame 불필요하게 수업

    null /을 사용하지 마십시오. AbsoluteLayout 차라리 적절한 LayoutManager를 사용하십시오.

    전화 하지마 setBounds() 또는 setSize() 구성 요소에서 올바른 레이아웃 관리자를 사용하면이 작업이 처리됩니다.

    요구 JFrame#pack() 프레임을 표시로 설정하기 전에

    모든 Swing 구성 요소는 다음을 통해 EDT에서 호출되어야합니다. SwingUtilities.invokeLater

    나는 또한 구현의 팬이 아니었다 ActionListener 특히 하나 이상의 구성 요소를 등록하는 경우 ActionListener .

    다음은 변경 사항과 Timer :

    import java.awt.BorderLayout;
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import javax.swing.border.EmptyBorder;
    public class Example {
        private JButton button;
        private Timer timer;
        public static void main(String[] args) {
            SwingUtilities.invokeLater(Example::new);
        }
        public Example() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel panel = new JPanel();
            panel.setBorder(new EmptyBorder(20, 20, 20, 20));
            button = new JButton("button");
            button.addActionListener((ActionEvent e) -> {
                if (timer != null && timer.isRunning()) {
                    return;
                }
                
                button.setEnabled(false);
                timer = new Timer(5000, (ActionEvent e1) -> {
                    // TODO do something after sleeping for 5 seconds
                    button.setEnabled(true);
                    timer.stop();
                });
                timer.start();
            });
            panel.add(button, BorderLayout.CENTER);
            frame.add(panel);
            frame.pack();
            frame.setVisible(true);
        }
    }
    
    

  • 답변 # 2

    @David Kroukamp 감사합니다. 제가 찾던 것입니다. 여기에 필요한 사람이 간단하지만 완벽하지는 않은 경우 toDavid의 답변을 참조하십시오. Worker

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    public class Example extends JFrame implements ActionListener {
        public static void main(String[] args) {
            Example e = new Example();
            e.setVisible(true);
        }
        private JButton button;
        public Example() {
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setSize(600, 400);
            this.setLayout(null);
            button = new JButton("button");
            button.setBounds(200, 150, 200, 50);
            button.addActionListener(this);
            this.add(button);
        }
        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            button.setEnabled(false);
            startThread();
        }
        private void startThread() {
            SwingWorker sw1 = new SwingWorker() {
                @Override
                protected Object doInBackground() {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return null;
                }
                @Override
                protected void done() {
                    button.setEnabled(true);
                }
            };
            
            sw1.execute();
        }
    }
    
    
    

관련 자료

  • 이전 c++ - 낮은 정밀도로의 암시 적 변환에 대한 경고를받는 방법은 무엇입니까?
  • 다음 javascript - 로컬 스토리지를 추가 할 때 어떤 동작을 기대합니까?