简体   繁体   English

如何在 ActionListener 中使用 JLabel?

[英]How do I use JLabel in ActionListener?

I am trying to show a text saying "The background is (color)" whenever I press a button that has the name of the color written on it but the text doesn't show up.每当我按下一个写有颜色名称的按钮时,我都会尝试显示一个文本,上面写着“背景是(颜色)”,但文本没有显示。

How it is supposed to be:它应该是怎样的:我的教授上传的示例图片

but mine is like this:但我的是这样的:我的这段代码截图

Here is my code:这是我的代码:

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ThreeBtn extends JFrame {
    private JButton btnRed;
    private JButton btnGreen;
    private JButton btnBlue;
    
    
     public class ButtonListener implements ActionListener {
         
         public void actionPerformed (ActionEvent e) {
             if (e.getSource() == btnRed) {
                 (getContentPane()).setBackground(Color.red);
                 JLabel label = new JLabel("빨간색 배경입니다."); //it means "The background is red" in Korean               label.setFont(new Font("Serif", Font.BOLD, 25));
                 label.setForeground(Color.yellow);
                 (getContentPane()).add(label);
             }
             else if(e.getSource()==btnGreen) {
                 (getContentPane()).setBackground(Color.green);
                 JLabel label = new JLabel("초록색 배경입니다."); //it means "The background is green" in Korean
                 label.setFont(new Font("Serif", Font.BOLD, 25));
                 label.setForeground(Color.yellow);         
                 (getContentPane()).add(label);
             }
             else if(e.getSource()==btnBlue) {
                 (getContentPane()).setBackground(Color.blue);
                 JLabel label = new JLabel("파란색 배경입니다."); //it means "The background is blue" in Korean
                 label.setFont(new Font("Serif", Font.BOLD, 25));
                 label.setForeground(Color.yellow); 
                 (getContentPane()).add(label);
             }
         }
     }
     
     public ThreeBtn() {
         setSize(300, 200);
         setTitle("Three Button Example");
         setDefaultCloseOperation(EXIT_ON_CLOSE);
         
         Container cPane = getContentPane();
         cPane.setLayout(new FlowLayout());
         btnRed = new JButton("RED");
         btnGreen = new JButton("GREEN");
         btnBlue = new JButton("Blue");
         
         ButtonListener listener = new ButtonListener();
         btnRed.addActionListener(listener);
         btnGreen.addActionListener(listener);
         btnBlue.addActionListener(listener);
         
         cPane.add(btnRed);
         cPane.add(btnGreen);
         cPane.add(btnBlue);
         

     }
     
     public static void main(String[] args) {
         (new ThreeBtn()).setVisible(true);
     }
}

I am wondering if I used JLabel in a wrong way in the ActionListener but I can't figure it out.我想知道我是否在 ActionListener 中以错误的方式使用了 JLabel,但我无法弄清楚。

I would really appreciate your help.我将衷心感谢您的帮助。

When adding or deleting components to your GUI on runtime, you have to tell Swing that you did so.在运行时向 GUI 添加或删除组件时,您必须告诉 Swing 您这样做了。 To do this, you should use revalidate() and repaint() on the container where the modification happened.为此,您应该在发生修改的容器上使用revalidate()repaint()

However, in your case, you don't actually need to always add a new JLabel on runtime, as you can simply do that when setting up the GUI, and only modifying the label that is already there.但是,在您的情况下,您实际上并不需要总是在运行时添加新的JLabel ,因为您可以在设置 GUI 时简单地这样做,并且只修改已经存在的 label。 By doing it this way, you avoid having to revalidate() and repaint() (and it is also easier and cleaner this way).通过这种方式,您避免了revalidate()repaint() (而且这种方式也更容易和更清洁)。

I updated your code and did the following modificiations:我更新了您的代码并进行了以下修改:

  • Moved the declaration and initialization of the JLabel out of the actionPerformed() , so you don't have to create a new JLabel each time a button is pressed.JLabel的声明和初始化从actionPerformed()中移出,因此您不必在每次按下按钮时都创建新的JLabel Now, only the text is changed.现在,只更改了文本。 (A side effect of this change is, that the revalidate() and repaint() are actually not needed anymore, as no more component is added during runtime) (此更改的副作用是,实际上不再需要revalidate()repaint() ,因为在运行时不再添加组件)
  • Started the GUI on the Event Dispatch Thread via SwingUtilities.invokeLater() .通过SwingUtilities.invokeLater()事件调度线程上启动 GUI。
  • Usually it is also good practice in Swing to not create a subclass of JFrame if this is not specifically needed (like in your case).通常在 Swing 中,如果不是特别需要(如您的情况),不创建JFrame的子类也是一种很好的做法。 The better approach is to subclass JPanel , add the necessary components there, override getPreferredSize() and then add this to the JFrame .更好的方法是继承JPanel ,在那里添加必要的组件,覆盖getPreferredSize() ,然后将其添加到JFrame I have not included this change here, since it might have caused too much confusion.我没有在此处包含此更改,因为它可能会引起太多混乱。

