Java 如何在ActionListener中使用JLabel?

Java 如何在ActionListener中使用JLabel?,java,jframe,jlabel,Java,Jframe,Jlabel,每当我按下一个写有颜色名称的按钮时,我试图显示一条文字,上面写着“背景是(颜色)”,但文字没有显示出来 它应该是怎样的: 但我的是这样的: 这是我的密码: 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.ActionListene

每当我按下一个写有颜色名称的按钮时,我试图显示一条文字,上面写着“背景是(颜色)”,但文字没有显示出来

它应该是怎样的:

但我的是这样的:

这是我的密码:

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);
     }
}
我想知道我是否在ActionListener中以错误的方式使用了JLabel,但我无法理解


非常感谢您的帮助。

在运行时向GUI添加或删除组件时,您必须告诉Swing您这样做了。为此,应在发生修改的容器上使用
revalidate()
repaint()

但是,在您的情况下,实际上并不需要总是在运行时添加一个新的
JLabel
,因为您可以在设置GUI时简单地这样做,并且只修改已经存在的标签。通过这种方式,您可以避免
revalidate()
repaint()
(这种方式也更简单、更干净)

我更新了您的代码并进行了以下修改:

  • JLabel
    的声明和初始化从
    actionPerformed()
    中移出,因此您不必每次按下按钮时都创建一个新的
    JLabel
    。现在,只更改了文本。(此更改的一个副作用是,实际上不再需要
    revalidate()
    repaint()
    ,因为在运行时不再添加任何组件)
  • 在via
    SwingUtilities.invokeLater()上启动GUI
  • 通常,在Swing中,如果不需要创建
    JFrame
    的子类(如您的情况),那么不创建该子类也是一种很好的做法。更好的方法是子类化
    JPanel
    ,在那里添加必要的组件,重写
    getPreferredSize()
    ,然后将其添加到
    JFrame
    。我没有把这个变化包括在这里,因为它可能会引起太多的混乱
更新代码:

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));
    }
}
输出:


现在,使用所用的
FlowLayout
可根据您的要求进行操作。但是,如果您计划使用另一个布局管理器进行更多操作,则可以使用另一个布局管理器(或组合不同的布局管理器)。

在运行时向GUI添加或删除组件时,您必须告诉Swing您这样做了。为此,应在发生修改的容器上使用
revalidate()
repaint()

但是,在您的情况下,实际上并不需要总是在运行时添加一个新的
JLabel
,因为您可以在设置GUI时简单地这样做,并且只修改已经存在的标签。通过这种方式,您可以避免
revalidate()
repaint()
(这种方式也更简单、更干净)

我更新了您的代码并进行了以下修改:

  • JLabel
    的声明和初始化从
    actionPerformed()
    中移出,因此您不必每次按下按钮时都创建一个新的
    JLabel
    。现在,只更改了文本。(此更改的一个副作用是,实际上不再需要
    revalidate()
    repaint()
    ,因为在运行时不再添加任何组件)
  • 在via
    SwingUtilities.invokeLater()上启动GUI
  • 通常,在Swing中,如果不需要创建
    JFrame
    的子类(如您的情况),那么不创建该子类也是一种很好的做法。更好的方法是子类化
    JPanel
    ,在那里添加必要的组件,重写
    getPreferredSize()
    ,然后将其添加到
    JFrame
    。我没有把这个变化包括在这里,因为它可能会引起太多的混乱
更新代码:

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));
    }
}
输出:


现在,使用所用的
FlowLayout
可根据您的要求进行操作。但是,如果您打算使用另一个布局管理器做更多的工作,您可以使用它(或组合不同的布局管理器)。

我不知道您的程序是否有任何规则,但我建议,只将ActionListener中的if语句限制在您设置前景的位置。然后将JLabel对象设为类变量,并将JLabel添加到构造函数中。以下是完整的编辑代码:



我不知道您的程序是否有任何规则,但我建议您将ActionListener中的if语句限制在设置前台的位置。然后将JLabel对象设为类变量,并将JLabel添加到构造函数中。以下是完整的编辑代码:



框架和面板的尺寸很小,因此按下按钮时不会显示文本

维度大小=label.getPreferredSize();
标签.立根(150100,尺寸.宽度,尺寸.高度)

框架和面板的尺寸很小,因此按下按钮时不会显示文本

维度大小=label.getPreferredSize();
标签.立根(150100,尺寸.宽度,尺寸.高度)

如果在运行时向GUI添加新组件,则应在发生修改的父容器上使用
revalidate()
repaint()
。这将告诉swing,添加了一些新的内容,应该加以考虑。因此,如果在
actionPerformed()
方法的末尾添加
revalidate()
repaint()
,您将看到
JLabel
实际上被添加了。不过,您可能不得不考虑使用另一个布局管理器,因为<代码> FlowLayout < /C>不会在这里给出您想要的结果。因为您将看到,在当前布局中,
JLabel
s将不会被替换,而是始终添加到其他位置。现在我可以看到带有revalidate()的文本,但现在文本被堆叠在彼此的顶部,而不是被替换。“那个么我应该移除FlowLayot吗?”韩仔细看看答案,你们只需要一个