5

The following code renders a JButton without text:

public abstract class Test {

    public static void main(String... args) {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            JPanel panel = new JPanel();

            String text = "Invisible";
            JButton button = new JButton(text); // blank button rendered ???

            System.out.println(button.getText()); // prints Invisible

            button.setAction(new AbstractAction() {     
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    // do nothing
                }
            });

            System.out.println(button.getText()); // prints null ???

            button.setFocusable(false);

            button.setPreferredSize(new Dimension(100, 40));

            panel.add(button);

            frame.setResizable(false);
            frame.getContentPane().add(panel);

            frame.pack();
            frame.setVisible(true);

        });

    }

}

If i remove the call to button.setAction(...) it renders the button including the text.

Alternatively:

public abstract class Test {

    public static void main(String... args) {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            JPanel panel = new JPanel();

            String text = "Invisible";
            JButton button = null;
            button = new JButton(new AbstractAction() {     
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    // do nothing
                }
            });

            button.setText(text); // renders the button with text
            System.out.println(button.getText()); // prints Invisible obviously

            button.setFocusable(false);

            button.setPreferredSize(new Dimension(100, 40));

            panel.add(button);

            frame.setResizable(false);
            frame.getContentPane().add(panel);

            frame.pack();
            frame.setVisible(true);

        });

    }

}

Works fine but has some nasty implications like not being able to change the buttons action without resetting its text after.

Why?!

2 Answers 2

3

@Dima Maligin

  • not an answer, will be deleted

  • Swing Action should be declared (override isEnabled too, it can be importnant)

.

 private class SwingAction extends AbstractAction {

   //or public Action SwingAction() {
   //       return new AbstractAction("Invisible") {
   //           here to override AbstractAction   
   //       } 
   //    } 

    public SwingAction() {
        putValue(NAME, "Invisible"); // bounds properties
        putValue(SHORT_DESCRIPTION, "Invisible");
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // do nothing
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I get the point but isn't it kinda makes the whole point of anonymous inner class useless in this case?
1. this is as I understand the Swing Action ..., Swing Action is designated as interface, 2. this action could be accesible from everywhere (see my note about - override isEnabled too), not hidden as anonymous inner class, 3. it must works your way too
@Dima Maligin true is, seems like as there (in API ins't another declaration) is called JButton.setAction(new AbstractAction(JButton.getText()) { () translated to your SSCCE/MCVE
So basically JButton.setAction(...) sets the buttons text to the name of the action. Oracle stated: Setting the Action results in immediately changing all the properties described in Swing Components Supporting Action. which implies to effect only the action it self and not the components attributes.
@DimaMaligin, which implies to effect only the action it self and not the components - No. The is the API for the button, not the Action. So it implies the properties of the button are changed. If you want to know how to change the properties of the Action, then read the Action API.
1

It's Better to Enter Text in JButton Constructor because JButton constructor has argument of Strings not String Variable.

JButton button = new JButton("Invisible"); 

3 Comments

Originally that was exactly the case I added the String just before the post.
Besides that does not seem very practical.
I do not agree with this. An Action is a much better way to configure a JButton. Not only does it assure common behavior between multiple controls (such as a menu item and toolbar button which both perform the same function), it allows a tight coupling of the text, mnemonic, and accelerator.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.