0

I searched StackOverflow and found this question but I couldn't get it.

How do I invoke a Java method when given the method name as a string?

I have some JLabels and JPanels and each Label is working as a custom graphical button to change background color of a particular JPanel and as there are alot of these labels so I have created a custom MouseListener which is to change the background color of particular JPanel with the name each JLabel has.

Now as these JLabels are giving name of calling JPanels in String value, I want something like this

@Override
public void mouseClicked(MouseEvent e)
{
    e.getComponent().getName().setBackground(new COLOR.RED);
}

But I cannot do so.

I just want to convert my string into JPanel's name.

Community
  • 1
  • 1
Airy
  • 5,484
  • 7
  • 53
  • 78
  • No as I said there are alot of these JLabels, so calling method directly on each label would be hell – Airy Sep 16 '14 at 14:58
  • If I understand correctly you need to map a label to a panel, why not use a `HashMap` and just open the panel associated with the clicked label? – user1803551 Sep 16 '14 at 14:59
  • Then I will have to make a separate long list with HashMap and keeping track of each JPanel's name and position so that I can call from that list. Therefore the better idea can be if somehow I could convert string coming from JLabel into JPanel variable name. – Airy Sep 16 '14 at 15:03
  • Why would you need to keep track of the `JPanel`s' name and position when a mapping doesn't require them? – user1803551 Sep 16 '14 at 15:10
  • And what do you mean by *"open a particular JPanel "*? You can't strictly open a `JPanel`, what exactly is the operation you want to do? – user1803551 Sep 16 '14 at 15:13
  • @user1803551 Sorry, now I have changed that to change background color instead of opening word. The actual story is really long so in short i want to change the background color of jpanel. – Airy Sep 16 '14 at 15:18
  • So now you want to choose a color with each label? `Color` is not a `Component`. You want to convert the label's `String` to a color's name? – user1803551 Sep 16 '14 at 15:23
  • Not at all. I didn't say that I want to convert label's string to a color but a JPanel – Airy Sep 16 '14 at 15:25
  • But now you have only 1 panel which has its background changing according to a color specified by a label. – user1803551 Sep 16 '14 at 15:27
  • Please read the question again. I have tried my best explaining the problem. – Airy Sep 16 '14 at 15:28
  • Yet still *"I have created a custom MouseListener which is to **open the JPanel** with the name each JLabel has."* makes little sense to me. You really need to give specific details of what you have and what you want to achieve. – user1803551 Sep 16 '14 at 15:32
  • You can't just put the labels and panels in arrays with corresponding indexes? – user1803551 Sep 16 '14 at 15:57

3 Answers3

2

You can use "client properties" from JComponent. Each Jcomponent contains a Map to put properties inside. You can use a constant String like "associatedPanel" for the key, and the JPanel for the value. The code could be something like this:

JPanel panel1 = new JPanel();
JLabel label1 = new JLabel();
label1.putClientProperty("associatedPanel", panel1);

Now in the mouse listener use getClientProperty("associatedPanel") to obtain the associated panel to set the background.

Ezequiel
  • 3,477
  • 1
  • 20
  • 28
  • 1
    You said that second parameter would be a JPanel but that's the string coming from JLabel's name. – Airy Sep 16 '14 at 16:08
  • @AbdulJabbarWebBestow The second paramter *is* a `JPanel`, the label's string is whatever it wants to be. If you have so many labels and panels like you said, did you code all of them in by hand (probably wrong) or did you create them procedurally? You are almost surely trying to to solve a problem that can be avoided. – user1803551 Sep 16 '14 at 16:22
0

You can do it like this:

create a map:

Map<String, JPanel> map = new HashMap<String, JPanel>();

then put all your jPanels in it using their names as keys:

map.put("jPanel1", jPanel1);

Then in the event listener:

JPanel jPanel1 = map.get(e.getComponent().getName());
  • 2
    What will `this` refer to? Where will you put these lines in? – user1803551 Sep 16 '14 at 15:04
  • Let me check, I will get back as I check it – Airy Sep 16 '14 at 15:11
  • If you create a mapping, why not just put the label and corresponding panel in instead of the names? – user1803551 Sep 16 '14 at 15:15
  • No I don't want to create a long map of my jpanels. The previous answer was looking better – Airy Sep 16 '14 at 15:16
  • Please change back to previous one. I am getting an exception of no such field – Airy Sep 16 '14 at 15:19
  • The previous one was wrong, because I had misunderstood your question. You can not get an object already created in java by name, you can only create a new instance of a class or get a class variable object, so I am afraid this is the only way available in your case as far as I know –  Sep 16 '14 at 15:22
  • Oh my luck :(. But I believe there surely can be a way to do this. I will try my best to get answer for this. Because this has been a question in programming for long time. – Airy Sep 16 '14 at 15:24
  • @AbdulJabbarWebBestow You can get instances by name in Java, but I'm avoiding telling you how to do that because it's the wrong way to go. – user1803551 Sep 16 '14 at 15:25
  • @AbdulJabbarWebBestow Because it uses reflection which you should always avoid unless you just can't. Besides, this is a sure [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – user1803551 Sep 16 '14 at 15:29
  • No, there's nothing like that available. If you hook into the debugging API you may be able to do it, but not when running "normally". –  Sep 16 '14 at 15:30
0

I would say that the simplest solution to associate 2 elements of the UI is to combine them into a class. Then referencing the corresponding element from the other becomes obvious.

Something like:

class LabelPanel {
   JLabel label;
   JPanel pane;
   ...
}

Basic working example:

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class TestLabelPanelComposition {

    public static class LabelPanel {

        private final JLabel label;
        private final JPanel panel;
        private Color colorToSet;
        public LabelPanel(String labelText, final Color colorToSet) {
            super();
            this.colorToSet = colorToSet;
            this.label = new JLabel(labelText);
            this.panel = new JPanel();
            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    Color old= panel.getBackground();
                    panel.setBackground(LabelPanel.this.colorToSet);
                    LabelPanel.this.colorToSet = old;
                }
            });
        }

        public JLabel getLabel() {
            return label;
        }

        public JPanel getPanel() {
            return panel;
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new  TestLabelPanelComposition().initUI();
            }
        });
    }

    protected void initUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Random r= new Random();
        List<LabelPanel> labelPanels =new ArrayList<TestLabelPanelComposition.LabelPanel>();
        for(int i=0;i<10;i++) {
            LabelPanel labelPanel = new LabelPanel("My Label to click "+(i+1), new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
            labelPanel.getPanel().add(new JLabel("Some dummy text inside panel "+(i+1)));
            labelPanels.add(labelPanel);
        }
        frame.setLayout(new GridLayout(0, 5));
        for (LabelPanel labelPanel : labelPanels) {
            frame.add(labelPanel.getLabel());
        }
        for (LabelPanel labelPanel : labelPanels) {
            frame.add(labelPanel.getPanel());
        }
        frame.pack();
        frame.setVisible(true);
    }
}

This should not be too hard to adapt to your actual situation .

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117