0

I have a JPanel, which contains a JPanel and a JButtons. in the inner JPanel I have some JCheckBoxes which are initially selected. I have added an actionListener to my JButtons that check, if each of the JCheckBoxes changed to unselected an action performs. but It doesn't work. this is my code, where would the problem be?

public LimitPanel(String[] dates, int column) {

    GridLayout layout = new GridLayout(1 + dates.length, 0);
    setLayout(layout);
    setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    setVisible(true);

    this.dates = dates;

    checks = new JCheckBox[dates.length][column-1];

    for (int i = 0; i < dates.length; i++) {

        for (int j = 0; j < column - 1; j++) {
            checks[i][j] = new JCheckBox();
            checks[i][j].setSelected(true);
            checks[i][j]
                    .setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
            add(checks[i][j]);

        }
    }
}
public JCheckBox[][] getChecks() {
    return checks;
}

in my Main Clas, I have another method that contains:

ResultSet e = connect.select("Invi", "*");
        try {
            while (e.next()) {
                final int inviID = e.getInt("inviID");
                    JPanel pn = new JPanel();
                pn.setSize(d.width, d.height);
            pn.setLocation(0, 0);
                    pn.setLayout(new BoxLayout(pn, BoxLayout.PAGE_AXIS));

                    lp = new LimitPanel(st, 6);
                    pn.add(lp);



                    JButton sabt = new JButton("  ثبت  ");
                    sabt.addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent arg0) {
                            System.out.println("saaaaaaaaaaaaaaaabt");
                            JCheckBox[][] jcb = new JCheckBox[lp.getDates().length][5];
                            jcb = lp.getChecks();
                            for (int i = 0; i < lp.getDates().length; i++)
                                for (int j = 0; j < 5; j++) {
                                    if (!jcb[i][j].isSelected()) {
                                        System.out.println("naaaaaaaaa");
                                        connect.insertLimit(inviID, (lp
                                                .getDates())[i], j+"");
                                    }

                                }

                        }
                    });
                    pn.add(sabt);

                    panels.add(pn);

                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            setContentPane(panels.get(p));
            revalidate();

I edited it to contain what ever is necessary, my problem is that System.out.println("saaaaaaaaaaaaaaaabt"); is always works when I press the button but what ever I do with the checkBoxes System.out.println("naaaaaaaaa"); never works.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Paniz
  • 594
  • 6
  • 19
  • In `for (int j = 0; j < column - 1; j++) {` it should be `j < collumn` or `j <= collumn -1`. You'r skipping a whole row of JCheckBoxes in this loop. – ApproachingDarknessFish Aug 19 '13 at 20:55
  • the problem insists, I have a checkbox with column-1 columns. I have written here incorrectly. I will edit it. – Paniz Aug 19 '13 at 21:01
  • You get your checkboxes from `lp` which is a `LimitPanel` which in turn is initialized with `st`. I won't even going to ask what the `st` variable is. Please post a [SSCCE](http://sscce.org/) so you can get help faster – c.s. Aug 19 '13 at 21:10
  • Where's the `getChecks` method? You shouldn't be passing back the `JCheckBox`, it exposes it to possible modification. Instead, you `lp` class should provide a `isChecked` method instead - IMHO – MadProgrammer Aug 19 '13 at 21:13
  • @MadProgrammer getchecks is a method I added it to my question. it doesnt return boolean, it returns the JChceckBoxes Value. – Paniz Aug 19 '13 at 21:18
  • @c.s. `st` is an array which is correctly initialized, but the process is so long so that I decided not to post it.to make sure I have tested both of my classes, and they work properly individually but together no. – Paniz Aug 19 '13 at 21:19
  • @Paniz I was pretty sure it did (return `JCheckBox[]`), my suggestion would be to change it, again, because you are exposing objects that can be modified out side of your control. – MadProgrammer Aug 19 '13 at 21:22
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Aug 19 '13 at 21:40
  • @AndrewThompson I have added what ever is necessary and removed what ever is extra. I don't know what else I should do :( – Paniz Aug 19 '13 at 21:42
  • Code snippets are not compilable & therefore not 'correct' at showing (being an example of) the problem. – Andrew Thompson Aug 19 '13 at 22:05

