【问题标题】:Changing the visibilty of a label更改标签的可见性
【发布时间】:2020-07-21 11:43:08
【问题描述】:

我是 Java 新手,对 WindowBuilder 有一点经验。我想更改标签或文本字段等不同组件的可见性。所以我写了一个示例代码:功能是,当我点击按钮btnAnzahl时,布尔值bNoteVis在方法uebernehmen中设置为true,bNoteVis用作变量来改变可见性标签lblNote。 当我单击按钮时,消息True 显示在文本字段tfNote 上,但标签lblNote 仍然不可见。 有人可以告诉我如何改变这样的可见性,因为我想用多个事件中的许多组件来改变它。

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;
    }

}


【问题讨论】:

    标签: java swing visibility windowbuilder


    【解决方案1】:

    你有一些“神奇的想法”。也就是说:

    • 您已根据布尔变量设置组件的可见性
    • 您希望当布尔变量发生变化时组件的可见性会神奇地发生变化 - 但组件不知道,也没有通知表明发生了这种变化,因此这肯定会失败。

    要获得成功,您需要在侦听器中更改组件本身的可见性。换句话说,在 ActionListener 中,您需要在感兴趣的组件上调用 .setVisible(true/false)

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

    其他不相关的问题:

    • 这样做 contentPane.setLayout(null);lblNote.setBounds(10, 68, 87, 16); 随着时间的推移会导致严重的挫败感,因为它会导致不灵活的 GUI扩展和修改。更好地学习和使用布局管理器
    • 如果您的目标是更改多个组件,那么最好使用 CardLayout 来交换组件。请查看CardLayout Tutorial,了解有关如何使用此工具的详细信息。
    • 另外,我不会切换 JLabel 的可见性,而是更改它的文本,以便它仍然占用 GUI 上的空间。

    例如:

    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);
            });
        }
    }
    

    【讨论】:

    • "我想更改标签或文本字段等不同组件的可见性。" 1) 如果我是最终用户,'最不意外的路径是在不相关时看到提交的文本 disabled。但是.. 2) 如果在此应用程序的上下文中有意义。CardLayout 在一张卡片中包含组件,另一张卡片中包含空白面板也是确保布局管理器为其保留空间的好方法。