import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class IdPostRank extends JFrame {
private JTextField folderField;
private JTextArea resultArea;
private Map<String, java.util.List<String>> idPosts;
public IdPostRank() {
setTitle("ID投稿ランキング");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout(10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel inputPanel = new JPanel(new GridLayout(2, 2, 5, 5));
inputPanel.add(new JLabel("ログフォルダ:"));
folderField = new JTextField("C:\\gikonavi\\Log\\2ch\\poverty");
inputPanel.add(folderField);
JButton browseButton = new JButton("参照");
browseButton.addActionListener(e -> chooseFolder());
inputPanel.add(browseButton);
JButton analyzeButton = new JButton("分析開始");
analyzeButton.addActionListener(e -> analyzePosts());
inputPanel.add(analyzeButton);
resultArea = new JTextArea();
resultArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(resultArea);
panel.add(inputPanel, BorderLayout.NORTH);
panel.add(scrollPane, BorderLayout.CENTER);
add(panel);
}
private void chooseFolder() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
folderField.setText(fileChooser.getSelectedFile().getAbsolutePath());
}
}
private void analyzePosts() {
String logDir = folderField.getText().trim();
if (logDir.isEmpty()) {
JOptionPane.showMessageDialog(this, "ログフォルダを入力してください。",
"入力エラー", JOptionPane.ERROR_MESSAGE);
return;
}
resultArea.setText("分析中... (" + logDir + ")\n");
analyzePostsByID(logDir);
}
private void analyzePostsByID(String logDir) {
File dir = new File(logDir);
if (!dir.exists() || !dir.isDirectory()) {
resultArea.append("エラー: 指定したフォルダが見つからないか、ディレクトリではありません。\n");
return;
}
File[] logFiles = dir.listFiles((d, name) -> name.endsWith(".dat"));
if (logFiles == null || logFiles.length == 0) {
resultArea.append("エラー: *.dat ファイルが見つかりません。\n");
return;
}
resultArea.append("処理対象ファイル数: " + logFiles.length + "\n");
Map<String, Integer> idCounts = new HashMap<>();
idPosts = new HashMap<>();
Pattern idPattern = Pattern.compile("ID:\\s*([a-zA-Z0-9+/]+)\\b");
int processedFiles = 0;
for (File file : logFiles) {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file), "Shift_JIS"))) {
String line;
while ((line = reader.readLine()) != null) {
Matcher matcher = idPattern.matcher(line);
while (matcher.find()) {
String id = matcher.group(1);
idCounts.put(id, idCounts.getOrDefault(id, 0) + 1);
idPosts.computeIfAbsent(id, k -> new ArrayList<>()).add(line);
}
}
processedFiles++;
if (processedFiles % 1000 == 0) {
resultArea.append("処理中: " + processedFiles + " / " + logFiles.length + " ファイル\n");
}
} catch (IOException e) {
resultArea.append("ファイル読み込みエラー: " + file.getName() + " - " + e.getMessage() + "\n");
}
}
if (idCounts.isEmpty()) {
resultArea.append("指定した条件に一致するIDが見つかりませんでした。\n");
return;
}
java.util.List<Map.Entry<String, Integer>> sortedIds = new ArrayList<>(idCounts.entrySet());
sortedIds.sort((a, b) -> b.getValue().compareTo(a.getValue()));
resultArea.append("\n投稿数ランキング (全 *.dat ファイル):\n");
resultArea.append("総ID数: " + sortedIds.size() + "\n");
// ランキングを100位まで表示
JPanel rankPanel = new JPanel(new GridLayout(100, 1, 5, 5)); // 10 → 100 に変更
int rank = 1;
for (Map.Entry<String, Integer> entry : sortedIds) {
if (rank > 100) break; // 10 → 100 に変更
String id = entry.getKey();
int count = entry.getValue();
JButton idButton = new JButton(String.format("%d位: ID %s - %d件", rank, id, count));
idButton.addActionListener(e -> showPosts(id));
rankPanel.add(idButton);
rank++;
}
JFrame rankFrame = new JFrame("ランキング");
rankFrame.setSize(400, 600); // ウィンドウサイズを拡大(100件表示用)
rankFrame.add(new JScrollPane(rankPanel));
rankFrame.setLocationRelativeTo(this);
rankFrame.setVisible(true);
}
private void showPosts(String id) {
JFrame postFrame = new JFrame("ID: " + id + " の投稿内容");
postFrame.setSize(500, 400);
JTextArea postArea = new JTextArea();
postArea.setEditable(false);
java.util.List<String> posts = idPosts.get(id);
if (posts != null) {
for (String post : posts) {
postArea.append(post + "\n");
}
}
postFrame.add(new JScrollPane(postArea));
postFrame.setLocationRelativeTo(this);
postFrame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new IdPostRank().setVisible(true);
});
}
}