Поиск…


Задержка задачи пользовательского интерфейса за определенный период

Все операции, связанные с Swing, выполняются по выделенному потоку (EDT- E vent D ispatch T hread). Если этот поток блокируется, пользовательский интерфейс становится неактивным.

Поэтому, если вы хотите отложить операцию, вы не можете использовать Thread.sleep . Вместо этого используйте javax.swing.Timer . Например, следующий Timer изменит текст на JLabel

  int delay = 2000;//specify the delay for the timer
  Timer timer = new Timer( delay, e -> {
    //The following code will be executed once the delay is reached
    String revertedText = new StringBuilder( label.getText() ).reverse().toString();
    label.setText( revertedText );
  } );
  timer.setRepeats( false );//make sure the timer only runs once

Полный пример выполнения, который использует этот Timer , приведен ниже: пользовательский интерфейс содержит кнопку и метку. Нажатие кнопки отменяет текст метки после 2-секундной задержки

import javax.swing.*;
import java.awt.*;

public final class DelayedExecutionExample {

  public static void main( String[] args ) {
    EventQueue.invokeLater( () -> showUI() );
  }

  private static void showUI(){
    JFrame frame = new JFrame( "Delayed execution example" );

    JLabel label = new JLabel( "Hello world" );
    JButton button = new JButton( "Reverse text with delay" );
    button.addActionListener( event -> {
      button.setEnabled( false );
      //Instead of directly updating the label, we use a timer
      //This allows to introduce a delay, while keeping the EDT free
      int delay = 2000;
      Timer timer = new Timer( delay, e -> {
        String revertedText = new StringBuilder( label.getText() ).reverse().toString();
        label.setText( revertedText );
        button.setEnabled( true );
      } );
      timer.setRepeats( false );//make sure the timer only runs once
      timer.start();
    } );

    frame.add( label, BorderLayout.CENTER );
    frame.add( button, BorderLayout.SOUTH );
    frame.pack();
    frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
    frame.setVisible( true );
  }
}

Повторите задачу пользовательского интерфейса с фиксированным интервалом

Обновление состояния компонента Swing должно происходить в Thread Dispatch Thread (EDT). javax.swing.Timer запускает свой ActionListener на EDT, что делает его хорошим выбором для выполнения операций Swing.

Следующий пример обновляет текст JLabel каждые две секунды:

//Use a timer to update the label at a fixed interval
int delay = 2000;
Timer timer = new Timer( delay, e -> {
  String revertedText = new StringBuilder( label.getText() ).reverse().toString();
  label.setText( revertedText );
} );
timer.start(); 

Полный приведенный пример, который использует этот Timer , приведен ниже: пользовательский интерфейс содержит метку, а текст метки будет возвращен каждые две секунды.

import javax.swing.*;
import java.awt.*;

public final class RepeatTaskFixedIntervalExample {
  public static void main( String[] args ) {
    EventQueue.invokeLater( () -> showUI() );
  }
  private static void showUI(){
    JFrame frame = new JFrame( "Repeated task example" );
    JLabel label = new JLabel( "Hello world" );

    //Use a timer to update the label at a fixed interval
    int delay = 2000;
    Timer timer = new Timer( delay, e -> {
      String revertedText = new StringBuilder( label.getText() ).reverse().toString();
      label.setText( revertedText );
    } );
    timer.start();

    frame.add( label, BorderLayout.CENTER );
    frame.pack();
    frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
    frame.setVisible( true );
  }
}

Запуск задачи пользовательского интерфейса фиксированное количество раз

В ActionListener подключенном к javax.swing.Timer , вы можете отслеживать количество раз, когда Timer выполнял ActionListener . Как только необходимое количество раз будет достигнуто, вы можете использовать метод Timer#stop() чтобы остановить Timer .

Timer timer = new Timer( delay, new ActionListener() {
  private int counter = 0;
  @Override
  public void actionPerformed( ActionEvent e ) {
    counter++;//keep track of the number of times the Timer executed
    label.setText( counter + "" );
    if ( counter == 5 ){
      ( ( Timer ) e.getSource() ).stop();
    }
  }
});

Полный приведенный пример, который использует этот Timer , приведен ниже: он показывает интерфейс, где текст метки будет отсчитываться от нуля до пяти. Как только пять достигнуто, Timer остановлен.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public final class RepeatFixedNumberOfTimes {
  public static void main( String[] args ) {
    EventQueue.invokeLater( () -> showUI() );
  }
  private static void showUI(){
    JFrame frame = new JFrame( "Repeated fixed number of times example" );
    JLabel label = new JLabel( "0" );

    int delay = 2000;
    Timer timer = new Timer( delay, new ActionListener() {
      private int counter = 0;
      @Override
      public void actionPerformed( ActionEvent e ) {
        counter++;//keep track of the number of times the Timer executed
        label.setText( counter + "" );
        if ( counter == 5 ){
          //stop the Timer when we reach 5
          ( ( Timer ) e.getSource() ).stop();
        }
      }
    });
    timer.setInitialDelay( delay );
    timer.start();

    frame.add( label, BorderLayout.CENTER );
    frame.pack();
    frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
    frame.setVisible( true );
  }
}

