JavaSwingGUI从小白到大神-3(javaswith)

deer332025-02-01技术文章61

背景

首先本文是一个系列的文章,起名为《Java Swing GUi从小白到大神》,主要介绍Java Swing相关概念和实践应用。目前JavaSwingGUI很少作为界面的开发框架,但是对于学习Java体系,以及新手将来学习后端之后,能快速从前后端整体去理解一套系统是非常有帮助的,所以是很有必要学习和掌握的。本篇是系列博文的第三篇,若想详细学习请点击首篇博文开始,让我们开始吧。

文章概览

  1. 如何使用选取器组件
  2. 如何使用文本组件
  3. 如何使用窗口、对话框和JApplet组件
  4. 如何使用菜单和工具条组件

8. 如何使用选取器组件

8.1 如何使用文件选取器
8.2 如何使用颜色选取器

  • addChoosableFileFilter(FileFilter),用于向JFileChooser中添加过滤器
  • setAcceptAllFileFilterUsed(boolean),用于启用或禁用所有文件过滤器
  • showOpenDialog(Component),显示文件对话框
  • showSaveDialog(Component),显示保存对话框
  • JFileChooser.APPROVE_OPTION,用于判断用户是否确认选择了文件

代码文件选取器

public class FileChooserExample {
    public static void main(String[] args) {
        // 创建 JFrame
        JFrame frame = new JFrame("Swing JFileChooser Example");
        frame.setSize(500, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        // 创建 JTextArea 用于显示和编辑文本内容
        JTextArea textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea);
        frame.add(scrollPane, BorderLayout.CENTER);

        // 创建面板放置按钮
        JPanel buttonPanel = new JPanel();
        JButton openFileButton = new JButton("打开文件");
        JButton saveFileButton = new JButton("存储文件");
        buttonPanel.add(openFileButton);
        buttonPanel.add(saveFileButton);
        frame.add(buttonPanel, BorderLayout.NORTH);

        // 创建 JFileChooser
        JFileChooser fileChooser = new JFileChooser();

        // 添加文件类型过滤器
        javax.swing.filechooser.FileFilter txtFileFilter = new javax.swing.filechooser.FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.isDirectory() || file.getName().endsWith(".txt");
            }

            @Override
            public String getDescription() {
                return "Text Files (*.txt)";
            }
        };

        // 设置文件过滤器
        fileChooser.addChoosableFileFilter(txtFileFilter); // 文件过滤器限制用户可以看到的文件类型
        fileChooser.setAcceptAllFileFilterUsed(true); // 设置是否显示所有文件类型(包括不显示的)
        fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter()); // 设置默认文件过滤器

        // 打开文件按钮功能
        openFileButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int returnValue = fileChooser.showOpenDialog(frame); // 打开文件对话框
                if (returnValue == JFileChooser.APPROVE_OPTION) { // 如果用户选择了一个文件
                    File selectedFile = fileChooser.getSelectedFile();
                    if (selectedFile.getName().endsWith(".txt")) {
                        try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) {
                            textArea.setText("");
                            String line;
                            while ((line = reader.readLine()) != null) {
                                textArea.append(line + "\n");
                            }
                        } catch (IOException ex) {
                            JOptionPane.showMessageDialog(frame, "无法读取文件: " + ex.getMessage(),
                                    "错误", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        JOptionPane.showMessageDialog(frame, "请选择一个 .txt 文件", "错误", JOptionPane.WARNING_MESSAGE);
                    }
                }
            }
        });

        // 保存文件按钮功能
        saveFileButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int returnValue = fileChooser.showSaveDialog(frame); // 显示保存文件对话框
                if (returnValue == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    // 如果文件没有 .txt 扩展名,自动添加
                    if (!selectedFile.getName().endsWith(".txt")) {
                        selectedFile = new File(selectedFile.getAbsolutePath() + ".txt");
                    }
                    try (BufferedWriter writer = new BufferedWriter(new FileWriter(selectedFile))) {
                        writer.write(textArea.getText());
                        JOptionPane.showMessageDialog(frame, "文件保存成功", "提示", JOptionPane.INFORMATION_MESSAGE);
                    } catch (IOException ex) {
                        JOptionPane.showMessageDialog(frame, "无法保存文件: " + ex.getMessage(),
                                "错误", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }
        });

        // 显示窗口
        frame.setVisible(true);
    }
}

代码颜色选择器

