简体   繁体   中英

JPanel radioButton not changing text with timer but when clicked

After 1h of googling and 4h of debugging without an answer I have to ask:

I tried to change the text of two radiobuttons per timer but it somehow does not change even though does when you click them.

public class JTestinf extends JPanel implements ActionListener {

    JRadioButton one = new JRadioButton();
    JRadioButton two = new JRadioButton();
    int i = 0;

    public static void main(String[] args) {
        JFrame window = new JFrame("RadioButtonDemo");
        JComponent ContentPane = new JTestinf();

        window.setContentPane(ContentPane);
        window.pack();
        window.setVisible(true);
        Timer time = new Timer(500, new JTestinf());
        time.start();
    }

    public JTestinf() {
        one.setText(""+ i++);
        two.setText(""+ i++);
        ButtonGroup group = new ButtonGroup();
        group.add(one);
        group.add(two);

        one.addActionListener(this);
        two.addActionListener(this);

        JPanel radioPanel = new JPanel(new GridLayout(0, 1));
        radioPanel.add(one);
        radioPanel.add(two);

        add(radioPanel, BorderLayout.LINE_START);
    }

    public void actionPerformed(ActionEvent e) {
        one.setText(""+ i++);
        two.setText(""+ i++);
        System.err.println("actionPerformed: ActionEvent="+e.getActionCommand()+" i="+i);
    }
}

Additionally, i contains two different integers, one that counts up with the timer and one that counts up with clicks. How did that happen?

You've got two JTestInf objects:

    JFrame window = new JFrame("RadioButtonDemo");
    JComponent ContentPane = new JTestinf();  // **** one

    window.setContentPane(ContentPane);
    window.pack();
    window.setVisible(true);
    Timer time = new Timer(500, new JTestinf()); // **** two

Use only one!

ie,

    JFrame window = new JFrame("RadioButtonDemo");
    // JComponent ContentPane = new JTestinf();
    JTestinf jTestinf = new JTestinf();

    window.setContentPane(jTestinf);
    window.pack();
    window.setVisible(true);
    Timer time = new Timer(500, jTestinf);

Better still, don't have your GUI view classes implement your listener control interfaces. Keep them separate.

Also your Timer should have its own ActionListener, one distinct from the JRadioButton listener, since their actions are so different. Also, often you don't give JRadioButton's ActionListeners, but rather add them to a ButtonGroup and extract the selected button from the ButtonGroup in another event, such as an ActionListener from another JButton.


You ask,

But why (and how) should I keep them seperate?

Because otherwise you're giving one class too much responsibility. For instance by making your GUI implement ActionListener it almost pushes you into giving the Timer and the JRadioButtons the same listener, something that you don't want to do since they have very different actions. If the listener code is quite small, consider using an anonymous inner class.


For example

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

public class JTestinf extends JPanel {

    JRadioButton one = new JRadioButton();
    JRadioButton two = new JRadioButton();
    int i = 0;

    public static void main(String[] args) {
        JFrame window = new JFrame("RadioButtonDemo");
        // JComponent ContentPane = new JTestinf();
        JTestinf jTestinf = new JTestinf();

        window.setContentPane(jTestinf);
        window.pack();
        window.setVisible(true);
        TimerListener timerListener = new TimerListener(jTestinf);
        Timer time = new Timer(500, timerListener);
        time.start();
    }

    public JTestinf() {
        one.setText("" + i++);
        two.setText("" + i++);
        ButtonGroup group = new ButtonGroup();
        group.add(one);
        group.add(two);

        one.addActionListener(new RadioListener());
        two.addActionListener(new RadioListener());

        JPanel radioPanel = new JPanel(new GridLayout(0, 1));
        radioPanel.add(one);
        radioPanel.add(two);
        one.setActionCommand("one");
        two.setActionCommand("two");

        add(radioPanel, BorderLayout.LINE_START);
    }

    private class RadioListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO put in code for radio button            
            System.out.println("JRadioButton Pressed: " + e.getActionCommand());
        }
    }

    public void setRadioText(int index) {
        one.setText("" + index);
        two.setText("" + (index + 1));
    }
}

class TimerListener implements ActionListener {
    private int index = 0;

    private JTestinf jTestinf;

    public TimerListener(JTestinf jTestinf) {
        this.jTestinf = jTestinf;
    }

    public void actionPerformed(ActionEvent e) {
        index++;
        jTestinf.setRadioText(index);
    }
}

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