N T
N T

Reputation: 3

Changing the visibilty of a label

i'm new to Java and experience a little bit with the WindowBuilder. I want to change the visibility of a different components like labels or textfields. So I wrote an example code: the function is, when I click on the button btnAnzahl the boolean bNoteVis is set to true in the method uebernehmen and bNoteVis is used as the variable to change the visibility of the label lblNote. When I click on the button the message True is shown on the textfield tfNote but the label lblNote is still not visible. Can somebody tell me how I can change the visibility like this because I want to change it with many components in multiple events.

package gui;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Notenbilanz_2 extends JFrame {

    private JPanel contentPane;
    private JTextField tfAnzahl;
    private JTextField tfNote;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (Throwable e) {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Notenbilanz_2 frame = new Notenbilanz_2();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Notenbilanz_2() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel lblAnzahl = new JLabel("Noten Anzahl");
        lblAnzahl.setBounds(10, 11, 87, 14);
        contentPane.add(lblAnzahl);

        tfAnzahl = new JTextField();
        tfAnzahl.setBounds(10, 31, 104, 20);
        contentPane.add(tfAnzahl);
        tfAnzahl.setColumns(10);

        JLabel lblNote = new JLabel("1.Note");
        lblNote.setVisible(bNoteVis);
        lblNote.setBounds(10, 68, 87, 16);
        contentPane.add(lblNote);

        tfNote = new JTextField();
        tfNote.setBounds(10, 95, 104, 20);
        contentPane.add(tfNote);
        tfNote.setColumns(10);

        JButton btnAnzahl = new JButton("Umrechnen");
        btnAnzahl.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                uebernehmen();
                if (bNoteVis) {
                    tfNote.setText("True");
                }
            }
        });
        btnAnzahl.setBounds(159, 28, 100, 26);
        contentPane.add(btnAnzahl);

        JButton btnNote = new JButton("Umrechnen");
        btnNote.setBounds(159, 92, 100, 26);
        contentPane.add(btnNote);
    }

    boolean bNoteVis = false;

    private void uebernehmen() {
        bNoteVis = true;
    }

}


Upvotes: 0

Views: 506

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

You've got some "magic thinking" going on. To wit:

  • You've set the visibility of the component based on a boolean variable
  • You expect the visibility of the component to magically change when the boolean variable changes -- but the component has no idea, no notification that this change has occurred, and so this is guaranteed to fail.

To get success, you will need to change the visibility of the component itself from within a listener. In other words, within the ActionListener, you will need to call .setVisible(true/false) on the component of interest.

    btnAnzahl.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            uebernehmen();
            lblNote.setVisible(bNoteVis);
        }
    });

Other unrelated issues:

  • doing this, contentPane.setLayout(null);, and this, lblNote.setBounds(10, 68, 87, 16); will lead to siginficant frustration over time as it leads to inflexible GUI's that might look sort-of OK on one platform, but not OK on others, and that are hard to extend and modify. Much better to learn and use layout managers
  • If your goal is to change multiple components, then best to swap components using a CardLayout. Have a look at the CardLayout Tutorial for the details on how to use this tool.
  • Also, rather than toggle a JLabel's visibility, I'd change its text so that it still takes up space on the GUI.

For example:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class Notenbilanz3 extends JPanel {
    private static final String LABEL_TEXT = "Noten Anzahl";
    private JLabel lblNote = new JLabel(LABEL_TEXT);
    private JTextField txtField1 = new JTextField(10);
    private JCheckBox checkBox = new JCheckBox("Check Box", true);

    public Notenbilanz3() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.gridwidth = 2;  
        gbc.insets = new Insets(3, 3, 3, 3);
        add(lblNote, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        add(txtField1, gbc);
        gbc.gridx = 1;
        add(checkBox, gbc);

        checkBox.addItemListener(l -> {
            String text = l.getStateChange() == ItemEvent.SELECTED ? LABEL_TEXT : " ";
            lblNote.setText(text);
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> {
            JFrame frame = new JFrame("Foo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new Notenbilanz3());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

Upvotes: 1

Related Questions