public class ColorChooserExample {
    public static void main(String[] args) {
        // 创建主窗口
        JFrame frame = new JFrame("Color Chooser Example");
        frame.setSize(700, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        // 创建按钮
        JButton getColorButton = new JButton("Get Color");
        JButton rgbButton = new JButton("RGB: (0, 0, 0)");
        JButton redButton = new JButton("Red: 0");
        JButton greenButton = new JButton("Green: 0");
        JButton blueButton = new JButton("Blue: 0");

        // 调整按钮字体
        Font buttonFont = new Font("Arial", Font.PLAIN, 12);
        getColorButton.setFont(buttonFont);
        rgbButton.setFont(buttonFont);
        redButton.setFont(buttonFont);
        greenButton.setFont(buttonFont);
        blueButton.setFont(buttonFont);

        // 创建面板放置按钮,并设置边距
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 5, 10, 0)); // 按钮之间的水平间隔为 10 像素
        buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); // 面板的内边距

        buttonPanel.add(getColorButton);
        buttonPanel.add(rgbButton);
        buttonPanel.add(redButton);
        buttonPanel.add(greenButton);
        buttonPanel.add(blueButton);

        // 添加按钮面板到顶部
        frame.add(buttonPanel, BorderLayout.NORTH);

        // 设置默认背景颜色
        Color[] currentColor = { Color.WHITE };
        frame.getContentPane().setBackground(currentColor[0]);

        // "Get Color" 按钮功能
        getColorButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 弹出颜色选择器
                Color selectedColor = JColorChooser.showDialog(frame, "Choose a Color", currentColor[0]);
                if (selectedColor != null) {
                    // 更新窗口背景颜色
                    currentColor[0] = selectedColor;
                    frame.getContentPane().setBackground(selectedColor);

                    // 更新按钮显示值
                    int red = selectedColor.getRed();
                    int green = selectedColor.getGreen();
                    int blue = selectedColor.getBlue();
                    rgbButton.setText("RGB:" + red + green + blue);
                    redButton.setText("Red: " + red);
                    greenButton.setText("Green: " + green);
                    blueButton.setText("Blue: " + blue);
                }
            }
        });

        // 显示窗口
        frame.setVisible(true);
    }
}

9. 如何使用文本组件

9.1 如何使用普通文本框组件

  • insertString 方法,用于处理文本插入操作,例如限制文本长度等。
  • replace 方法,用于处理文本替换操作,例如限制替换后的文本总长度。

代码如何使用文本组件

public class LoginWindowExample {
    private static JFormattedTextField dateField;
    private static JFormattedTextField timeField;

    public static void main(String[] args) {
        // 创建主窗口
        JFrame frame = new JFrame("Login Window");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setLayout(new java.awt.GridBagLayout()); // 使用 GridBagLayout 实现居中布局
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10); // 设置组件间的间距
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 用户名标签和文本框
        JLabel usernameLabel = new JLabel("用户:");
        JTextField usernameField = new JTextField(18);
        usernameField.setHorizontalAlignment(SwingConstants.CENTER); // 文本居中
        PlainDocument usernameDoc = new PlainDocument();
        usernameDoc.setDocumentFilter(new DocumentFilter() {
            @Override
            public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) // 限制输入框的最大长度为15
                    throws BadLocationException {
                if ((fb.getDocument().getLength() + string.length()) <= 15) {
                    super.insertString(fb, offset, string, attr);
                }
            }

            @Override
            public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) // 限制替换后的文本总长度为15
                    throws BadLocationException {
                if ((fb.getDocument().getLength() - length + (text != null ? text.length() : 0)) <= 15) {
                    super.replace(fb, offset, length, text, attrs);
                }
            }
        });
        usernameField.setDocument(usernameDoc);

        // 密码标签和密码框
        JLabel passwordLabel = new JLabel("密码:");
        JPasswordField passwordField = new JPasswordField();
        passwordField.setHorizontalAlignment(SwingConstants.CENTER); // 文本居中

        // 日期和时间格式化文本框
        JLabel dateLabel = new JLabel("Date (yyyy-MM-dd):");

        try {
            MaskFormatter dateFormatter = new MaskFormatter("####-##-##");
            dateFormatter.setPlaceholderCharacter('_'); // 设置占位符
            dateField = new JFormattedTextField(dateFormatter);
            dateField.setHorizontalAlignment(SwingConstants.CENTER); // 文本居中
        } catch (ParseException e) {
            e.printStackTrace();
        }

        JLabel timeLabel = new JLabel("Time (HH:mm:ss):");

        try {
            MaskFormatter timeFormatter = new MaskFormatter("##:##:##");
            timeFormatter.setPlaceholderCharacter('_');
            timeField = new JFormattedTextField(timeFormatter);
            timeField.setHorizontalAlignment(SwingConstants.CENTER); // 文本居中
        } catch (ParseException e) {
            e.printStackTrace();
        }

        // 登录按钮
        JButton loginButton = new JButton("Login");
        loginButton.addActionListener(e -> {
            String username = usernameField.getText();
            String password = new String(passwordField.getPassword());
            String date = dateField.getText();
            String time = timeField.getText();

            JOptionPane.showMessageDialog(frame,
                    "Username: " + username + "\nPassword: " + password +
                            "\nDate: " + date + "\nTime: " + time,
                    "Login Info", JOptionPane.INFORMATION_MESSAGE);
        });

        // 添加组件到窗口,设置布局约束
        gbc.gridx = 0;
        gbc.gridy = 0;
        frame.add(usernameLabel, gbc);

        gbc.gridx = 1;
        frame.add(usernameField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        frame.add(passwordLabel, gbc);

        gbc.gridx = 1;
        frame.add(passwordField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 2;
        frame.add(dateLabel, gbc);

        gbc.gridx = 1;
        frame.add(dateField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 3;
        frame.add(timeLabel, gbc);

        gbc.gridx = 1;
        frame.add(timeField, gbc);

        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.gridwidth = 2;
        frame.add(loginButton, gbc);

        // 显示窗口
        frame.setVisible(true);
    }
}

9.2 如何使用多行文本区组件

9.2.1 JTextArea组件拷贝粘贴剪切功能

  • JTextArea.copy(),多行文本区复制方法
  • JTextArea.paste(),多行文本区粘贴方法
  • JTextArea.cut(),多行文本区剪切方法

JTextArea使用多行文本区组件

public class TextComponentDemo {
    public static void main(String[] args) {
        // 创建主窗口
        JFrame frame = new JFrame("Text Components Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 400);
        frame.setLayout(new BorderLayout());

        // 创建 JTextArea
        JTextArea textArea = new JTextArea("This is a JTextArea. You can edit text here.");
        JScrollPane textAreaScroll = new JScrollPane(textArea);

        // 创建按钮
        JPanel buttonPanel = new JPanel(new FlowLayout());
        JButton copyButton = new JButton("Copy");
        JButton pasteButton = new JButton("Paste");
        JButton cutButton = new JButton("Cut");

        buttonPanel.add(copyButton);
        buttonPanel.add(pasteButton);
        buttonPanel.add(cutButton);

        copyButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == copyButton) {
                    textArea.copy(); // 复制选中的文本
                }
            }
        });

        pasteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == pasteButton) {
                    textArea.paste(); // 粘贴剪贴板中的文本
                }
            }
        });

        cutButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == cutButton) {
                    textArea.cut(); // 剪切选中的文本到剪贴板
                }
            }
        });

        frame.add(textAreaScroll, BorderLayout.CENTER);
        frame.add(buttonPanel, BorderLayout.SOUTH);
        frame.setVisible(true);
    }
}

9.2.2 JTextArea组件撤销重做功能

  • JTextArea.getDocument().addUndoableEditListener(undoManager),多行文本区撤销、重做功能undoManager.undo()undoManager.redo()
  • JTextArea.getDocument().addDocumentListener(new DocumentListener() {}),多行文本区文本监听器

代码多行文本区撤销、重做功能、文本监听器

public class UndoRedoEditorDemo {
    public static void main(String[] args) {
        // 创建主窗口
        JFrame frame = new JFrame("Undo/Redo Editor Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 400);
        frame.setLayout(new BorderLayout());

        // 创建文本区域和日志区域
        JTextArea editorTextArea = new JTextArea();
        JTextArea eventLogArea = new JTextArea();
        eventLogArea.setEditable(false);

        // 创建滚动面板
        JScrollPane editorScrollPane = new JScrollPane(editorTextArea);
        JScrollPane logScrollPane = new JScrollPane(eventLogArea);

        // 设置上下分布
        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, editorScrollPane, logScrollPane);
        splitPane.setDividerLocation(200);
        frame.add(splitPane, BorderLayout.CENTER);

        // 创建菜单栏
        JMenuBar menuBar = new JMenuBar();
        JMenu editMenu = new JMenu("Edit");
        JMenuItem undoMenuItem = new JMenuItem("Undo");
        JMenuItem redoMenuItem = new JMenuItem("Redo");
        editMenu.add(undoMenuItem);
        editMenu.add(redoMenuItem);
        menuBar.add(editMenu);
        frame.setJMenuBar(menuBar);

        // 添加撤销和重写功能
        UndoManager undoManager = new UndoManager();
        editorTextArea.getDocument().addUndoableEditListener(undoManager);

        // 添加撤销功能
        undoMenuItem.addActionListener(e -> {
            if (undoManager.canUndo()) {
                try {
                    undoManager.undo();
                } catch (CannotUndoException ex) {
                    JOptionPane.showMessageDialog(frame, "Cannot undo!", "Error", JOptionPane.ERROR_MESSAGE);
                }
            } else {
                JOptionPane.showMessageDialog(frame, "No actions to undo.", "Info", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        // 添加重写功能
        redoMenuItem.addActionListener(e -> {
            if (undoManager.canRedo()) {
                try {
                    undoManager.redo();
                } catch (CannotRedoException ex) {
                    JOptionPane.showMessageDialog(frame, "Cannot redo!", "Error", JOptionPane.ERROR_MESSAGE);
                }
            } else {
                JOptionPane.showMessageDialog(frame, "No actions to redo.", "Info", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        // 添加文档监听器
        editorTextArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                logEvent("Text inserted.");
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                logEvent("Text removed.");
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                logEvent("Document properties changed.");
            }

            private void logEvent(String message) {
                eventLogArea.append(message + "\n");
                eventLogArea.setCaretPosition(eventLogArea.getDocument().getLength());
            }
        });

        // 添加窗口事件监听器
        frame.addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
                logEvent("Window opened.");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                logEvent("Window closing.");
            }

            @Override
            public void windowClosed(WindowEvent e) {
                logEvent("Window closed.");
            }

            @Override
            public void windowIconified(WindowEvent e) {
                logEvent("Window minimized.");
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                logEvent("Window restored.");
            }

            @Override
            public void windowActivated(WindowEvent e) {
                logEvent("Window activated.");
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                logEvent("Window deactivated.");
            }

            private void logEvent(String message) {
                eventLogArea.append(message + "\n");
                eventLogArea.setCaretPosition(eventLogArea.getDocument().getLength());
            }
        });

        // 显示窗口
        frame.setVisible(true);
    }
}

9.2.3 JTextArea组件字体属性设置、段落格式设置

  • 类SimpleAttributeSet 用于表示一组样式属性(如字体样式、颜色、大小等)。是 AttributeSet 接口的一个简单实现。
  • 类StyleConstants 是用于管理文本和段落样式的工具类。StyleConstants 通过内部接口 CharacterConstants 和 ParagraphConstants 分别管理文本样式和段落样式。设置文本样式(字体、颜色、大小、加粗、斜体等)。设置段落样式(段落对齐方式左、中、右对齐等)。

示例:设置字体样式

SimpleAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setFontFamily(attr, "Arial");   // 设置字体
StyleConstants.setFontSize(attr, 18);         // 设置字体大小
StyleConstants.setBold(attr, true);           // 加粗
StyleConstants.setForeground(attr, Color.RED); // 设置前景色(字体颜色)
StyledDocument doc = textPane.getStyledDocument();
doc.setCharacterAttributes(0, 4, attr, false); // 为 "This" 设置样式

示例:设置段落样式

SimpleAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setAlignment(attr, StyleConstants.ALIGN_CENTER); // 居中对齐
StyleConstants.setLineSpacing(attr, 1.5f);                     // 行间距
StyleConstants.setFirstLineIndent(attr, 20);                   // 首行缩进
StyleConstants.setSpaceAbove(attr, 10);                        // 段前间距
StyleConstants.setSpaceBelow(attr, 10);                        // 段后间距
StyledDocument doc = textPane.getStyledDocument();
doc.setParagraphAttributes(0, doc.getLength(), attr, false);

代码JTextArea组件字体属性设置、段落格式设置

public class EditorPaneTextPaneDemo {
    public static void main(String[] args) {
        // 创建主窗口
        JFrame frame = new JFrame("JEditorPane and JTextPane Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setLayout(new BorderLayout());

        // 创建 JEditorPane
        JEditorPane editorPane = new JEditorPane();
        editorPane.setContentType("text/plain"); // 默认纯文本
        editorPane.setText("This is a JEditorPane.\nChange the content type using the menu.");
        editorPane.setEditable(true);
        JScrollPane editorScrollPane = new JScrollPane(editorPane);

        // 创建 JTextPane
        JTextPane textPane = new JTextPane();
        textPane.setEditable(true);
        JScrollPane textPaneScrollPane = new JScrollPane(textPane);

        // 创建顶部菜单栏
        JMenuBar menuBar = new JMenuBar();

        // JEditorPane 的内容类型菜单
        JMenu editorMenu = new JMenu("JEditorPane Content Type");
        JMenuItem plainTextMenuItem = new JMenuItem("Load Plain Text");
        JMenuItem htmlTextMenuItem = new JMenuItem("Load HTML");
        JMenuItem rtfTextMenuItem = new JMenuItem("Load RTF");

        // 设置 plain 文本内容
        plainTextMenuItem.addActionListener(e -> {
            editorPane.setContentType("text/plain");
            editorPane.setText("This is plain text in JEditorPane.");
        });

        // 设置 HTML 内容
        htmlTextMenuItem.addActionListener(e -> {
            editorPane.setContentType("text/html");
            editorPane.setText(
                    "

HTML Content

This is an example of HTML in JEditorPane.

"); }); // EditorPane 的 text/rtf 类型原生支持有限,因此需要额外的 RTF 解析器来正确加载, // javax.swing.text.rtf.RTFEditorKit,它可以解析简单的 // RTF 文本格式 // \\b 和 \\b0 表示加粗开启和关闭。 \\i 和 \\i0 表示斜体开启和关闭。 rtfTextMenuItem.addActionListener(e -> { try { editorPane.setContentType("text/rtf"); editorPane.setEditorKit(new javax.swing.text.rtf.RTFEditorKit()); editorPane.setText("{\\rtf1\\ansi\\deff0 {\\fonttbl {\\f0 Courier;}}\n" + "\\f0\\fs24 This is RTF content loaded in JEditorPane.\n" + "\\b Bold Text \\b0 and \\i Italic Text\\i0.\n}"); } catch (Exception ex) { editorPane.setContentType("text/plain"); editorPane.setText("Error loading RTF content.\n" + ex.getMessage()); } }); editorMenu.add(plainTextMenuItem); editorMenu.add(htmlTextMenuItem); editorMenu.add(rtfTextMenuItem); // JTextPane 的样式菜单 JMenu textPaneMenu = new JMenu("JTextPane Styles"); JMenuItem boldMenuItem = new JMenuItem("Bold"); JMenuItem italicMenuItem = new JMenuItem("Italic"); JMenuItem colorMenuItem = new JMenuItem("Change Color"); // 设置加粗样式 boldMenuItem.addActionListener(e -> applyStyle(textPane, StyleConstants.CharacterConstants.Bold, true)); // 设置斜体样式 italicMenuItem.addActionListener(e -> applyStyle(textPane, StyleConstants.CharacterConstants.Italic, true)); // 设置颜色样式 colorMenuItem.addActionListener(e -> { Color color = JColorChooser.showDialog(frame, "Choose Text Color", Color.BLACK); if (color != null) { applyStyle(textPane, StyleConstants.Foreground, color); } }); textPaneMenu.add(boldMenuItem); textPaneMenu.add(italicMenuItem); textPaneMenu.add(colorMenuItem); // 添加菜单到菜单栏 menuBar.add(editorMenu); menuBar.add(textPaneMenu); // 设置菜单栏 frame.setJMenuBar(menuBar); // 分上下两部分展示 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, editorScrollPane, textPaneScrollPane); splitPane.setDividerLocation(300); frame.add(splitPane, BorderLayout.CENTER); // 显示窗口 frame.setVisible(true); } // 应用样式到 JTextPane private static void applyStyle(JTextPane textPane, Object styleKey, Object styleValue) { StyledDocument doc = textPane.getStyledDocument(); int start = textPane.getSelectionStart(); int end = textPane.getSelectionEnd(); if (start == end) { // 如果没有选中文本,则设置当前输入点样式 SimpleAttributeSet attrs = new SimpleAttributeSet(); StyleConstants.setBold(attrs, Boolean.TRUE.equals(styleKey == StyleConstants.CharacterConstants.Bold)); StyleConstants.setItalic(attrs, Boolean.TRUE.equals(styleKey == StyleConstants.CharacterConstants.Italic)); if (styleKey == StyleConstants.Foreground) { StyleConstants.setForeground(attrs, (Color) styleValue); } textPane.setCharacterAttributes(attrs, false); } else { // 设置选中文本样式 SimpleAttributeSet attrs = new SimpleAttributeSet(); attrs.addAttribute(styleKey, styleValue); doc.setCharacterAttributes(start, end - start, attrs, false); } } }

9.3 如何打印文本组件

代码JTextArea组件打印文本功能

public class JTextAreaPrintDemo {
    public static void main(String[] args) {
        // 创建主窗口
        JFrame frame = new JFrame("JTextArea 打印测试窗口");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);

        // 创建 JTextArea 和 JScrollPane
        JTextArea textArea = new JTextArea();
        textArea.setLineWrap(true); // 自动换行
        textArea.setWrapStyleWord(true); // 按单词换行

        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); // 垂直滚动条随内容变化而变化

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JButton printButton = new JButton("打印内容");
        JButton clearButton = new JButton("清除内容");

        // 添加按钮事件
        printButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    boolean isPrinted = textArea.print(); // 调用系统打印
                    if (isPrinted) {
                        JOptionPane.showMessageDialog(frame, "打印成功!", "信息", JOptionPane.INFORMATION_MESSAGE);
                    } else {
                        JOptionPane.showMessageDialog(frame, "打印取消!", "提示", JOptionPane.WARNING_MESSAGE);
                    }
                } catch (PrinterException ex) {
                    JOptionPane.showMessageDialog(frame, "打印失败: " + ex.getMessage(), "错误",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.setText(""); // 清空内容
            }
        });

        buttonPanel.add(printButton);
        buttonPanel.add(clearButton);

        // 添加组件到主窗口
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.add(buttonPanel, BorderLayout.SOUTH);

        // 显示窗口
        frame.setVisible(true);
    }
}

10. 如何使用窗口、对话框和JApplet组件

10.1 如何使用窗口组件

  • Toolkit 是 Java GUI 开发中一个重要的工具类,主要用于获取屏幕信息、管理系统剪贴板、加载资源以及其他与操作系统交互的功能。它为跨平台应用程序提供了统一的接口,使得开发者能够轻松访问底层系统资源。获取屏幕信息getScreenSize(),返回屏幕的分辨率(单位:像素)。例如:toolkit.getScreenSize();screenSize.width;screenSize.heightgetScreenResolution(),返回屏幕的分辨率(单位:DPI,每英寸像素数)。例如:int resolution = toolkit.getScreenResolution();getSystemClipboard(),返回系统剪贴板的引用,用于剪切、复制和粘贴操作。例如:Clipboard clipboard = toolkit.getSystemClipboard();getImage(String filename) 或 getImage(URL url),从文件或 URL 加载图像。例如:Image image = toolkit.getImage("path/to/image.png");

代码JFrame示例

public class JFrameDemo {
    private static final int WIDTH = 700;
    private static final int HEIGHT = 500;

    public static void main(String[] args) {
        JFrame frame = new JFrame("纺织厂职工管理系统");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, HEIGHT);

        JPanel panel = new JPanel();
        panel.setLayout(new java.awt.GridBagLayout());
        frame.setContentPane(panel);

        JLabel label1 = new JLabel("职工信息窗口查询");
        JLabel label2 = new JLabel("按照职工名字查询");
        JLabel label3 = new JLabel("按照职工工号查询");

        JTextField textField1 = new JTextField(15);
        JTextField textField2 = new JTextField(15);

        JButton button1 = new JButton("查询");
        JButton button2 = new JButton("查询");

        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Dimension dimension = toolkit.getScreenSize();
        frame.setLocation(dimension.width / 2 - WIDTH / 2, dimension.height / 2 - HEIGHT / 2);

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.NONE;
        constraints.weightx = 3.0;
        constraints.weighty = 3.0;

        addComponent(panel, label1, constraints, 0, 0, 6, 1);
        addComponent(panel, label2, constraints, 0, 1, 1, 1);
        addComponent(panel, label3, constraints, 0, 2, 1, 1);
        addComponent(panel, textField1, constraints, 1, 1, 1, 1);
        addComponent(panel, textField2, constraints, 1, 2, 1, 1);
        addComponent(panel, button1, constraints, 3, 1, 1, 1);
        addComponent(panel, button2, constraints, 3, 2, 1, 1);

        frame.setVisible(true);
    }

    public static void addComponent(Container container, Component component, GridBagConstraints constraints, int x,
            int y,
            int width, int height) {
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        container.add(component, constraints);
    }
}

10.2 如何使用对话框组件

  • JOptionPane 类介绍,便捷类,用于显示标准对话框,如消息提示、确认、输入对话框等。JOptionPane.showMessageDialog() 方法,用于显示消息对话框。JOptionPane.showConfirmDialog() 方法,用于显示确认对话框。JOptionPane.showInputDialog() 方法,用于显示输入对话框。JOptionPane.showOptionDialog() 方法,用于显示选项对话框。

代码Dialog对话框示例

public class JDialogExample {
    private static final int WIDTH = 400;
    private static final int HEIGHT = 300;

    public static void main(String[] args) {
        JFrame frame = new JFrame("JDialog测试程序");
        frame.setSize(WIDTH, HEIGHT);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setLayout(new java.awt.FlowLayout());
        frame.setContentPane(panel);

        JButton button1 = new JButton("showMessageDialog");
        JButton button2 = new JButton("showConfirmDialog");
        JButton button3 = new JButton("showOptionDialog");
        JButton button4 = new JButton("showInputDialog");

        panel.add(button1);
        panel.add(button2);
        panel.add(button3);
        panel.add(button4);

        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(frame, "这是一个消息对话框", "消息", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showConfirmDialog(frame, "确认对话框", "这是一个Confirm消息框",
                        JOptionPane.YES_NO_CANCEL_OPTION);
            }
        });

        button3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object[] options = { "OK", "CANCEL" };
                JOptionPane.showOptionDialog(frame, "点击ok按钮继续", "警告", JOptionPane.DEFAULT_OPTION,
                        JOptionPane.WARNING_MESSAGE, null, options, options[0]);
            }
        });

        button4.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object[] options = { "第一", "第二", "第三" };
                Object inuser = JOptionPane.showInputDialog(frame, "请选择第一个", "输入", JOptionPane.INFORMATION_MESSAGE,
                        new ImageIcon("blue.gif"), options, options[0]);

                if (inuser == null) {
                    JOptionPane.showMessageDialog(frame, "您没有选择任何选项!", "提示", JOptionPane.WARNING_MESSAGE);
                } else if (inuser.equals("第一")) {
                    System.out.println("第一");
                } else if (inuser.equals("第二")) {
                    System.out.println("第二");
                } else if (inuser.equals("第三")) {
                    System.out.println("第三");
                }
            }
        });

        frame.setVisible(true);
    }
}

10.3 如何使用JApplet组件
Applet 技术在 Java 9 中被废弃,且主流浏览器已停止支持。若没有老代码需要维护,初学者没有必要了解JApplet组件。

代码如何使用JApplet组件

public class SimpleAppletExample extends JApplet {
    private JLabel label;
    private JButton button;
    private JTextField textField;

    @Override
    public void init() {
        // 初始化 Applet
        setLayout(new BorderLayout());

        // 上方展示一段欢迎文字
        label = new JLabel("欢迎使用 JApplet 示例!", JLabel.CENTER);
        label.setBorder(new EmptyBorder(20, 10, 20, 10)); // 设置边框
        label.setFont(new Font("宋体", Font.BOLD, 18)); // 设置支持中文的字体
        add(label, BorderLayout.NORTH);

        // 中部放置一个输入框和按钮
        JPanel centerPanel = new JPanel(new FlowLayout());
        textField = new JTextField(15);
        button = new JButton("点击显示输入");
        centerPanel.add(new JLabel("输入内容:"));
        centerPanel.add(textField);
        centerPanel.add(button);
        add(centerPanel, BorderLayout.CENTER);

        // 设置按钮事件
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String input = textField.getText();
                label.setText("您输入的内容是: " + input);
            }
        });

        // 在底部绘制一个简单的形状
        add(new DrawPanel(), BorderLayout.SOUTH);
    }

    @Override
    public void start() {
        System.out.println("Applet 已启动");
    }

    @Override
    public void stop() {
        System.out.println("Applet 已停止");
    }

    @Override
    public void destroy() {
        System.out.println("Applet 已销毁");
    }

    // 自定义绘图面板类
    class DrawPanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLUE);
            g.fillOval(10, 10, 50, 50); // 绘制一个蓝色圆形
            g.setColor(Color.RED);
            g.drawString("绘图区域", 70, 35); // 添加文字
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 60);
        }
    }

    // 添加 main 方法支持直接运行
    public static void main(String[] args) {
        // 创建一个 JFrame 容器
        JFrame frame = new JFrame("JApplet 示例");
        SimpleAppletExample applet = new SimpleAppletExample();

        // 调用 Applet 生命周期方法
        applet.init(); // 初始化 Applet
        applet.start(); // 启动 Applet

        // 将 Applet 添加到 JFrame 中
        frame.add(applet);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setVisible(true);
    }
}

11. 如何使用菜单和工具条组件

11.1 如何使用菜单组件
11.2 如何使用工具条组件

代码如何使用菜单和工具条组件

public class JMenuBarExample {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;

    public static void main(String[] args) {
        JFrame frame = new JFrame("星火纺织厂信息系统");
        frame.setSize(WIDTH, HEIGHT);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建菜单栏
        JMenuBar menuBar = createMenuBar(frame);
        frame.setJMenuBar(menuBar);

        // 创建工具栏
        JToolBar toolBar = new JToolBar();
        JButton btn1 = new JButton("磨砂分厂职工信息");
        btn1.addActionListener(e -> showTabbedPaneDialog(frame));
        JButton btn2 = new JButton("纺纱分厂工资信息");
        btn2.addActionListener(e -> JOptionPane.showMessageDialog(frame, "纺纱分厂工资信息功能未实现"));
        JButton btn3 = new JButton("人事部职工信息");
        btn3.addActionListener(e -> JOptionPane.showMessageDialog(frame, "人事部职工信息功能未实现"));

        toolBar.add(btn1);
        toolBar.add(btn2);
        toolBar.add(btn3);

        // 添加工具栏到窗口顶部
        frame.add(toolBar, BorderLayout.NORTH);

        // 添加右键菜单
        JPopupMenu popupMenu = createPopupMenu(frame);
        frame.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent e) {
                if (e.isPopupTrigger()) {
                    popupMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        });

