Java单选按钮更改另一个面板中的按钮文本

时间:2013-11-19 23:47:55

标签: java swing actionlistener jradiobutton

我正在为我的Programming II课程制作一个Java日历,我需要一些帮助。我已经制作了我的日历,因此它是6 x 7网格按钮并创建了一个方法,可以更改按钮文本以匹配所选月份(通过单选按钮选择)。它适用于默认的选定月份,但是当选择新的单选按钮时,我无法更新ui。我的formatCalendar方法以及我的日历按钮都在CalendarPanel类中,它扩展了JPanel,但我的单选按钮位于MonthRadioButtonPanel中,它也扩展了JPanel。我知道单选按钮上的动作监听器是可行的,因为我已经用简单的System.out.println测试了它...谢谢,非常感谢任何帮助!

我的单选按钮是在MonthRadioButtonPanel()构造函数中创建的。

JRadioButton[] monthRadioButton;
RadioButtonListener listener = new RadioButtonListener();

public MonthRadioButtonPanel()
{
    monthRadioButton = new JRadioButton[12];
    ButtonGroup monthSelect = new ButtonGroup();

    this.setLayout(new GridLayout(2,6));

    //creates radio buttons with labels and default selected value
    monthRadioButton[0] = new JRadioButton("January",true);
    monthRadioButton[1] = new JRadioButton("February",false);
    monthRadioButton[2] = new JRadioButton("March",false);
    monthRadioButton[3] = new JRadioButton("April",false);
    monthRadioButton[4] = new JRadioButton("May",false);
    monthRadioButton[5] = new JRadioButton("June",false);
    monthRadioButton[6] = new JRadioButton("July",false);
    monthRadioButton[7] = new JRadioButton("August",false);
    monthRadioButton[8] = new JRadioButton("September",false);
    monthRadioButton[9] = new JRadioButton("October",false);
    monthRadioButton[10] = new JRadioButton("November",false);
    monthRadioButton[11] = new JRadioButton("December",false);

    for (int i = 0; i < monthRadioButton.length; i++)
    {
        //adds radio buttons and an action listener to each 
        monthSelect.add(monthRadioButton[i]);
        monthRadioButton[i].addActionListener(listener);      
        monthRadioButton[i].setActionCommand(monthRadioButton[i].getText());
        this.add(monthRadioButton[i]);                        
    }

}

我正在使用内部类来收听单选按钮。方法formatCalendar(int nDays,int firstDayOfWeek)在CalendarPanel类中,它根据月中的天数和当月的第一天(例如Mon,Tues使用int)正确格式化日历表示)。 getDaysInMonth()和getFirstDayOfWeek()方法位于MonthRadioButtonPanel中,无论选择哪个单选按钮,都可以找到月中的日期和月中的第一天。这适用于默认选择(在本例中为January),但是当选择新的单选按钮时,UI不会刷新。这是我的内部RadioButtonListener类。

class RadioButtonListener implements ActionListener
{
    //listens to radio buttons and reformats calendar
    public void actionPerformed(ActionEvent e)
    {
        //this is just a test to see if the listeners are working correctly; it works
        System.out.println(e.getActionCommand()); 

        //actual code trying to reformat CalendarPanel when a radio button is clicked
        CalendarPanel cal = new CalendarPanel();
        cal.formatCalendar(getDaysInMonth(), getFirstDayOfWeek());
        cal.revalidate();
        cal.repaint();

    }

}

修改

所以我完全改变了我的RadioButtonListener @Hovercraft Full Of Eels建议所以看起来像:

class RadioButtonListener implements ActionListener
{
    private CalendarPanel cal;

    public RadioButtonListener()
    {

    }

    public RadioButtonListener(CalendarPanel cal) {
        this.cal = cal;
    }

    public void actionPerformed(ActionEvent e)
    {
        cal.formatCalendar(getDaysInMonth(), getFirstDayOfWeek());
        cal.revalidate();
        cal.repaint();
    }    
}

}

我的Frame类构造函数编译得很好,但是当我单击一个单选按钮时,它会抛出一个空指针异常。

public class Frame extends JFrame
{

//creates frame with added panels
public Frame()
{
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("Calendar");
    this.setSize(900,400);
    this.setLayout(new BorderLayout());

    MonthRadioButtonPanel mon = new MonthRadioButtonPanel();
    this.add(mon, BorderLayout.SOUTH);

    CalendarPanel cal = new CalendarPanel();

    MonthRadioButtonPanel.RadioButtonListener list = mon.new RadioButtonListener(cal);

    this.add(cal, BorderLayout.WEST);
    this.add(new TitlePanel(), BorderLayout.NORTH);

    this.setVisible(true);

}

}

1 个答案:

答案 0 :(得分:2)

您正在将错误的CalendarPanel对象更改为在侦听器中专门创建的对象。同时,显示的CalendarPanel对象不知道这些更改。

class RadioButtonListener implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        // the line below creates a *new* CalendarPanel object
        // one completely unrelated to the displayed CalendarPanel 
        CalendarPanel cal = new CalendarPanel();
        cal.formatCalendar(getDaysInMonth(), getFirstDayOfWeek());
        cal.revalidate();
        cal.repaint();
    }    
}

__ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _

解决方案是将对显示的CalendarPanel对象的引用传递给侦听器,并对其进行更改。

class RadioButtonListener implements ActionListener
{
    private CalendarPanel cal;

    public RadioButtonListener(CalendarPanel cal) {
       this.cal = cal;
    }
    public void actionPerformed(ActionEvent e)
    {
        cal.formatCalendar(getDaysInMonth(), getFirstDayOfWeek());
        cal.revalidate();
        cal.repaint();
    }    
}

创建上面的监听器时,您需要传递对有效显示的CalendarPanel对象的引用以允许它工作。


修改
您在评论中说明:

  

好的,我这样做并在我的Frame构造函数中实例化它(它也创建并添加了我的其他面板),但它创建了一个空指针异常。

如果您的问题有任何重大更改,请通过在当前问题的底部发布新代码和新说明来编辑您的问题(我现在正在做)。如果您可以避免这样做,请不要更改原始问题或代码,以免使答案无效。

现在解决你的问题:我只能猜测,因为我们没有看到你改变的代码,但你是否已经将CalendarPlayer变量传递到RadioButtonListener构造函数之前你已经分配了一个有效的CalendarPlayer为其变量。如果是这样,那将解释这一点,因为您将null传递给RadioButtonListener构造函数。解决方案是在调用RadioButtonListener构造函数之前首先将CalendarPlayer分配给它的变量。


修改2

您可能会创建两个RadioButtonListener,一个使用默认构造函数,一个没有参数,另一个使用参数。摆脱那个默认的构造函数,再次没有参数的构造函数,不要创建其中两个对象(这没有任何意义,让我抓住你的头脑为什么要这样做)并努力搞清楚获取正确引用到侦听器的方法。如果你仔细想想,你应该能够弄明白这一点,而不是从这里复制和粘贴代码。