简体   繁体   中英

How to turn on buttons once turned off in ActionListener

Problem: Code does not turn the button back on (Example gives it 5 seconds for you to press)

Example code:

public static void main(String[] args) throws InterruptedException
{
    Example call = new Example();
    Thread.sleep(5000);
    call.ButtonSwitch(1);
}

NOTE: this is the smallest coding i could make to show my problem

public class Example extends JFrame implements ActionListener {

static Example frame2 = new Example();

GridLayout experimentLayout = new GridLayout(0,1);

JPanel Game = new JPanel();

JButton button1 = new JButton("Press");

public Example()
{
    Create();
}

public void Set() 
{
    setResizable(false);
}

public static void Create() {
    /* Use an appropriate Look and Feel */
    try {
        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }
    /* Turn off metal's use of bold fonts */
    UIManager.put("swing.boldMetal", Boolean.FALSE);

    //Schedule a job for the event dispatch thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
    public static void createAndShowGUI() 
    {
        //Create and set up the window.
        frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Set up the content pane.
        frame2.addComponentsToPane(frame2.getContentPane());
        //Display the window.
        frame2.pack();
        frame2.setVisible(true);
    }

    public void addComponentsToPane(final Container pane) 
    {
        Game.setLayout(experimentLayout);
        JPanel controls = new JPanel();
        controls.setLayout(new GridLayout(2,3));

        //Set up components preferred size
        JButton b = new JButton("Just fake button");
        Dimension buttonSize = b.getPreferredSize();
        Game.setPreferredSize(new Dimension((int)(buttonSize.getWidth() * 2),
                (int)(buttonSize.getHeight() * 1)* 4));

        Game.add(button1);
        button1.addActionListener(this);

        //Process the Apply gaps button press
        pane.add(Game, BorderLayout.NORTH);
        pane.add(new JSeparator(), BorderLayout.CENTER);
        pane.add(controls, BorderLayout.SOUTH);

    }
    //Turns button off On Click
    public void actionPerformed(ActionEvent e) 
    {
        if (e.getSource() == button1)
        {
            button1.setEnabled(false);
        }
    }

    //This does not turn the button on but tries to
    public void ButtonSwitch(int num)
    {
        if (num == 1)
        {
            System.out.println("This is called");
            button1.setEnabled(true);
        }
    }

}

I want to make the method Enable the button, but if this is not possible a way to do this in action listener without user input would be the second option (which would look like the Button switch method placed inside the ActionListener)

The problem comes from the bad design of the class. The point is that you are not calling setEnabled(true) and setEnabled(false) on the same button1 . In your main ,

Example call = new Example();
Thread.sleep(5000);
call.ButtonSwitch(1);

the last line invokes setEnabled(true) on the button of call , while the actionPerformed invokes the setEnabled(false) on the button of frame2 .

Regardless, you are doing it wrong:

  1. Don't mix the main (entry) thread with the EDT.
  2. Don't hold a member of the same class type as the containing class (unless there's a special reason to do so).

Here is a real MCVE of a working code:

public class Example extends JFrame {

    JButton button = new JButton("Press");
    Timer timer = new Timer(5000, e -> button.setEnabled(true));

    public Example() {

        add(button);
        button.addActionListener(e -> { 
            button.setEnabled(false);
            timer.start();
        });

        timer.setRepeats(false);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

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

        SwingUtilities.invokeLater(() -> new Example());
    }
}

Notes:

  • Method and non-final variable names start with a lowercase.
  • Don't use setPreferredSize , override getPreferredSize instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM