问题
I want a JFrame application with 2 buttons (eventually more) that I can use to switch between multiple repeating actions, ofr simplicity I'm just using a console print for now, though it will probably be calling a method instead later. Here is the framework for the JFrame:
public class DayNight extends JFrame implements ActionListener{
//JFrame entities
private JPanel animationPanel;
private JButton button;
private JButton button2;
public static void main(String[] args) {
DayNight frame = new DayNight();
frame.setSize(2000, 1300);
frame.setLocation(1000,350);
frame.createGUI();
frame.setVisible(true);
frame.setTitle("Day/Night Cycle, Rogier");
}
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new FlowLayout() );
animationPanel = new JPanel();
animationPanel.setPreferredSize(new Dimension(2000, 900));
animationPanel.setBackground(Color.black);
window.add(animationPanel);
button = new JButton("choice1");
button.setFont(new Font("Arial", Font.PLAIN, 50));
window.add(button);
button.setActionCommand("choice1");
button.addActionListener(this);
button2 = new JButton("choice2");
button2.setFont(new Font("Arial", Font.PLAIN, 50));
window.add(button2);
button2.setActionCommand("choice2");
button2.addActionListener(this);
}
}
I've tried the following:
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
while ("Stop"!=(command)){
command = event.getActionCommand();
try{
Thread.sleep(500);
if ("choice1".equals(command)){
System.out.println("choice1");
}
else if("choice2".equals(command)){
System.out.println("choice2");
}
else{
System.out.println("no choice");
}
}
catch(InterruptedException ex){
Thread.currentThread().interrupt();
}
}
}
But after I click a button it keeps stuck on that print and I can't even interact with the buttons anymore. Am I missing something or do I need a completely different structure? I've examined a lot of different programs but they are too complicated for me to understand, reading the concurrency in swing also didn't clear it up for me.
Edit: There is no "stop" command yet because I don't need it for now.
回答1:
There are many things wrong with your code.
It starts with wrong comparison of strings ( see here ).
But your actual problem: you are sleeping the event dispatcher thread ( see there )
So your idea of sleeping with an event listener is simply the wrong approach. You can't do it this way. You have to re-think your approach there.
And the real answer here is: you are lacking basic knowledge of Java. Consider learning such basic things first before further overburdening yourself if Swing UI coding.
Your requirement seems to be: after that button was hit - and a certain amount of time passed you want to print something on the console. You can do that like:
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
command = event.getActionCommand();
Runnable printChoice = new Runnable() {
@Override
public void run() {
try{
Thread.sleep(500);
if ("choice1".equals(command)){
System.out.println("choice1");
}
else if("choice2".equals(command)){
System.out.println("choice2");
}
else{
System.out.println("no choice");
}
}
catch(InterruptedException ex){
Thread.currentThread().interrupt();
}
});
new Thread(printChoice).start();
}
The above:
- creates a Runnable that simply waits to then print something
- uses a new Thread (not the event dispatcher thread) to do that
I didn't run this through the compiler - it is meant as "pseudo code" to give you some ideas how to solve your problem.
But further thinking about this - I think this is going in the wrong direction. You don't want that anything is waiting when you develop a reasonable UI application.
In other words: you think of:
- button A is clicked - some code starts "looping"
- when the user makes another choice, that "looping" code notices that and does something
Wrong approach. Instead work along these lines:
- user clicks a button, and maybe that enables other UI components
- user does something with those other UI components - triggering other actions
Example: changing radiobuttons causes events to be fired. You should not have a loop that regularly keeps checking those buttons. Instead you define a clear flow of actions/events the user has to follow in order to trigger a certain action.
来源:https://stackoverflow.com/questions/46200570/jframe-swing-switching-repeating-actions-with-buttons