1

I am having issues with connecting components within Swing in a way where they would interact or exert a flow of action. My plan is to disable/enable a JTextPane when a button is pushed, and then input numbers so that the program can start the computation. So far here is where I am stuck at:

    private JPanel contentPane;
    protected JTextPane txtpnA;
    protected JTextPane txtpnB;
    protected JTextPane txtpnC;

     /* Button 'a' **/

    JButton btnA = new JButton("a");
    btnA.setBackground(Color.YELLOW);
    btnA.setBounds(47, 54, 89, 23);
    btnA.setActionCommand("a");
    btnA.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
        } {
        }
    });
    contentPane.add(btnA);

   /* TextPane 'a' **/

   txtpnA = new JTextPane();
   txtpnA.setBounds(47, 88, 89, 20);
   contentPane.add(txtpnA);
   txtpnA.setBorder(BorderFactory.createLineBorder(Color.black));

And here is the method:

   public void actionPerformed(ActionEvent event) {

    String command = event.getActionCommand();
    if(command.equals("a")) 
    {
        txtpnA.setEnabled(false);
    } else if(command.equals("b")) 
    {
        txtpnB.setEnabled(false);
    } else if(command.equals("c")) 
    {
        txtpnC.setEnabled(false);
    }
  }
}

I am having hard time to find articles regarding communication between JComponents. If you could also suggest a verbose source, it'd be much appreciated.

winnergo
  • 101
  • 11
  • I don't understand what is you problem and why `public void actionPerformed(ActionEvent event)` is empty. – KunLun Jun 28 '18 at 10:30
  • I am trying to mount the method written on the bottom to each of the buttons. I know for a fact I am doing it very bad, hence this query. – winnergo Jun 28 '18 at 10:35
  • so, you have more buttons and want to make a common actionlistener for them? – KunLun Jun 28 '18 at 10:44
  • In the top example, you've created an anonymous `ActionListener` to button "a". Since you can guarantee that only button "a" will be able to execute this listener, it's safe to assume, when it's called, that what ever needs to be done is related to button "a" been actioned – MadProgrammer Jun 28 '18 at 10:45
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Jun 28 '18 at 10:50
  • I see my post is quite confusing. Sorry for that. So , ultimately, what I want to achieve is to connect Jbuttons with Jtextpanes, as an example, if the user clicks on button 'a', textpane 'a' would become disabled, and when the user inserts data into textpane 'b' and 'c', the computation starts. – winnergo Jun 28 '18 at 10:54

2 Answers2

2

I would suggest you to create a new class that can handle your request for a specific component and don't use anonymouse event handler:

public class ButtonHandler extends AbstractAction {
    private JComponent componentToDisable;
    public ButtonHandler(JComponent comp, String text) {
        super(text);
        componentToDisable = comp;
    }
    public void actionPerformed(ActionEvent event) {
       componentToDisable.setEnabled(false);
    }
}

How to use it:

/* TextPane 'a' **/
txtpnA = new JTextPane();
txtpnA.setBounds(47, 88, 89, 20);
contentPane.add(txtpnA);
txtpnA.setBorder(BorderFactory.createLineBorder(Color.black));

JButton btnA = new JButton(new ButtonHandler(textpnA, "a"));
btnA.setBackground(Color.YELLOW);
btnA.setBounds(47, 54, 89, 23);
contentPane.add(btnA);

The same procedure for other buttons.

JButton btnB = new JButton(new ButtonHandler(textpnB, "b"));
JButton btnC = new JButton(new ButtonHandler(textpnC, "c"));

And last but not least. As it already mentioned by Andrew Thompson:

Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or combinations of them along with layout padding and borders for white space.

Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • Thanks, I really like the idea of yours. However, I don't get the part where you create the constructor with a String parameter. How does it receive the String without ActionCommand? Also, when I implement the class the way you suggested, I receive a nullpointer exception at the implemented actionPerformed method. – winnergo Jun 28 '18 at 13:08
  • 1
    @Bence this solution doesn't require action command. It's already linked with the component, that must be disabled. About nullpointer: the variables `textpnA`, `textpnB` and `textpnC` must be initialized before the appropriate instance of `ButtonHandler` is created. – Sergiy Medvynskyy Jun 28 '18 at 13:24
0

If I understand right your problem, you want to make a common ActionListener which will be called by your buttons.

You can create an inner private class in your class where have those buttons. And add an instance, of that inner class, to ActionListener of button.

public class MyClass {

    //...//

    JButton a = new JButton("a");
    a.setActionCommand("a");
    a.setBounds(0, 0, 50, 50);
    a.addActionListener(new ActionButtons());

    //...//

    private class ActionButtons implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {

            String action = arg0.getActionCommand();

            if(action.equals("a")) {

                System.out.println("a");

            }

            if(action.equals("b")) {

                System.out.println("b");

            }

            if(action.equals("c")) {

                System.out.println("c");

            }
        }
    }
}

P.S.: If you want to use that ActionListener in more than one class, you can declare it as public class in other class file.

KunLun
  • 3,109
  • 3
  • 18
  • 65