Создание вашего первого JFrame

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class FrameCreator {
    
    public static void main(String args[]) {
        //All Swing actions should be run on the Event Dispatch Thread (EDT)
        //Calling SwingUtilities.invokeLater makes sure that happens.
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            //JFrames will not display without size being set
            frame.setSize(500, 500);
            
            JLabel label = new JLabel("Hello World");
            frame.add(label);
            
            frame.setVisible(true);
        });
    }
        
}

Как вы можете заметить, если вы запустите этот код, ярлык находится в очень плохом месте. Это трудно изменить с помощью метода add . Чтобы обеспечить более динамичное и гибкое размещение, ознакомьтесь с менеджерами Swing Layout .

Создание подкласса JFrame

import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class CustomFrame extends JFrame {
    
    private static CustomFrame statFrame;
    
    public CustomFrame(String labelText) {
        setSize(500, 500);
        
        //See link below for more info on FlowLayout
        this.setLayout(new FlowLayout());
        
        JLabel label = new JLabel(labelText);
        add(label);
        
        //Tells the JFrame what to do when it's closed
        //In this case, we're saying to "Dispose" on remove all resources
        //associated with the frame on close
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }
    
    public void addLabel(String labelText) {
        JLabel label = new JLabel(labelText);
        add(label);
        this.validate();
    }
    
    public static void main(String args[]) {
        //All Swing actions should be run on the Event Dispatch Thread (EDT)
        //Calling SwingUtilities.invokeLater makes sure that happens.
        SwingUtilities.invokeLater(() -> {
            CustomFrame frame = new CustomFrame("Hello Jungle");
            //This is simply being done so it can be accessed later
            statFrame = frame;
            frame.setVisible(true);
        });
        
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ex) {
            //Handle error
        }
        
        SwingUtilities.invokeLater(() -> statFrame.addLabel("Oh, hello world too."));
    }
        
}

Для получения дополнительной информации о FlowLayout здесь .

Прослушивание события

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class CustomFrame extends JFrame {
        
    public CustomFrame(String labelText) {
        setSize(500, 500);
        
        //See link below for more info on FlowLayout
        this.setLayout(new FlowLayout());
        
        //Tells the JFrame what to do when it's closed
        //In this case, we're saying to "Dispose" on remove all resources
        //associated with the frame on close
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
        //Add a button
        JButton btn = new JButton("Hello button");
        //And a textbox
        JTextField field = new JTextField("Name");
        field.setSize(150, 50);
        //This next block of code executes whenever the button is clicked.
        btn.addActionListener((evt) -> {
            JLabel helloLbl = new JLabel("Hello " + field.getText());
            add(helloLbl);
            validate();
        });
        add(btn);
        add(field);
    }
    
    public static void main(String args[]) {
        //All Swing actions should be run on the Event Dispatch Thread (EDT)
        //Calling SwingUtilities.invokeLater makes sure that happens.
        SwingUtilities.invokeLater(() -> {
            CustomFrame frame = new CustomFrame("Hello Jungle");
            //This is simply being done so it can be accessed later
            frame.setVisible(true);
        });
    }
        
}

Создайте всплывающее окно «Подождите ...»

Этот код можно добавить к любому событию, например, к слушателю, кнопке и т. Д. Блокирующий JDialog появится и останется до завершения процесса.

final JDialog loading = new JDialog(parentComponent);
JPanel p1 = new JPanel(new BorderLayout());
p1.add(new JLabel("Please wait..."), BorderLayout.CENTER);
loading.setUndecorated(true);
loading.getContentPane().add(p1);
loading.pack();
loading.setLocationRelativeTo(parentComponent);
loading.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
loading.setModal(true);

SwingWorker<String, Void> worker = new SwingWorker<String, Void>() {
    @Override
    protected String doInBackground() throws InterruptedException 
        /** Execute some operation */   
    }
    @Override
    protected void done() {
        loading.dispose();
    }
};
worker.execute(); //here the process thread initiates
loading.setVisible(true);
try {
    worker.get(); //here the parent thread waits for completion
} catch (Exception e1) {
    e1.printStackTrace();
}

Добавление JButtons (Hello World Pt.2)

Предполагая, что вы успешно создали JFrame и что Swing был импортирован ...

Вы можете импортировать Swing полностью

import javax.Swing.*;

или Вы можете импортировать Swing Components / Frame, который вы собираетесь использовать

import javax.Swing.Jframe;
import javax.Swing.JButton;

Теперь до добавления Jbutton ...

public static void main(String[] args) {
    
    JFrame frame = new JFrame(); //creates the frame
    frame.setSize(300, 300);
    frame.setVisible(true);

    //////////////////////////ADDING BUTTON BELOW//////////////////////////////
    JButton B = new JButton("Say Hello World");
    B.addMouseListener(new MouseAdapter() {
        
        public void mouseReleased(MouseEvent arg0) {
            System.out.println("Hello World");
        }
        
    });
    B.setBounds(0, 0,frame.getHeight(), frame.getWidth());
    B.setVisible(true);
    frame.add(B);
    ////////////////////////////////////////////////////////////////////////////
}

Выполняя / Компилируя этот код, вы должны получить что-то вроде этого ...

Конечный продукт

Когда нажимается кнопка ... «Hello World» также должен появиться на консоли.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow