原文: http://zetcode.com/tutorials/javaswingtutorial/basicswingcomponents/

Swing 组件是应用的基本构建块。 Swing 具有广泛的各种组件,包括按钮,复选框,滑块和列表框。

Tweet

在 Swing 教程的这一部分中,我们将介绍JButtonJLabelJTextFieldJPasswordField

JButton

JButton正在实现按钮。 如果用户单击该动作,则用于触发该动作。

显示文字和图标

JButton可以显示文本,图标或两者。

ImageIconButtonEx.java

  1. package com.zetcode;
  2. import javax.swing.GroupLayout;
  3. import javax.swing.ImageIcon;
  4. import javax.swing.JButton;
  5. import javax.swing.JComponent;
  6. import javax.swing.JFrame;
  7. import java.awt.EventQueue;
  8. public class ImageIconButtonEx extends JFrame {
  9. public ImageIconButtonEx() {
  10. initUI();
  11. }
  12. private void initUI() {
  13. var saveIcon = new ImageIcon("src/resources/save.png");
  14. var homeIcon = new ImageIcon("src/resources/home.png");
  15. var quitBtn = new JButton("Quit");
  16. var saveBtn = new JButton(saveIcon);
  17. var homeBtn = new JButton("Home", homeIcon);
  18. createLayout(quitBtn, saveBtn, homeBtn);
  19. setTitle("JButtons");
  20. setLocationRelativeTo(null);
  21. setDefaultCloseOperation(EXIT_ON_CLOSE);
  22. }
  23. private void createLayout(JComponent... arg) {
  24. var pane = getContentPane();
  25. var gl = new GroupLayout(pane);
  26. pane.setLayout(gl);
  27. gl.setAutoCreateContainerGaps(true);
  28. gl.setAutoCreateGaps(true);
  29. gl.setHorizontalGroup(gl.createSequentialGroup()
  30. .addComponent(arg[0])
  31. .addComponent(arg[1])
  32. .addComponent(arg[2])
  33. );
  34. gl.setVerticalGroup(gl.createParallelGroup()
  35. .addComponent(arg[0])
  36. .addComponent(arg[1])
  37. .addComponent(arg[2])
  38. );
  39. gl.linkSize(arg[0], arg[1], arg[2]);
  40. pack();
  41. }
  42. public static void main(String[] args) {
  43. EventQueue.invokeLater(() -> {
  44. var ex = new ImageIconButtonEx();
  45. ex.setVisible(true);
  46. });
  47. }
  48. }

该示例显示了三个按钮:一个显示文本,一个显示图标,一个同时显示文本和图标。

  1. var saveIcon = new ImageIcon("src/main/resources/save.png");

许多组件可以用图标修饰。 为此,我们使用ImageIcon类。

  1. var quitBtn = new JButton("Quit");

JButton构造器将文本作为参数。

  1. var saveBtn = new JButton(saveIcon);

在此JButton构造器中,我们传递一个图标。

  1. JButton homeBtn = new JButton("Home", homeIcon);

此按钮显示文本和图标。

  1. gl.linkSize(arg[0], arg[1], arg[2]);

使用GroupLayoutlinkSize()方法,使按钮大小相同。

基本的 Swing 组件 - 图1

图:JButtons

带有助记符的JButton

助记符该键与外观的无鼠标修饰符(通常为 Alt)结合使用时,如果焦点位于该按钮的祖先窗口内的某个位置,它将激活该按钮。

ButtonMnemonicEx.java

  1. package com.zetcode;
  2. import javax.swing.GroupLayout;
  3. import javax.swing.JButton;
  4. import javax.swing.JComponent;
  5. import javax.swing.JFrame;
  6. import javax.swing.JOptionPane;
  7. import java.awt.EventQueue;
  8. import java.awt.event.ActionEvent;
  9. import java.awt.event.ActionListener;
  10. import java.awt.event.KeyEvent;
  11. public class ButtonMnemonicEx extends JFrame implements ActionListener {
  12. public ButtonMnemonicEx() {
  13. initUI();
  14. }
  15. private void initUI() {
  16. var showBtn = new JButton("Show");
  17. showBtn.addActionListener(this);
  18. showBtn.setMnemonic(KeyEvent.VK_S);
  19. createLayout(showBtn);
  20. setTitle("JButton");
  21. setLocationRelativeTo(null);
  22. setDefaultCloseOperation(EXIT_ON_CLOSE);
  23. }
  24. private void createLayout(JComponent... arg) {
  25. var pane = getContentPane();
  26. var gl = new GroupLayout(pane);
  27. pane.setLayout(gl);
  28. gl.setAutoCreateContainerGaps(true);
  29. gl.setAutoCreateGaps(true);
  30. gl.setHorizontalGroup(gl.createSequentialGroup()
  31. .addComponent(arg[0])
  32. .addGap(250)
  33. );
  34. gl.setVerticalGroup(gl.createParallelGroup()
  35. .addComponent(arg[0])
  36. .addGap(150)
  37. );
  38. pack();
  39. }
  40. @Override
  41. public void actionPerformed(ActionEvent e) {
  42. JOptionPane.showMessageDialog(this, "Button clicked",
  43. "Information", JOptionPane.INFORMATION_MESSAGE);
  44. }
  45. public static void main(String[] args) {
  46. EventQueue.invokeLater(() -> {
  47. var ex = new ButtonMnemonicEx();
  48. ex.setVisible(true);
  49. });
  50. }
  51. }

此示例中的按钮可以通过单击鼠标或 Alt + S 键盘快捷键来激活。

  1. public class ButtonMnemonicEx extends JFrame implements ActionListener

ButtonMnemonicEx类实现ActionListener; 它必须覆盖actionPerformed()方法,在该方法中,我们将激活按钮后执行的代码放入其中。

  1. var showBtn = new JButton("Show");
  2. showBtn.addActionListener(this);

创建一个新的JButton。 我们使用addActionListener()方法向按钮添加一个动作监听器。

  1. showBtn.setMnemonic(KeyEvent.VK_S);

setMnemonic()设置助记键; 带下划线的"S"字符。

  1. @Override
  2. public void actionPerformed(ActionEvent e) {
  3. JOptionPane.showMessageDialog(this, "Button clicked",
  4. "Information", JOptionPane.INFORMATION_MESSAGE);
  5. }

当通过单击鼠标或通过快捷方式激活按钮时,将显示带有JOptionPane.showMessageDialog()的消息对话框。

JLabel

JLabel是显示文本和/或图像的简单组件。 它不响应输入事件。

显示文字

以下示例显示文本。

LabelEx.java

  1. package com.zetcode;
  2. import javax.swing.GroupLayout;
  3. import javax.swing.JComponent;
  4. import javax.swing.JFrame;
  5. import javax.swing.JLabel;
  6. import java.awt.Color;
  7. import java.awt.EventQueue;
  8. import java.awt.Font;
  9. public class LabelEx extends JFrame {
  10. public LabelEx() {
  11. initUI();
  12. }
  13. private void initUI() {
  14. var lyrics = "<html>It's way too late to think of<br>" +
  15. "Someone I would call now<br>" +
  16. "And neon signs got tired<br>" +
  17. "Red eye flights help the stars out<br>" +
  18. "I'm safe in a corner<br>" +
  19. "Just hours before me<br>" +
  20. "<br>" +
  21. "I'm waking with the roaches<br>" +
  22. "The world has surrendered<br>" +
  23. "I'm dating ancient ghosts<br>" +
  24. "The ones I made friends with<br>" +
  25. "The comfort of fireflies<br>" +
  26. "Long gone before daylight<br>" +
  27. "<br>" +
  28. "And if I had one wishful field tonight<br>" +
  29. "I'd ask for the sun to never rise<br>" +
  30. "If God leant his voice for me to speak<br>" +
  31. "I'd say go to bed, world<br>" +
  32. "<br>" +
  33. "I've always been too late<br>" +
  34. "To see what's before me<br>" +
  35. "And I know nothing sweeter than<br>" +
  36. "Champaign from last New Years<br>" +
  37. "Sweet music in my ears<br>" +
  38. "And a night full of no fears<br>" +
  39. "<br>" +
  40. "But if I had one wishful field tonight<br>" +
  41. "I'd ask for the sun to never rise<br>" +
  42. "If God passed a mic to me to speak<br>" +
  43. "I'd say stay in bed, world<br>" +
  44. "Sleep in peace</html>";
  45. var label = new JLabel(lyrics);
  46. label.setFont(new Font("Serif", Font.PLAIN, 14));
  47. label.setForeground(new Color(50, 50, 25));
  48. createLayout(label);
  49. setTitle("No Sleep");
  50. setLocationRelativeTo(null);
  51. setDefaultCloseOperation(EXIT_ON_CLOSE);
  52. }
  53. private void createLayout(JComponent... arg) {
  54. var pane = getContentPane();
  55. var gl = new GroupLayout(pane);
  56. pane.setLayout(gl);
  57. gl.setAutoCreateContainerGaps(true);
  58. gl.setHorizontalGroup(gl.createSequentialGroup()
  59. .addComponent(arg[0])
  60. );
  61. gl.setVerticalGroup(gl.createParallelGroup()
  62. .addComponent(arg[0])
  63. );
  64. pack();
  65. }
  66. public static void main(String[] args) {
  67. EventQueue.invokeLater(() -> {
  68. var ex = new LabelEx();
  69. ex.setVisible(true);
  70. });
  71. }
  72. }

