You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不同Java类中访问同一个JTextArea变量?

解决你的Java GUI文本更新与脚本标签移除问题

首先,我注意到你当前的代码存在几个影响功能的问题,同时使用静态JTextArea也不是最佳实践,咱们一步步来修复:

主要问题分析

  1. 逐行覆盖文本:你在循环里每次调用textArea.setText(),这会把之前的内容全部替换掉,最后只会显示文件的最后一行处理结果。
  2. 静态组件的不良设计:把textArea设为静态虽然能让其他类访问,但会破坏封装性,也不利于程序扩展。
  3. 硬编码文件路径:文件路径写死在代码里,用户无法选择自己的文件,和你提供的Import File按钮功能脱节。
  4. 未处理跨多行的脚本标签:如果<script>标签和内容跨了多行,当前逐行处理的方式无法正确识别并移除。

修正后的完整代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GUI {
    private JTextArea textArea;
    private File selectedFile; // 保存用户选择的文件

    public GUI() {
        JFrame frame = new JFrame();
        textArea = new JTextArea(5, 30);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JScrollPane scrollPane = new JScrollPane(textArea); // 添加滚动条,方便查看长文本

        JButton runButton = new JButton("Remove JS");
        JButton importButton = new JButton("Import File");

        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        panel.setLayout(new GridLayout(0, 1, 10, 10)); // 增加组件间距
        panel.add(scrollPane);
        panel.add(runButton);
        panel.add(importButton);

        // 绑定按钮事件
        runButton.addActionListener(new RunButtonListener());
        importButton.addActionListener(new ImportButtonListener());

        frame.add(panel, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("JavaScript Extractor");
        frame.pack();
        frame.setVisible(true);
    }

    // 提供公共方法更新文本区域
    public void updateTextArea(String content) {
        textArea.setText(content);
    }

    public File getSelectedFile() {
        return selectedFile;
    }

    public static void main(String[] args) {
        // 在事件调度线程中启动GUI,符合Swing规范
        SwingUtilities.invokeLater(GUI::new);
    }

    // 内部类实现运行按钮监听,直接访问GUI实例的方法
    private class RunButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (getSelectedFile() == null) {
                JOptionPane.showMessageDialog(null, "请先导入文件!");
                return;
            }

            RemoveScript scriptRemover = new RemoveScript();
            StringBuilder contentBuilder = new StringBuilder();

            try (Scanner reader = new Scanner(getSelectedFile())) {
                // 读取整个文件内容,处理跨多行的脚本标签
                while (reader.hasNextLine()) {
                    contentBuilder.append(reader.nextLine()).append("\n");
                }
                String processedContent = scriptRemover.removeScript(contentBuilder.toString());
                updateTextArea(processedContent);
            } catch (FileNotFoundException ex) {
                JOptionPane.showMessageDialog(null, "文件未找到:" + ex.getMessage());
                ex.printStackTrace();
            }
        }
    }

    // 内部类实现导入文件按钮监听
    private class ImportButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser fileChooser = new JFileChooser();
            int result = fileChooser.showOpenDialog(null);
            if (result == JFileChooser.APPROVE_OPTION) {
                selectedFile = fileChooser.getSelectedFile();
                // 可选:导入后直接显示原文件内容
                try (Scanner reader = new Scanner(selectedFile)) {
                    StringBuilder contentBuilder = new StringBuilder();
                    while (reader.hasNextLine()) {
                        contentBuilder.append(reader.nextLine()).append("\n");
                    }
                    updateTextArea(contentBuilder.toString());
                } catch (FileNotFoundException ex) {
                    JOptionPane.showMessageDialog(null, "读取文件失败:" + ex.getMessage());
                }
            }
        }
    }
}

class RemoveScript {
    // 使用正则表达式移除所有<script>标签及其内容(包括跨多行)
    public String removeScript(String input) {
        // 正则匹配:忽略大小写,匹配<script>开始到</script>结束的所有内容,包括换行
        Pattern pattern = Pattern.compile("<script[^>]*>.*?</script>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(input);
        return matcher.replaceAll("");
    }
}

关键修改点说明

  1. 移除静态组件:把textArea改为GUI类的实例变量,通过updateTextArea()方法更新内容,既保证封装性又能安全更新组件。
  2. 文件选择功能:实现了Import File按钮的功能,用户可以选择任意文本文件,不再依赖硬编码路径。
  3. 处理跨多行脚本:读取整个文件内容后再用正则表达式处理,Pattern.DOTALL标志让.可以匹配换行符,确保跨多行的脚本标签也能被移除。
  4. 文本显示优化:给JTextArea添加了滚动条,开启自动换行,提升用户体验。
  5. 规范Swing线程:在SwingUtilities.invokeLater()中启动GUI,符合Swing的线程安全要求。
  6. 错误提示优化:用JOptionPane给用户弹出可视化错误提示,比控制台输出更友好。

这样修改后,点击“Import File”选择文件,再点击“Remove JS”就能正确移除所有脚本标签并显示处理后的内容啦。

内容的提问来源于stack exchange,提问作者Sylas Coker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:23:49