1

I have two classes mainpanel.java and subpanel.java. The subpanel.class contains a checkbox and some labels. I want to change the setSelected() and setText() of these components when i click some buttons in the mainpanel.java .

I have created a method in subpanel.java which i call from mainpanel.java and pass the boolean values.

public void schedulerchange(boolean check){
        System.out.println("checked"+check);
        scheduleenabler.setEnabled(check);
        scheduleenabler.setSelected(check);
        scheduleinfo.setText("Scheduler in On");
        //subpanel21.updateUI();
    }

When i call this function from mainpanel.java the function is called but the values don't change unless i make jcheckbox and jlabel static. But from what i learned we should not use static components unless very necessary. Is there some other way to change the components?

Rachel Gallen
  • 27,943
  • 21
  • 72
  • 81
Rohan Kandwal
  • 9,112
  • 8
  • 74
  • 107
  • I guess after setting enabled call **scheduleenabler.revalidate()** will do the trick. – Amarnath Jan 19 '13 at 06:44
  • *"I have two classes mainpanel.java and subpanel.java"* Don't extend either one. Simply keep a reference. Keep also a reference to the text component, and the problem is solved. Also please learn common [Java naming conventions](http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#73307) (specifically the case used for the names) for class, method & attribute names & use it consistently. – Andrew Thompson Jan 19 '13 at 07:24
  • @che revalidate() not working. It is still updating checkbox if i use static – Rohan Kandwal Jan 19 '13 at 08:15

2 Answers2

3

This is not an appropriate use of updateUI(), which "Resets the UI property to a value from the current look and feel." Using revalidate(), as suggested in a comment, would be helpful only if components are added to, or removed from, the enclosing Container. Instead, invoke repaint() directly on the sub-panel instance. For greater flexibility, use the observer pettern suggested here.

Addendum: This example use Action to encapsulate the button's behavior. Because the checkbox's selected state is a bound property, the component is repainted automatically, but you can invoke repaint() explicitly if needed.

Addendum: Update to pass a reference as a parameter.

Addendum: In this variation, the parameter is a reference to the exported Action.

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/a/14412516/230513 */
public class Example {

    private void display() {
        JFrame f = new JFrame("Example");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(0, 1));
        JPanel panel = new JPanel();
        final JCheckBox check = new JCheckBox("Check");
        Action checkAction = new AbstractAction("Update") {

            @Override
            public void actionPerformed(ActionEvent e) {
                check.setSelected(!check.isSelected());
            }
        };
        panel.add(check);
        f.add(panel);
        f.add(new SubPanel(checkAction));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static class SubPanel extends JPanel {

        public SubPanel(final Action action) {
            this.add(new JButton(action));
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Example().display();
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I am pretty much a noob so i don't understand deep coding much. A simple example with two classes will be nice – Rohan Kandwal Jan 19 '13 at 08:49
  • Thanks for the example but your example is using one class in which updation is made on actionPerformed. I want to select/deselect the checkbox when i perform a action from other class. – Rohan Kandwal Jan 19 '13 at 09:39
  • You could pass a reference to the target component(s) as a parameter to your sub-panel class. – trashgod Jan 19 '13 at 09:57
  • can you elaborate? are you suggesting to use object_of_subpanel_class.checkbox.setEnabled(true) ? If you are then i am already using it but the value is updated only if i make checkbox as static. – Rohan Kandwal Jan 19 '13 at 10:56
  • Another common approach is to associate the `Action` with the component, as shown above. For additional guidance, please edit your question to include an [sscce](http://sscce.org/) that shows your current approach. – trashgod Jan 19 '13 at 18:53
3

If I have understood your question then I think you want to write a separate ActionListener class and perform action there which will enable or disable the JCheckBox in the UI-class. The below code shows that. Pass your checkbox reference to that PerformAction class and make it enabled or disabled by clicking on the button.

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MainClass {

 MainClass() {
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JCheckBox check = null;
    // Get the Panel from the subclass;
    JPanel panel = new CheckBox().getCheckBoxPanel();

    // From the compoenents present in the panel get the CheckBox compoenent.
    for(int i = 0; i < panel.getComponentCount(); i++) {
       if(panel.getComponent(i) instanceof JCheckBox) {
        check = (JCheckBox) panel.getComponent(i);
        }
    }

    JButton button = new JButton("Click");

    // Pass the CheckBox Compoenent to the ActionListener.
button.addActionListener(new PerformAction(check));

    jfrm.add(button);
    jfrm.add(panel);
    jfrm.setVisible(true);
 }

  public static void main(String args[]) {
  EventQueue.invokeLater(new Runnable() {

      @Override
      public void run() {
          new MainClass();
      }
  });
 }
}

class PerformAction implements ActionListener {

JCheckBox check = null;
public PerformAction(JCheckBox checkBox) {
    check = checkBox;
}
@Override
public void actionPerformed(ActionEvent e) {
    boolean checkStatus = check.isSelected();
    if(checkStatus == true) {
        check.setEnabled(false);
        check.setSelected(false);
    } else {
        check.setEnabled(true);
        check.setSelected(true);
      }
}
}

 class CheckBox {
public JPanel getCheckBoxPanel() {
    JPanel checkPanel = new JPanel();
    JCheckBox check = new JCheckBox();
    checkPanel.add(new JLabel("CheckBox"));
    checkPanel.add(check);

    return checkPanel;
}
}
Amarnath
  • 8,736
  • 10
  • 54
  • 81
  • i am using two different classes. The subpanel class returns a panel to the mainpanel class. This panel contains a checkbox and label whose properties i am trying to change when i click a button in mainpanel class. – Rohan Kandwal Jan 19 '13 at 10:34
  • Look at my Updated code. This will get the Panel and get the components from the panel and then then pass it to the ActionPerformed class. Hope this helps .. ;-) – Amarnath Jan 19 '13 at 11:06
  • @RohanKandwal: Don't neglect to up-vote answers you found helpful. – trashgod Jan 19 '13 at 18:53