Updated code:更新代码:

public class ThreeBtn extends JFrame {

    private JButton btnRed;
    private JButton btnGreen;
    private JButton btnBlue;
    private JLabel label;

    public class ButtonListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            Container contentPane = getContentPane();
            if (e.getSource() == btnRed) {
                contentPane.setBackground(Color.red);
                label.setText("red in korean");
            } else if (e.getSource() == btnGreen) {
                contentPane.setBackground(Color.green);
                label.setText("green in korean");
            } else if (e.getSource() == btnBlue) {
                contentPane.setBackground(Color.blue);
                label.setText("blue in korean");
            }
        }
    }

    public ThreeBtn() {
        setSize(300, 200);
        setTitle("Three Button Example");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container cPane = getContentPane();
        cPane.setLayout(new FlowLayout());
        btnRed = new JButton("RED");
        btnGreen = new JButton("GREEN");
        btnBlue = new JButton("BLUE");
        label = new JLabel("");
        label.setFont(new Font("Serif", Font.BOLD, 25));
        label.setForeground(Color.yellow);

        ButtonListener listener = new ButtonListener();
        btnRed.addActionListener(listener);
        btnGreen.addActionListener(listener);
        btnBlue.addActionListener(listener);

        cPane.add(btnRed);
        cPane.add(btnGreen);
        cPane.add(btnBlue);
        cPane.add(label);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> (new ThreeBtn()).setVisible(true));
    }
}

Output: Output:

在此处输入图像描述

This now works as per your requirements with the used FlowLayout .现在,这可以根据您使用的FlowLayout的要求工作。 However, you may use another layout manager (or combine different ones) if you plan on doing more with it.但是,如果您打算用它做更多事情,您可以使用另一个布局管理器(或组合不同的布局管理器)。

The Dimensions of the frame and panel where small so they did not show the text when you pressed the buttons.框架和面板的尺寸很小,因此当您按下按钮时它们不会显示文本。

Dimension size = label.getPreferredSize();尺寸大小 = label.getPreferredSize(); label.setBounds(150, 100, size.width, size.height); label.setBounds(150, 100, size.width, size.height);

I dont know if there are any rules for your program, but I would suggest, just limiting your if statements in ActionListener to the point where you set the foreground.我不知道您的程序是否有任何规则,但我建议您将 ActionListener 中的 if 语句限制在您设置前景的位置。 Then make your JLabel object a class variable, and add the JLabel in the constructor.然后将您的 JLabel object 设为 class 变量,并在构造函数中添加 JLabel。 Here is the full edited code:这是完整的编辑代码:


import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ThreeBtn extends JFrame {

    private static final long serialVersionUID = 1L;
    private JButton btnRed;
    private JButton btnGreen;
    private JButton btnBlue;
    private JLabel text = new JLabel();
    
    
     public class ButtonListener implements ActionListener {
         
         public void actionPerformed (ActionEvent e) {
             if (e.getSource() == btnRed) {
                 (getContentPane()).setBackground(Color.red);
                 text.setText("red"); //it means "The background is red" in Korean   
                 text.setFont(new Font("Serif", Font.BOLD, 25));
                 text.setForeground(Color.yellow);
             }
             else if(e.getSource()==btnGreen) {
                 (getContentPane()).setBackground(Color.green);
                 text.setText("green"); //it means "The background is green" in Korean
                 text.setFont(new Font("Serif", Font.BOLD, 25));
                 text.setForeground(Color.yellow);         
             }
             else if(e.getSource()==btnBlue) {
                 (getContentPane()).setBackground(Color.blue);
                 text.setText("blue"); //it means "The background is blue" in Korean
                 text.setFont(new Font("Serif", Font.BOLD, 25));
                 text.setForeground(Color.yellow); 
                 (getContentPane()).add(text);
             }
         }
     }
     
     public ThreeBtn() {
         setSize(300, 200);
         setTitle("Three Button Example");
         setDefaultCloseOperation(EXIT_ON_CLOSE);
         
         Container cPane = getContentPane();
         cPane.setLayout(new FlowLayout());
         btnRed = new JButton("RED");
         btnGreen = new JButton("GREEN");
         btnBlue = new JButton("Blue");
         
         ButtonListener listener = new ButtonListener();
         btnRed.addActionListener(listener);
         btnGreen.addActionListener(listener);
         btnBlue.addActionListener(listener);
         
         cPane.add(btnRed);
         cPane.add(btnGreen);
         cPane.add(btnBlue);
         cPane.add(text);
         

     }
     
     public static void main(String[] args) {
         (new ThreeBtn()).setVisible(true);
     }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM