JPanel radioButton不会使用计时器更改文本,但单击时

时间:2015-10-24 16:29:27

标签: java swing

在谷歌搜索1小时和没有答案的4小时调试后,我不得不问:

我尝试更改每个计时器的两个单选按钮的文本,但即使你点击它们也不会改变它。

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);
    }
}

此外,i包含两个不同的整数,一个用计时器计数,另一个用点击计数。这是怎么发生的?

1 个答案:

答案 0 :(得分:3)

你有两个JTestInf对象:

    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

只使用一个!

即,

    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);

更好的是,不要让您的GUI视图类实现您的侦听器控件接口。将它们分开。

此外,你的Timer应该有自己的ActionListener,一个与JRadioButton监听器不同,因为它们的行为是如此不同。此外,通常不提供JRadioButton的ActionListener,而是将它们添加到ButtonGroup,并在另一个事件中从ButtonGroup中提取所选按钮,例如来自另一个JButton的ActionListener。

你问,

  

但为什么(以及如何)我应该将它们分开?

因为否则你会给一个班级太多的责任。例如,通过使GUI实现ActionListener,它几乎会推动你为Timer和JRadioButtons提供相同的监听器,这是你不想做的事情,因为它们有非常不同的动作。如果侦听器代码非常小,请考虑使用匿名内部类。

例如

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);
    }
}