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吗?”韩仔细看看答案,你们只需要一个