Grouping Objects in Java

433 Views Asked by At

Is there any way to group objects in Java core SE ?

Like i have multiple JButtons, JLabels and other objects and i want to set the visibility of them to false and enable using a function.

Can i group these Java objects as a single unit so that i do not have to write each component.setVisiiblity(true) like this.

For further example i have something like this:

private void hideDashboard() {
    someButton1.setVisible(false);
    someButton2.setVisible(false);
    someButton3.setVisible(false);
    someButton4.setVisible(false);
    someLabel.setVisible(false);
}

I am not using any external packages. For IDE i am using Netbeans 8.2

3

There are 3 best solutions below

6
Jason On

One option would be to store them in a Collection since they're all JComponent objects.

Collection<JComponent> components = new ArrayList<>(Arrays.asList(button1, button2, button3, button4, button5));

components.forEach(component -> component.setVisible(false));
0
Eyeyar Owen On

I think you can use the same approach when showing/hiding elements in HTML. You can wrap them with a parent element(e.g. div) and show/hide them using CSS(e.g. display: none).

As with Java, if I am not mistaken, if you add child panels to a parent panel and you show/hide the parent panel, the child panels will also be simply shown/hidden.

0
gthanop On

And there are some other options also:

  1. If you want to just make invisible some components you can add them in a CardLayout with a panel containing all of them and a blank one.
  2. If you want to apply an action to a Container (such as a JComponent) and all of its children Components, then you can make a recursive routine to do that (well actually it is not necessary obviously to be recursive, but that would have a more obvious code in my opinion).

Code for first option:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class Grouping1 {

    public static void main(final String[] args) {
        final JPanel buttons = new JPanel();
        for (int i = 0; i < 3; ++i)
            buttons.add(new JButton("Does nothing " + i));

        final JPanel internal = new JPanel(new BorderLayout());
        internal.add(new JTextArea("1234567890.\n0987654321."), BorderLayout.CENTER);
        internal.add(buttons, BorderLayout.LINE_END);

        final CardLayout clm = new CardLayout();
        final JPanel clp = new JPanel(clm);

        final JCheckBox enable = new JCheckBox("Click me", true);
        enable.addActionListener(e -> clm.show(clp, enable.isSelected()? "FILLED": "BLANK"));

        clp.add(internal, "FILLED");
        clp.add(new JPanel(), "BLANK");

        clm.show(clp, "FILLED");

        final JPanel contents = new JPanel(new BorderLayout());
        contents.add(clp, BorderLayout.CENTER);
        contents.add(enable, BorderLayout.PAGE_START);

        final JFrame frame = new JFrame("Components");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(contents);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

And code for second option:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.util.function.Consumer;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class Grouping2 {

    public static void applyRecursively(final Container container,
                                        final Consumer<Component> consumer) {
        for (final Component child: container.getComponents())
            if (child instanceof Container)
                applyRecursively((Container) child, consumer);
            else
                consumer.accept(child);
        consumer.accept(container);
    }

    public static void main(final String[] args) {
        final JPanel buttons = new JPanel();
        for (int i = 0; i < 3; ++i)
            buttons.add(new JButton("Does nothing " + i));

        final JPanel internal = new JPanel(new BorderLayout());
        internal.add(new JTextArea("1234567890.\n0987654321."), BorderLayout.CENTER);
        internal.add(buttons, BorderLayout.LINE_END);

        final JCheckBox enable = new JCheckBox("Click me", true);
        enable.addActionListener(e -> applyRecursively(internal, c -> c.setEnabled(enable.isSelected())));

        final JPanel contents = new JPanel(new BorderLayout());
        contents.add(internal, BorderLayout.CENTER);
        contents.add(enable, BorderLayout.PAGE_START);

        final JFrame frame = new JFrame("Components");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(contents);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

In both codes, just click the "Click me" checkbox to toggle the components' state.

The most precise answer though in my opinion could be Jason's which lets you group the components you are free to select. Having your own Collection of Components lets you apply actions to them, without having to be in the same GUI area (as in my first code) and without having to apply to all of the Container's children the action (as in my second code). I guess it depends on your needs.