在我们的示例中,我们显示了 Cardigans 的歌曲的歌词。 我们可以在JLabel组件中使用 HTML 标签。 我们使用<br>标签来分隔行。

  1. var label = new JLabel(lyrics);
  2. label.setFont(new Font("Serif", Font.PLAIN, 14));

在这里,我们创建一个标签组件。 我们选择纯衬线字体并将其高度设置为 14px。

  1. pack();

pack()方法将调整窗口大小,以便标签组件以其首选大小显示。

基本的 Swing 组件 - 图2

图:JLabel

显示图标

JLabel可用于显示图像。

LabelEx2.java

  1. package com.zetcode;
  2. import javax.swing.GroupLayout;
  3. import javax.swing.ImageIcon;
  4. import javax.swing.JComponent;
  5. import javax.swing.JFrame;
  6. import javax.swing.JLabel;
  7. import java.awt.EventQueue;
  8. public class LabelEx2 extends JFrame {
  9. public LabelEx2() {
  10. initUI();
  11. }
  12. private void initUI() {
  13. var lbl1 = new JLabel(new ImageIcon("src/resources/cpu.png"));
  14. var lbl2 = new JLabel(new ImageIcon("src/resources/drive.png"));
  15. var lbl3 = new JLabel(new ImageIcon("src/resources/laptop.png"));
  16. var lbl4 = new JLabel(new ImageIcon("src/resources/player.png"));
  17. createLayout(lbl1, lbl2, lbl3, lbl4);
  18. setTitle("Icons");
  19. setLocationRelativeTo(null);
  20. setDefaultCloseOperation(EXIT_ON_CLOSE);
  21. }
  22. private void createLayout(JComponent... arg) {
  23. var pane = getContentPane();
  24. var gl = new GroupLayout(pane);
  25. pane.setLayout(gl);
  26. gl.setAutoCreateContainerGaps(true);
  27. gl.setAutoCreateGaps(true);
  28. gl.setHorizontalGroup(gl.createSequentialGroup()
  29. .addComponent(arg[0])
  30. .addComponent(arg[1])
  31. .addComponent(arg[2])
  32. .addComponent(arg[3])
  33. );
  34. gl.setVerticalGroup(gl.createParallelGroup()
  35. .addComponent(arg[0])
  36. .addComponent(arg[1])
  37. .addComponent(arg[2])
  38. .addComponent(arg[3])
  39. );
  40. pack();
  41. }
  42. public static void main(String[] args) {
  43. EventQueue.invokeLater(() -> {
  44. var ex = new LabelEx2();
  45. ex.setVisible(true);
  46. });
  47. }
  48. }

在示例中,我们使用JLabel组件显示四个图标。

  1. var lbl1 = new JLabel(new ImageIcon("src/main/resources/cpu.png"));

JLabelImageIcon作为参数。 图标是固定大小的图像。 ImageIcon从 GIF,JPEG 或 PNG 图像绘制图标。

基本的 Swing 组件 - 图3

图:显示图标

JTextField

JTextField是一个文本组件,允许编辑一行非格式化文本。

JTextFieldEx.java

  1. package com.zetcode;
  2. import javax.swing.GroupLayout;
  3. import javax.swing.JComponent;
  4. import javax.swing.JFrame;
  5. import javax.swing.JLabel;
  6. import javax.swing.JTextField;
  7. import javax.swing.event.DocumentEvent;
  8. import javax.swing.event.DocumentListener;
  9. import javax.swing.text.BadLocationException;
  10. import java.awt.EventQueue;
  11. import java.util.logging.Level;
  12. import java.util.logging.Logger;
  13. public class JTextFieldEx extends JFrame {
  14. private JLabel lbl;
  15. public JTextFieldEx() {
  16. initUI();
  17. }
  18. private void initUI() {
  19. var field = new JTextField(15);
  20. lbl = new JLabel();
  21. field.getDocument().addDocumentListener(new MyDocumentListener());
  22. createLayout(field, lbl);
  23. setTitle("JTextField");
  24. setLocationRelativeTo(null);
  25. setDefaultCloseOperation(EXIT_ON_CLOSE);
  26. }
  27. private class MyDocumentListener implements DocumentListener {
  28. private String text;
  29. @Override
  30. public void insertUpdate(DocumentEvent e) {
  31. updateLabel(e);
  32. }
  33. @Override
  34. public void removeUpdate(DocumentEvent e) {
  35. updateLabel(e);
  36. }
  37. @Override
  38. public void changedUpdate(DocumentEvent e) {
  39. }
  40. private void updateLabel(DocumentEvent e) {
  41. var doc = e.getDocument();
  42. int len = doc.getLength();
  43. try {
  44. text = doc.getText(0, len);
  45. } catch (BadLocationException ex) {
  46. Logger.getLogger(JTextFieldEx.class.getName()).log(
  47. Level.WARNING, "Bad location", ex);
  48. }
  49. lbl.setText(text);
  50. }
  51. }
  52. private void createLayout(JComponent... arg) {
  53. var pane = getContentPane();
  54. var gl = new GroupLayout(pane);
  55. pane.setLayout(gl);
  56. gl.setAutoCreateContainerGaps(true);
  57. gl.setAutoCreateGaps(true);
  58. gl.setHorizontalGroup(gl.createParallelGroup()
  59. .addComponent(arg[0])
  60. .addComponent(arg[1])
  61. .addGap(250)
  62. );
  63. gl.setVerticalGroup(gl.createSequentialGroup()
  64. .addComponent(arg[0], GroupLayout.DEFAULT_SIZE,
  65. GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
  66. .addComponent(arg[1])
  67. .addGap(150)
  68. );
  69. pack();
  70. }
  71. public static void main(String[] args) {
  72. EventQueue.invokeLater(() -> {
  73. var ex = new JTextFieldEx();
  74. ex.setVisible(true);
  75. });
  76. }
  77. }

在示例中,输入JTextField的文本立即显示在标签组件中。

  1. var field = new JTextField(15);

创建了新的JTextField。 该参数是列数。 请注意,此值不会设置字段中允许的字符数。 该值用于计算字段的首选宽度。

  1. field.getDocument().addDocumentListener(new MyDocumentListener());

我们将文档监听器添加到JTextFieldgetDocument()方法获取与编辑器关联的模型。 每个 Swing 组件都有一个模型,用于管理其状态或数据。

  1. @Override
  2. public void insertUpdate(DocumentEvent e) {
  3. updateLabel(e);
  4. }
  5. @Override
  6. public void removeUpdate(DocumentEvent e) {
  7. updateLabel(e);
  8. }

insertUpdate()removeUpdate()方法调用updateLabel()方法,该方法从文本字段复制文本并将其设置为标签组件。

  1. @Override
  2. public void changedUpdate(DocumentEvent e) {
  3. }

我们对changeUpdate()方法不感兴趣。 仅在样式化文档中生成此事件。

  1. private void updateLabel(DocumentEvent e) {
  2. var doc = e.getDocument();
  3. int len = doc.getLength();
  4. try {
  5. text = doc.getText(0, len);
  6. } catch (BadLocationException ex) {
  7. Logger.getLogger(JTextFieldEx.class.getName()).log(
  8. Level.WARNING, "Bad location", ex);
  9. }
  10. lbl.setText(text);
  11. }

文档事件的getDocument()方法用于获取正在观察的文本字段的文档。 我们使用文档的getLength()方法获得字符数。 该值用于通过文档的getText()方法复制文本。 最后,使用标签的setText()方法将文本设置为标签。

  1. gl.setVerticalGroup(gl.createSequentialGroup()
  2. .addComponent(arg[0], GroupLayout.DEFAULT_SIZE,
  3. GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
  4. .addComponent(arg[1])
  5. .addGap(150)
  6. );

我们不希望JTextField垂直生长; 因此,我们在垂直方向将其最大值设置为GroupLayout.PREFERRED_SIZE

基本的 Swing 组件 - 图4

图:JTextField

JPasswordField

JPasswordFieldJTextField子类,不显示用户键入的字符。

PasswordEx.java

  1. package com.zetcode;
  2. import javax.swing.AbstractAction;
  3. import javax.swing.GroupLayout;
  4. import javax.swing.JButton;
  5. import javax.swing.JFrame;
  6. import javax.swing.JLabel;
  7. import javax.swing.JPasswordField;
  8. import javax.swing.JTextField;
  9. import java.awt.Component;
  10. import java.awt.EventQueue;
  11. import java.awt.event.ActionEvent;
  12. import java.util.Arrays;
  13. import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED;
  14. public class PasswordEx extends JFrame {
  15. private JTextField loginField;
  16. private JPasswordField passField;
  17. public PasswordEx() {
  18. initUI();
  19. }
  20. private void initUI() {
  21. var lbl1 = new JLabel("Login");
  22. var lbl2 = new JLabel("Password");
  23. loginField = new JTextField(15);
  24. passField = new JPasswordField(15);
  25. var submitButton = new JButton("Submit");
  26. submitButton.addActionListener(new SubmitAction());
  27. createLayout(lbl1, loginField, lbl2, passField, submitButton);
  28. setTitle("Login");
  29. setLocationRelativeTo(null);
  30. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  31. }
  32. private class SubmitAction extends AbstractAction {
  33. @Override
  34. public void actionPerformed(ActionEvent e) {
  35. doSubmitAction();
  36. }
  37. private void doSubmitAction() {
  38. var login = loginField.getText();
  39. var passwd = passField.getPassword();
  40. if (!login.isEmpty() && passwd.length != 0) {
  41. System.out.format("User %s entered %s password%n",
  42. login, String.valueOf(passwd));
  43. }
  44. Arrays.fill(passwd, '0');
  45. }
  46. }
  47. private void createLayout(Component... arg) {
  48. var pane = getContentPane();
  49. var gl = new GroupLayout(pane);
  50. pane.setLayout(gl);
  51. gl.setAutoCreateGaps(true);
  52. gl.setAutoCreateContainerGaps(true);
  53. gl.setHorizontalGroup(gl.createSequentialGroup()
  54. .addGap(50)
  55. .addGroup(gl.createParallelGroup()
  56. .addComponent(arg[0])
  57. .addComponent(arg[1])
  58. .addComponent(arg[2])
  59. .addComponent(arg[3])
  60. .addComponent(arg[4]))
  61. .addGap(50)
  62. );
  63. gl.setVerticalGroup(gl.createSequentialGroup()
  64. .addGap(50)
  65. .addGroup(gl.createSequentialGroup()
  66. .addComponent(arg[0])
  67. .addComponent(arg[1], GroupLayout.DEFAULT_SIZE,
  68. GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
  69. .addComponent(arg[2])
  70. .addComponent(arg[3], GroupLayout.DEFAULT_SIZE,
  71. GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
  72. .addPreferredGap(UNRELATED)
  73. .addComponent(arg[4]))
  74. .addGap(50)
  75. );
  76. pack();
  77. }
  78. public static void main(String[] args) {
  79. EventQueue.invokeLater(() -> {
  80. var ex = new PasswordEx();
  81. ex.setVisible(true);
  82. });
  83. }
  84. }

该示例具有一个文本字段,一个密码字段和一个按钮。 该按钮将打印用户输入的数据。

  1. passField = new JPasswordField (15);

创建JPasswordField的实例。

  1. var passwd = passField.getPassword();

为了安全起见,密码字段将其值存储为字符数组而不是字符串。 字符数组由getPassword()方法返回。 不推荐使用较早的getText()方法。

  1. Arrays.fill(passwd , '0');

处理完密码后,建议将数组的元素设置为零。

基本的 Swing 组件 - 图5

图:JPasswordField

在 Java Swing 教程的这一部分中,我们介绍了基本的 Swing 组件,包括JButtonJLabelJTextFieldJPasswordField