        // 窗口居中
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Dimension screenSize = toolkit.getScreenSize();
        frame.setLocation(screenSize.width / 2 - WIDTH / 2, screenSize.height / 2 - HEIGHT / 2);

        frame.setVisible(true);
    }

    private static JMenuBar createMenuBar(JFrame frame) {
        JMenuBar menuBar = new JMenuBar();

        // 职工信息系统菜单
        JMenu menu1 = createMenu("职工信息系统", 'Z',
                createMenuItem("磨砂分厂职工信息", 'M', e -> showTabbedPaneDialog(frame)),
                createMenuItem("纺纱分厂工资信息", 'F', null),
                null,
                createMenuItem("人事部职工信息", 'R', null),
                createMenuItem("财务部职工信息", 'C', null),
                createMenuItem("材料可职工信息", 0, null),
                createMenuItem("销售科职工信息", 0, null),
                createMenuItem("成品车间职工信息", 0, null));

        // 中层干部信息系统菜单
        JMenu menu2 = new JMenu("中层干部信息系统");
        menu2.setMnemonic('C');

        // 创建菜单项
        JMenuItem factoryManagerItem = createMenuItem("分厂厂长信息", 0, null);
        JMenuItem departmentManagerItem = createMenuItem("部门经理信息", 0, null);

        // 使用 disableManagerMenu 方法处理禁用逻辑
        factoryManagerItem.addActionListener(e -> disableManagerMenu(departmentManagerItem));

        // 添加到 menu2
        menu2.add(factoryManagerItem);
        menu2.add(departmentManagerItem);

        // 工资系统菜单(复选框菜单)
        JMenu menu3 = new JMenu("工资系统");
        menu3.setMnemonic('G');
        menu3.add(createCheckBoxMenuItem("职工工资信息", false));
        menu3.add(createCheckBoxMenuItem("领导工资信息", false));

        // 查询系统菜单(单选框菜单)
        JMenu menu4 = new JMenu("查询系统");
        menu4.setMnemonic('F');
        ButtonGroup group = new ButtonGroup();
        JRadioButtonMenuItem searchByName = createRadioButtonMenuItem("按照姓名查询", group, true);
        JRadioButtonMenuItem searchByID = createRadioButtonMenuItem("按照工号查询", group, false);
        menu4.add(searchByName);
        menu4.add(searchByID);

        // 登录系统菜单
        JMenu menu5 = createMenu("登录系统", 'D',
                createMenuItem("添加登录用户名", 0, null));

        // 帮助系统菜单
        JMenu menu6 = createMenu("帮助系统", 'H',
                createMenuItem("版本信息", 0, null),
                createMenuItem("帮助信息", 0, null));

        // 添加菜单到菜单栏
        menuBar.add(menu1);
        menuBar.add(menu2);
        menuBar.add(menu3);
        menuBar.add(menu4);
        menuBar.add(menu5);
        menuBar.add(menu6);

        return menuBar;
    }

    // 禁用菜单项的方法
    private static void disableManagerMenu(JMenuItem menuItem) {
        if (menuItem != null) {
            menuItem.setEnabled(false); // 禁用菜单项
        }
    }

    private static JPopupMenu createPopupMenu(JFrame frame) {
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem infoItem = new JMenuItem("显示信息");
        infoItem.addActionListener(e -> JOptionPane.showMessageDialog(frame, "右键菜单:显示信息"));
        popupMenu.add(infoItem);

        JMenuItem exitItem = new JMenuItem("退出");
        exitItem.addActionListener(e -> System.exit(0));
        popupMenu.add(exitItem);

        return popupMenu;
    }

    private static JCheckBoxMenuItem createCheckBoxMenuItem(String title, boolean selected) {
        JCheckBoxMenuItem item = new JCheckBoxMenuItem(title);
        item.setSelected(selected);
        return item;
    }

    private static JRadioButtonMenuItem createRadioButtonMenuItem(String title, ButtonGroup group, boolean selected) {
        JRadioButtonMenuItem item = new JRadioButtonMenuItem(title, selected);
        group.add(item);
        return item;
    }

    private static JMenu createMenu(String title, char mnemonic, Object... items) {
        JMenu menu = new JMenu(title);
        menu.setMnemonic(mnemonic);

        for (Object item : items) {
            if (item == null) {
                menu.addSeparator();
            } else if (item instanceof JMenuItem) {
                menu.add((JMenuItem) item);
            }
        }

        return menu;
    }

    private static JMenuItem createMenuItem(String title, int acceleratorKey, ActionListener action) {
        JMenuItem item = new JMenuItem(title);
        if (acceleratorKey != 0) {
            item.setAccelerator(KeyStroke.getKeyStroke(acceleratorKey, InputEvent.CTRL_DOWN_MASK));
        }
        if (action != null) {
            item.addActionListener(action);
        }
        return item;
    }

    private static void showTabbedPaneDialog(JFrame parentFrame) {
        JDialog dialog = new JDialog(parentFrame, "磨砂分厂职工信息", true);
        dialog.setSize(700, 400);

        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Dimension screenSize = toolkit.getScreenSize();
        dialog.setLocation(screenSize.width / 2 - dialog.getWidth() / 2,
                screenSize.height / 2 - dialog.getHeight() / 2);

        JTabbedPane tabbedPane = new JTabbedPane();
        for (int i = 1; i <= 5; i++) {
            JPanel panel = createWorkshopPanel(i);
            tabbedPane.addTab("车间 " + i + " 信息", panel);
        }
        dialog.add(tabbedPane);
        dialog.setVisible(true);
    }

    private static JPanel createWorkshopPanel(int workshopNumber) {
        JPanel panel = new JPanel(new java.awt.GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5); // 设置组件间的间距
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 添加基本信息的标题
        JLabel titleLabel = new JLabel(" 基本信息", JLabel.CENTER);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 16));
        titleLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 50, 0));
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 4; // 跨两列
        panel.add(titleLabel, gbc);

        // 恢复单元格宽度
        gbc.gridwidth = 1;

        // 字段标签与输入框
        String[] labels = { "姓名", "出生年月", "工号", "家庭住址", "性别", "车间", "年龄", "职位" };
        for (int i = 0; i < labels.length / 2; i++) {
            // 添加标签
            JLabel label1 = new JLabel(labels[i] + ":");
            gbc.gridx = 0;
            gbc.gridy = i + 1;
            panel.add(label1, gbc);

            // 添加文本框
            JTextField textField1 = new JTextField(20);
            gbc.gridx = 1;
            gbc.gridy = i + 1;
            panel.add(textField1, gbc);

            // 添加标签
            JLabel label2 = new JLabel(labels[i] + ":");
            gbc.gridx = 2;
            gbc.gridy = i + 1;
            panel.add(label2, gbc);

            // 添加文本框
            JTextField textField2 = new JTextField(20);
            gbc.gridx = 3;
            gbc.gridy = i + 1;
            panel.add(textField2, gbc);
        }

        return panel;
    }
}

总结

本章重点,文本组件、窗口组件、对话框组件、菜单组件、工具条组件。这么多内容一次记住很难,不过通过例子来理解,就比较容易了。