改变标签的可见性

huangapple go评论77阅读模式
英文:

Changing the visibilty of a label

问题

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

}
英文:

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;
}
}
</details>
# 答案1
**得分**: 1
你的"魔法思维"有些问题。具体来说:
* 你基于一个布尔变量设置了组件的可见性。
* 你期望当布尔变量改变时,组件的可见性会神奇地改变 - 但组件并不知道这个变化已经发生,因此这肯定会失败。
要获得成功,你需要在监听器内部更改组件本身的可见性。换句话说,在*ActionListener*内部,你需要在感兴趣的组件上调用`.setVisible(true/false)`。
```java
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教程
  • 此外,与其切换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);
        });
    }
}
英文:

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(&quot;serial&quot;)
public class Notenbilanz3 extends JPanel {
private static final String LABEL_TEXT = &quot;Noten Anzahl&quot;;
private JLabel lblNote = new JLabel(LABEL_TEXT);
private JTextField txtField1 = new JTextField(10);
private JCheckBox checkBox = new JCheckBox(&quot;Check Box&quot;, 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 -&gt; {
String text = l.getStateChange() == ItemEvent.SELECTED ? LABEL_TEXT : &quot; &quot;;
lblNote.setText(text);
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(()-&gt; {
JFrame frame = new JFrame(&quot;Foo&quot;);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Notenbilanz3());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

huangapple
  • 本文由 发表于 2020年4月9日 06:47:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/61111251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定