diff --git a/README.md b/README.md
index bc8530b..554592f 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,17 @@
![b](https://s2.ax1x.com/2019/12/25/lFCd41.jpg "b")
+### 之前看到有网友开发了一款PC端和VS Code插件版的小说阅读器(摸鱼神器Thief-Book),原创[链接地址](https://github.com/cteams/Thief-Book "链接地址"),但是很可惜的是没有IDEA版的,最近刚好比较闲,按照他的原型开发出了类似功能的IDEA插件。
+
------------
+# 2020-09-04日更新记录
-### 之前看到有网友开发了一款PC端和VS Code插件版的小说阅读器(摸鱼神器Thief-Book),原创[链接地址](https://github.com/cteams/Thief-Book "链接地址"),但是很可惜的是没有IDEA版的,最近刚好比较闲,按照他的原型开发出了类似功能的IDEA插件。
+
+------------
+# 2019-07-26日
+------------
# 效果图
![t](https://s2.ax1x.com/2019/12/25/lFC6De.gif "t")
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 9c9b858..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,31 +0,0 @@
-plugins {
- id 'java'
- id 'org.jetbrains.intellij' version '0.4.9'
-}
-
-group 'com.thief.idea'
-version '1.0-SNAPSHOT'
-
-sourceCompatibility = 1.8
-
-repositories {
- mavenCentral()
-}
-
-dependencies {
- testCompile group: 'junit', name: 'junit', version: '4.12'
- compile 'com.jgoodies:forms:1.2.1'
-
-}
-
-intellij {
- version '2018.1.2'
-}
-patchPluginXml {
- changeNotes """
- Add change notes here.
- most HTML tags may be used"""
-}
-tasks.withType(JavaCompile) {
- options.encoding = "UTF-8"
-}
diff --git a/gradlew b/gradlew
deleted file mode 100644
index cccdd3d..0000000
--- a/gradlew
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env sh
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
- echo "$*"
-}
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=$(save "$@")
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
-
-exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
deleted file mode 100644
index f955316..0000000
--- a/gradlew.bat
+++ /dev/null
@@ -1,84 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/img/main.png b/img/main.png
new file mode 100644
index 0000000..de18c8c
Binary files /dev/null and b/img/main.png differ
diff --git a/img/setting.png b/img/setting.png
new file mode 100644
index 0000000..6e58dd0
Binary files /dev/null and b/img/setting.png differ
diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
new file mode 100644
index 0000000..a420781
--- /dev/null
+++ b/resources/META-INF/plugin.xml
@@ -0,0 +1,37 @@
+
+ com.thief.idea
+ thief-book-idea
+ 1.0
+ 毅斯
+
+
+
+
+
+
+
+
+
+ com.intellij.modules.platform
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/icons/thief.png b/resources/icons/thief.png
similarity index 100%
rename from src/main/resources/icons/thief.png
rename to resources/icons/thief.png
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index 61dd84d..0000000
--- a/settings.gradle
+++ /dev/null
@@ -1,2 +0,0 @@
-rootProject.name = 'thief-book-idea'
-
diff --git a/src/com/thief/idea/MainUi.java b/src/com/thief/idea/MainUi.java
new file mode 100644
index 0000000..3484b93
--- /dev/null
+++ b/src/com/thief/idea/MainUi.java
@@ -0,0 +1,458 @@
+package com.thief.idea;
+
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowFactory;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.ui.JBUI;
+import org.apache.commons.lang.StringUtils;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class MainUi implements ToolWindowFactory, DumbAware {
+
+ private PersistentState persistentState = PersistentState.getInstance();
+
+ /**
+ * 缓存文件页数所对应的seek,避免搜索指针的时候每次从头读取文件
+ **/
+ private Map seekDictionary = new LinkedHashMap<>();
+
+ /**
+ * 缓存文件页数所对应seek的间隔
+ * 该值越小,跳页时间越短,但对应的内存会增大
+ **/
+ private int cacheInterval = 200;
+
+ /**
+ * 读取文件路径
+ **/
+ private String bookFile = persistentState.getBookPathText();
+
+ /**
+ * 读取字体设置
+ **/
+ private String type = persistentState.getFontType();
+
+ /**
+ * 读取字号设置
+ **/
+ private String size = persistentState.getFontSize();
+
+ /**
+ * 读取每页行数设置
+ **/
+ private Integer lineCount = Integer.parseInt(persistentState.getLineCount());
+
+ /**
+ * 读取行距设置
+ **/
+ private Integer lineSpace = Integer.parseInt(persistentState.getLineSpace());
+
+ /**
+ * 正文内容显示
+ **/
+ private JTextArea textArea;
+
+ /**
+ * 当前阅读页&跳页输入框
+ **/
+ private JTextField current;
+
+ /**
+ * 显示总页数
+ **/
+ private JLabel total = new JLabel();
+
+ /**
+ * 读取文件的指针
+ **/
+ private long seek = 0;
+
+ /**
+ * 当前文件总页数
+ **/
+ private int totalLine = 0;
+
+ /**
+ * 当前正在阅读页数
+ **/
+ private int currentPage = 0;
+
+ /**
+ * 缓存文字
+ **/
+ private String temp = "Stopping memory leak detection....";
+
+ /**
+ * 是否隐藏界面
+ **/
+ private boolean hide = false;
+
+ @Override
+ public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
+ try {
+ JPanel panel = initPanel();
+ ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
+ Content content = contentFactory.createContent(panel, "Thief-Book", false);
+ toolWindow.getContentManager().addContent(content);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 初始化整体面板
+ **/
+ private JPanel initPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ textArea = initTextArea();
+ panel.add(textArea, BorderLayout.CENTER);
+ panel.add(initOperationPanel(), BorderLayout.EAST);
+ return panel;
+ }
+
+ /**
+ * 正文区域初始化
+ **/
+ private JTextArea initTextArea() {
+ JTextArea textArea = new JTextArea();
+ //初始化显示文字
+ String welcome = "Memory leak detection has started....";
+ textArea.setText(welcome);
+ textArea.setOpaque(false);
+ textArea.setTabSize(4);
+ textArea.setEditable(false);
+ textArea.setLineWrap(true);
+ textArea.setWrapStyleWord(true);
+ textArea.setFont(new Font(type, Font.PLAIN, Integer.parseInt(size)));
+ textArea.setBorder(JBUI.Borders.empty(10, 30));
+ return textArea;
+ }
+
+ /**
+ * 初始化操作面板
+ **/
+ private JPanel initOperationPanel() {
+ // 当前行
+ current = initTextField();
+ // 总行数
+ total.setText("/" + (totalLine % lineCount == 0 ? totalLine / lineCount : totalLine / lineCount + 1));
+
+ JPanel panelRight = new JPanel();
+ panelRight.setBorder(JBUI.Borders.empty(0, 20));
+ panelRight.setPreferredSize(new Dimension(280, 30));
+ panelRight.add(current, BorderLayout.EAST);
+ panelRight.add(total, BorderLayout.EAST);
+ //加载按钮
+ JButton fresh = initFreshButton();
+ panelRight.add(fresh, BorderLayout.EAST);
+ //上一页
+ JButton up = initUpButton();
+ panelRight.add(up, BorderLayout.EAST);
+ //下一页
+ JButton down = initDownButton();
+ panelRight.add(down, BorderLayout.EAST);
+ //老板键
+ JButton boss = initBossButton(new JButton[]{fresh, up, down});
+ panelRight.add(boss, BorderLayout.SOUTH);
+ return panelRight;
+ }
+
+ /**
+ * 跳页输入框
+ **/
+ private JTextField initTextField() {
+ JTextField current = new JTextField("current line:");
+ current.setPreferredSize(new Dimension(50, 30));
+ current.setOpaque(false);
+ current.setBorder(JBUI.Borders.empty(0));
+ current.setText(currentPage / lineCount + "");
+ current.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ //判断按下的键是否是回车键
+ if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+ try {
+ String input = current.getText();
+ String inputCurrent = input.split("/")[0].trim();
+ int i = Integer.parseInt(inputCurrent);
+ if (i <= 1) {
+ seek = 0;
+ currentPage = 0;
+ } else {
+ currentPage = (i - 1) * lineCount;
+ if (currentPage > totalLine) {
+ currentPage = totalLine - 1;
+ }
+ countSeek();
+ }
+ textArea.setText(readBook());
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ textArea.setText(e1.toString());
+ } catch (NumberFormatException e2) {
+ textArea.setText("请输入数字");
+ }
+
+ }
+ }
+ });
+ return current;
+ }
+
+ /**
+ * 刷新按钮🔄
+ **/
+ private JButton initFreshButton() {
+ JButton refresh = new JButton("\uD83D\uDD04");
+ refresh.setPreferredSize(new Dimension(20, 20));
+ refresh.setContentAreaFilled(false);
+ refresh.setBorderPainted(false);
+ refresh.addActionListener(e -> {
+ try {
+ persistentState = PersistentState.getInstanceForce();
+ if (StringUtils.isEmpty(persistentState.getBookPathText()) || !bookFile.equals(persistentState.getBookPathText())) {
+ bookFile = persistentState.getBookPathText();
+ currentPage = 0;
+ seek = 0;
+ seekDictionary.clear();
+ if (StringUtils.isEmpty(bookFile)) {
+ totalLine = 0;
+ return;
+ }
+ totalLine = countLine();
+ countSeek();
+ } else {
+ // 初始化当前行数
+ if (StringUtils.isNotEmpty(persistentState.getCurrentLine())) {
+ currentPage = Integer.parseInt(persistentState.getCurrentLine());
+ }
+ if (seekDictionary.size() <= 5 || totalLine == 0) {
+ totalLine = countLine();
+ countSeek();
+ }
+ }
+ type = persistentState.getFontType();
+ size = persistentState.getFontSize();
+ lineCount = Integer.parseInt(persistentState.getLineCount());
+ lineSpace = Integer.parseInt(persistentState.getLineSpace());
+ textArea.setText("已刷新");
+ current.setText(" " + currentPage / lineCount);
+ total.setText("/" + (totalLine % lineCount == 0 ? totalLine / lineCount : totalLine / lineCount + 1));
+ textArea.setFont(new Font(type, Font.PLAIN, Integer.parseInt(size)));
+ } catch (Exception newE) {
+ newE.printStackTrace();
+ }
+ });
+ return refresh;
+ }
+
+ /**
+ * 向上翻页按钮
+ **/
+ private JButton initUpButton() {
+ JButton afterB = new JButton("prev");
+ afterB.setPreferredSize(new Dimension(40, 20));
+ afterB.setContentAreaFilled(false);
+ afterB.setBorderPainted(false);
+ afterB.addActionListener(e -> {
+ if (currentPage > totalLine) {
+ return;
+ }
+ if (currentPage / lineCount > 1) {
+ if (currentPage % lineCount == 0) {
+ currentPage = currentPage - lineCount * 2;
+ } else {
+ while (currentPage % lineCount != 0) {
+ currentPage--;
+ }
+ currentPage -= lineCount;
+ }
+ try {
+ countSeek();
+ textArea.setText(readBook());
+ current.setText(" " + currentPage / lineCount);
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ }
+ });
+
+ afterB.registerKeyboardAction(afterB.getActionListeners()[0],
+ KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_MASK),
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+
+ return afterB;
+ }
+
+ /**
+ * 向下翻页按钮
+ **/
+ private JButton initDownButton() {
+ JButton nextB = new JButton("next");
+ nextB.setPreferredSize(new Dimension(40, 20));
+ nextB.setContentAreaFilled(false);
+ nextB.setBorderPainted(false);
+ nextB.addActionListener(e -> {
+
+ if (currentPage < totalLine) {
+ try {
+ if (currentPage / lineCount <= 1) {
+ countSeek();
+ }
+ textArea.setText(readBook());
+ current.setText(" " + (currentPage % lineCount == 0 ? currentPage / lineCount : currentPage / lineCount + 1));
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ });
+
+ nextB.registerKeyboardAction(nextB.getActionListeners()[0],
+ KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_MASK),
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+
+ return nextB;
+ }
+
+ /**
+ * 隐藏按钮
+ **/
+ private JButton initBossButton(JButton[] buttons) {
+ //老板键
+ JButton bossB = new JButton(" ");
+ bossB.setPreferredSize(new Dimension(5, 5));
+ bossB.setContentAreaFilled(false);
+ bossB.setBorderPainted(false);
+ bossB.addActionListener(e -> {
+ if (hide) {
+ for (JButton b : buttons) {
+ b.setVisible(true);
+ }
+ current.setVisible(true);
+ total.setVisible(true);
+ textArea.setText(temp);
+ hide = false;
+ } else {
+ for (JButton b : buttons) {
+ b.setVisible(false);
+ }
+ current.setVisible(false);
+ total.setVisible(false);
+ temp = textArea.getText();
+ textArea.setText("Memory leak detection....");
+ hide = true;
+ }
+ });
+ bossB.registerKeyboardAction(bossB.getActionListeners()[0], KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
+ bossB.registerKeyboardAction(bossB.getActionListeners()[0], KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
+ return bossB;
+ }
+
+ /**
+ * 向下读取文件
+ **/
+ private String readBook() throws IOException {
+ RandomAccessFile ra = null;
+ StringBuilder str = new StringBuilder();
+ StringBuilder nStr = new StringBuilder();
+ try {
+ ra = new RandomAccessFile(bookFile, "r");
+ ra.seek(seek);
+ for (int j = 0; j < lineSpace + 1; j++) {
+ nStr.append("\n");
+ }
+ String temp;
+ for (int i = 0; i < lineCount && (temp = ra.readLine()) != null; i++) {
+ str.append(new String(temp.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)).append(nStr);
+ currentPage++;
+ }
+ //实例化当前行数
+ persistentState.setCurrentLine(String.valueOf(currentPage));
+ seek = ra.getFilePointer();
+ if (currentPage % cacheInterval == 0) {
+ seekDictionary.put(currentPage, seek);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return e.getMessage();
+ } finally {
+ if (ra != null) {
+ ra.close();
+ }
+ }
+ return str.toString();
+ }
+
+ /**
+ * 读取文件总行数
+ **/
+ private int countLine() throws IOException {
+ try (RandomAccessFile ra = new RandomAccessFile(bookFile, "r")) {
+ int i = 0;
+ seekDictionary.put(0, ra.getFilePointer());
+ while (ra.readLine() != null) {
+ i++;
+ if (i % cacheInterval == 0) {
+ seekDictionary.put(i, ra.getFilePointer());
+ }
+ }
+ return i;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * 找到当前指针应在位置
+ **/
+ private void countSeek() throws IOException {
+
+ RandomAccessFile ra = null;
+
+ try {
+ if (seekDictionary.containsKey(currentPage)) {
+ this.seek = seekDictionary.get(currentPage);
+ } else {
+ ra = new RandomAccessFile(bookFile, "r");
+ int line = 0;
+ for (int i = 0; cacheInterval * i < currentPage; i++) {
+ line = cacheInterval * i;
+ ra.seek(seekDictionary.get(line));
+ }
+ while (ra.readLine() != null) {
+ line++;
+ if (line == currentPage) {
+ this.seek = ra.getFilePointer();
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (ra != null) {
+ ra.close();
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/thief_book/idea/PersistentState.java b/src/com/thief/idea/PersistentState.java
similarity index 59%
rename from src/main/java/com/thief_book/idea/PersistentState.java
rename to src/com/thief/idea/PersistentState.java
index 894742a..01faf5f 100644
--- a/src/main/java/com/thief_book/idea/PersistentState.java
+++ b/src/com/thief/idea/PersistentState.java
@@ -1,4 +1,4 @@
-package com.thief_book.idea;
+package com.thief.idea;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
@@ -24,7 +24,9 @@ public class PersistentState implements PersistentStateComponent {
private String showFlag;
- private String autoNextSecond;
+ private String fontSize;
+
+ private String fontType;
private String before;
@@ -32,7 +34,13 @@ public class PersistentState implements PersistentStateComponent {
private String currentLine;
- private String autoKeymap;
+ private String lineCount;
+
+ private String lineSpace;
+
+// private String bossKey;
+
+
public PersistentState() {
}
@@ -41,10 +49,13 @@ public static PersistentState getInstance() {
if (persistentState == null) {
persistentState = ServiceManager.getService(PersistentState.class);
}
-
return persistentState;
}
+ public static PersistentState getInstanceForce() {
+ return ServiceManager.getService(PersistentState.class);
+ }
+
@Nullable
@Override
@@ -52,11 +63,15 @@ public Element getState() {
Element element = new Element("PersistentState");
element.setAttribute("bookPath", this.getBookPathText());
element.setAttribute("showFlag", this.getShowFlag());
- element.setAttribute("autoNextSecond", this.getAutoNextSecond());
+ element.setAttribute("fontSize", this.getFontSize());
element.setAttribute("before", this.getBefore());
element.setAttribute("next", this.getNext());
element.setAttribute("currentLine", this.getCurrentLine());
- element.setAttribute("autoKeymap", this.getAutoKeymap());
+ element.setAttribute("fontType", this.getFontType());
+ element.setAttribute("lineCount",this.getLineCount());
+ element.setAttribute("lineSpace",this.getLineSpace());
+// element.setAttribute("bossKey",this.getBossKey());
+
return element;
}
@@ -64,11 +79,14 @@ public Element getState() {
public void loadState(@NotNull Element state) {
this.setBookPathText(state.getAttributeValue("bookPath"));
this.setShowFlag(state.getAttributeValue("showFlag"));
- this.setAutoNextSecond(state.getAttributeValue("autoNextSecond"));
+ this.setFontSize(state.getAttributeValue("fontSize"));
this.setBefore(state.getAttributeValue("before"));
this.setNext(state.getAttributeValue("next"));
this.setCurrentLine(state.getAttributeValue("currentLine"));
- this.setAutoKeymap(state.getAttributeValue("autoKeymap"));
+ this.setFontType(state.getAttributeValue("fontType"));
+ this.setLineCount(state.getAttributeValue("lineCount"));
+ this.setLineSpace(state.getAttributeValue("lineSpace"));
+// this.setLineSpace(state.getAttributeValue("bossKey"));
}
@@ -93,14 +111,6 @@ public void setShowFlag(String showFlag) {
this.showFlag = showFlag;
}
- public String getAutoNextSecond() {
- return StringUtils.isEmpty(autoNextSecond) ? "5" : this.autoNextSecond;
- }
-
- public void setAutoNextSecond(String autoNextSecond) {
- this.autoNextSecond = autoNextSecond;
- }
-
public String getBefore() {
return StringUtils.isEmpty(before) ? "Alt + ←" : this.before;
}
@@ -125,11 +135,41 @@ public void setCurrentLine(String currentLine) {
this.currentLine = currentLine;
}
- public String getAutoKeymap() {
- return StringUtils.isEmpty(autoKeymap) ? "Alt + ↑" : this.autoKeymap;
+ public String getFontSize() {
+ return StringUtils.isEmpty(fontSize) ? "14" : this.fontSize;
+ }
+
+ public void setFontSize(String fontSize) {
+ this.fontSize = fontSize;
+ }
+
+ public String getFontType() {
+ return StringUtils.isEmpty(fontType) ? "Microsoft JhengHei" : this.fontType;
+ }
+
+ public void setFontType(String fontType) {
+ this.fontType = fontType;
+ }
+ public String getLineCount() {
+ return this.lineCount =StringUtils.isEmpty(lineCount) ? "1" : lineCount;
+ }
+ public void setLineCount(String lineCount) {
+ this.lineCount = lineCount;
+ }
+
+ public String getLineSpace() {
+ return this.lineSpace=StringUtils.isEmpty(lineSpace) ? "0" : lineSpace;
}
- public void setAutoKeymap(String autoKeymap) {
- this.autoKeymap = autoKeymap;
+ public void setLineSpace(String lineSpace) {
+ this.lineSpace = lineSpace;
}
-}
+
+// public String getBossKey() {
+// return StringUtils.isEmpty(bossKey) ? "Ctrl + Shift + ↓" : this.bossKey;
+// }
+//
+// public void setBossKey(String bossKey) {
+// this.bossKey = bossKey;
+// }
+}
\ No newline at end of file
diff --git a/src/com/thief/idea/RemoveBlank.java b/src/com/thief/idea/RemoveBlank.java
new file mode 100644
index 0000000..906db3c
--- /dev/null
+++ b/src/com/thief/idea/RemoveBlank.java
@@ -0,0 +1,67 @@
+package com.thief.idea;
+
+import java.io.*;
+
+/**
+ * @description:
+ * @program: com.thief
+ * @author: youvy
+ * @create: 2019-12-29 10:47
+ **/
+public class RemoveBlank {
+ /*
+ * 删除txt文档空白行
+ * @author WTCLAB_yd
+ */
+ public static void main(String[] args)
+ {
+ String line=null;
+ int i=0;
+ File file=new File("C:\\Users\\BestN\\Downloads\\九星毒奶.txt");//用命令行参数直接写入待处理文件
+ File file1=new File("C:\\Users\\BestN\\Downloads\\九星毒奶DBLine.txt");
+
+ //判断输入的文档是否存在,不存在则提示退出
+ if(!file.exists())
+ {
+ System.out.println("文件不存在!");
+ System.exit(0);
+ }
+ //输入的是TXT文档则继续往下执行
+ try
+ {
+ //读出文档数据流方式
+ InputStreamReader Stream=new InputStreamReader(new FileInputStream(file),"gbk");//读入数据流方式设为‘UTF-8’,避免乱码
+ //构造一个字符流的缓存器,存放在控制台输入的字节转换后成的字符
+ BufferedReader reader=new BufferedReader(Stream);
+ //写入数据流方式
+ OutputStreamWriter outStream=new OutputStreamWriter(new FileOutputStream(file1),"gbk");
+ BufferedWriter writer=new BufferedWriter(outStream);
+ //以行读出文档内容至结束
+ while((line=reader.readLine())!=null)
+ {
+ if(line.equals(""))//判断是否是空行
+ {
+ continue;//是空行则不进行操作
+ }
+ else
+ {
+ i++;
+ writer.write("["+i+"]");//可在文档中标出行号
+ writer.write(line+"\r\n");//将非空白行写入新文档
+ }
+ }
+ //关闭数据流
+ writer.close();
+ reader.close();
+ System.out.println("修改完成!");
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+// public static void main(String[] args) {
+// System.out.println("\uD83D\uDD04");
+// }
+}
diff --git a/src/main/java/com/thief_book/idea/Setting.java b/src/com/thief/idea/Setting.java
similarity index 69%
rename from src/main/java/com/thief_book/idea/Setting.java
rename to src/com/thief/idea/Setting.java
index 4801799..cd3e89f 100644
--- a/src/main/java/com/thief_book/idea/Setting.java
+++ b/src/com/thief/idea/Setting.java
@@ -1,8 +1,8 @@
-package com.thief_book.idea;
+package com.thief.idea;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
-import com.thief_book.idea.ui.SettingUi;
+import com.thief.idea.ui.SettingUi;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -66,28 +66,32 @@ public JComponent createComponent() {
@Override
public boolean isModified() {
return !StringUtils.equals(persistentState.getBookPathText(), settingUi.bookPathText.getText())
- || !StringUtils.equals(persistentState.getShowFlag(), settingUi.showFlag.isSelected() ? "1" : "0")
- || !StringUtils.equals(persistentState.getAutoNextSecond(), settingUi.autoNextSecond.getSelectedItem().toString())
+ || !StringUtils.equals(persistentState.getFontSize(), settingUi.fontSize.getSelectedItem().toString())
|| !StringUtils.equals(persistentState.getBefore(), settingUi.before.getText())
|| !StringUtils.equals(persistentState.getNext(), settingUi.next.getText())
- || !StringUtils.equals(persistentState.getAutoKeymap(), settingUi.autoKeymap.getText());
+ || !StringUtils.equals(persistentState.getLineCount(), settingUi.lineCount.getSelectedItem().toString())
+ || !StringUtils.equals(persistentState.getLineSpace(), settingUi.lineSpace.getSelectedItem().toString())
+ || !StringUtils.equals(persistentState.getFontType(), settingUi.fontType.getSelectedItem().toString());
+
}
@Override
public void apply() {
persistentState.setBookPathText(settingUi.bookPathText.getText());
- persistentState.setShowFlag(settingUi.showFlag.isSelected() ? "1" : "0");
- persistentState.setAutoNextSecond(settingUi.autoNextSecond.getSelectedItem().toString());
+ persistentState.setFontSize(settingUi.fontSize.getSelectedItem().toString());
persistentState.setBefore(settingUi.before.getText());
persistentState.setNext(settingUi.next.getText());
- persistentState.setAutoKeymap(settingUi.autoKeymap.getText());
+ persistentState.setLineCount(settingUi.lineCount.getSelectedItem().toString());
+ persistentState.setFontType(settingUi.fontType.getSelectedItem().toString());
+ persistentState.setLineSpace(settingUi.lineSpace.getSelectedItem().toString());
+
}
@Override
public void reset() {
// settingUi.bookPathText.setText("");
// settingUi.showFlag.setSelected(false);
-// settingUi.autoNextSecond.setSelectedItem("5");
+// settingUi.fontSize.setSelectedItem("5");
// settingUi.before.setText("");
// settingUi.next.setText("");
}
diff --git a/src/main/java/com/thief_book/idea/ShowThiefBook.java b/src/com/thief/idea/ShowThiefBook.java
similarity index 77%
rename from src/main/java/com/thief_book/idea/ShowThiefBook.java
rename to src/com/thief/idea/ShowThiefBook.java
index 9e1d97a..b70d7e9 100644
--- a/src/main/java/com/thief_book/idea/ShowThiefBook.java
+++ b/src/com/thief/idea/ShowThiefBook.java
@@ -1,4 +1,4 @@
-package com.thief_book.idea;
+package com.thief.idea;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -9,7 +9,6 @@ public class ShowThiefBook extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
- // TODO: insert action logic here
if (e.getProject() != null) {
// 将项目对象,ToolWindow的id传入,获取控件对象
@@ -22,7 +21,12 @@ public void run() {
}
});
+ if (toolWindow.getContentManager().getContentCount() < 1) {
+ MainUi mainUi = new MainUi();
+ mainUi.createToolWindowContent(e.getProject(), toolWindow);
+ }
}
+
}
diff --git a/src/com/thief/idea/TestUi.java b/src/com/thief/idea/TestUi.java
new file mode 100644
index 0000000..5871d3f
--- /dev/null
+++ b/src/com/thief/idea/TestUi.java
@@ -0,0 +1,29 @@
+package com.thief.idea;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowFactory;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.ui.JBUI;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author yongpeng.zheng
+ * @since 2020-09-04 15:57
+ */
+public class TestUi implements ToolWindowFactory{
+ @Override
+ public boolean isApplicable(@NotNull Project project) {
+ return false;
+ }
+
+ @Override
+ public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
+
+ }
+
+}
diff --git a/src/main/java/com/thief_book/idea/ui/SettingUi.form b/src/com/thief/idea/ui/SettingUi.form
similarity index 70%
rename from src/main/java/com/thief_book/idea/ui/SettingUi.form
rename to src/com/thief/idea/ui/SettingUi.form
index b10b226..8b12b02 100644
--- a/src/main/java/com/thief_book/idea/ui/SettingUi.form
+++ b/src/com/thief/idea/ui/SettingUi.form
@@ -1,5 +1,5 @@
-