1 Answers1

2

Your using a while (while (e.next()) {) to build portions of your program. Within it your a creating a new reference to lp and JButton, sabt, on each iteration.

Your ActionListener will only be able to reference the LAST instance of lp created. This is most likely why you actionPerformed is doing what you think it should be...

Think about it like this...if I do...

lp = new new LimitPanel(st, 6);
lp = new new LimitPanel(st, 6);
lp = new new LimitPanel(st, 6);
lp = new new LimitPanel(st, 6);

JCheckBox[] = lp.getChecks();

Which instance of lp have I obtained the check boxes from??

Updated with more details

// Create a new instance of "LimitPanel"
lp = new LimitPanel(st, 6);
// You can check this by using the hashCode of the object...
System.out.println(lp.hashCode());
pn.add(lp);

JButton sabt = new JButton("  ثبت  ");
sabt.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        /*...*/
        // Use what ever was last assigned to "lp"
        jcb = lp.getChecks();
        // You can check this by using the hashCode of the object...
        System.out.println(lp.hashCode());
        /*...*/
    }
});

IF you really wanted to ensure that the ActionListener was using a particular instance of LimitPanel, you should pass that reference to a special instance of ActionListener...

For example...

lp = new LimitPanel(st, 6);
// You can check this by using the hashCode of the object...
System.out.println(lp.hashCode());
pn.add(lp);

JButton sabt = new JButton("  ثبت  ");
sabt.addActionListener(new LimitActionHandler(lp));

And the LimitActionHandler...

public class LimitActionHandler implements ActionListener {

    private LimitPanel limitPane;

    public LimitActionHandler(LimitPanel limitPane) {
        this.limitPane = limitPane;
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        /*...*/
        // Use what ever was last assigned to "lp"
        jcb = limitPane.getChecks();
        // You can check this by using the hashCode of the object...
        System.out.println(limitPane.hashCode());
        /*...*/
    }
}

As I stated in my comments, I think it's a bad idea to expose the JCheckBoxes from the LimitPanel, as it allows other parts of your application unrestricted access to those objects, which they don't need for there work...

JCheckBox[] jcb = limitPane.getChecks();
for (JCheckBox cb : jcb) {
    cb.setSelected(false); //...
}
for (JCheckBox cb : jcb) {
    cb.getParent().remove(cb); //...
}

This is very dangerous. You can argue that your application won't do these things, but you can't stop it from happening...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I have an `actionlistener` for each `Limit1panel` . I think each one should work for its own. no? – Paniz Aug 19 '13 at 21:41
  • No, you don't have one for each `ActionListener`. Each `ActionListener` is referencing the last instance of `lp` you created... – MadProgrammer Aug 19 '13 at 23:11
  • @trashgod Me or the OP? – MadProgrammer Aug 19 '13 at 23:20
  • @MadProgrammer: Just a link for your reference; +1 for trying, but I was at a loss. Paniz: Please edit your question to include an [sscce](http://sscce.org/) that exhibits the problem you describe. – trashgod Aug 19 '13 at 23:36
  • @trashgod Ah, I see. Double posting...naughty Paniz – MadProgrammer Aug 19 '13 at 23:39
  • @MadProgrammer: To be fair, Paniz deleted the question after I deleted my answer; `getChecks()` remains a mystery, and I remain wary of passing around arrays of components. – trashgod Aug 19 '13 at 23:49
  • @trashgod Paniz posted the `getChecks()` method and I've commented (at least twice) about the wisdom of passing `Components` about in this manner as well. Totally agree – MadProgrammer Aug 19 '13 at 23:57
  • @MadProgrammer thanks for your complete answer. I will do what ever you said to fix the problem. – Paniz Aug 20 '13 at 07:44
  • @Paniz Let me know if you have issues getting the concept to work ;) – MadProgrammer Aug 20 '13 at 07:45
  • @trashgod ya I have asked it before, but after changing it I didn't get any answer so I decided to post it once again. sorry any how and thanks for your help. – Paniz Aug 20 '13 at 07:46