Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
ql04210214
jadx
提交
e641b773
J
jadx
项目概览
ql04210214
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
e641b773
编写于
8月 05, 2022
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(gui): improve search dialog performance
上级
6e5899c6
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
266 addition
and
240 deletion
+266
-240
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java
+29
-10
jadx-gui/src/main/java/jadx/gui/jobs/Cancelable.java
jadx-gui/src/main/java/jadx/gui/jobs/Cancelable.java
+8
-0
jadx-gui/src/main/java/jadx/gui/jobs/IBackgroundTask.java
jadx-gui/src/main/java/jadx/gui/jobs/IBackgroundTask.java
+1
-1
jadx-gui/src/main/java/jadx/gui/search/SearchTask.java
jadx-gui/src/main/java/jadx/gui/search/SearchTask.java
+30
-21
jadx-gui/src/main/java/jadx/gui/ui/dialog/CommonSearchDialog.java
.../src/main/java/jadx/gui/ui/dialog/CommonSearchDialog.java
+61
-96
jadx-gui/src/main/java/jadx/gui/ui/dialog/SearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/dialog/SearchDialog.java
+108
-105
jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java
jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java
+8
-7
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
+13
-0
jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java
jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java
+8
-0
未找到文件。
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundExecutor.java
浏览文件 @
e641b773
...
...
@@ -145,8 +145,8 @@ public class BackgroundExecutor {
task
.
onDone
(
this
);
// treat UI task operations as part of the task to not mix with others
UiUtils
.
uiRunAndWait
(()
->
{
task
.
onFinish
(
this
);
progressPane
.
setVisible
(
false
);
task
.
onFinish
(
this
);
});
}
finally
{
taskComplete
(
id
);
...
...
@@ -190,13 +190,21 @@ public class BackgroundExecutor {
performCancel
(
executor
);
return
cancelStatus
;
}
updateProgress
(
executor
);
k
++;
Thread
.
sleep
(
k
<
10
?
200
:
1000
);
// faster update for short tasks
if
(
jobsCount
==
1
&&
k
==
3
)
{
if
(
k
<
10
)
{
// faster update for short tasks
Thread
.
sleep
(
200
);
if
(
k
==
5
)
{
updateProgress
(
executor
);
}
}
else
{
updateProgress
(
executor
);
Thread
.
sleep
(
1000
);
}
if
(
jobsCount
==
1
&&
k
==
5
)
{
// small delay before show progress to reduce blinking on short tasks
progressPane
.
changeVisibility
(
this
,
true
);
}
k
++;
}
}
catch
(
InterruptedException
e
)
{
LOG
.
debug
(
"Task wait interrupted"
);
...
...
@@ -210,7 +218,7 @@ public class BackgroundExecutor {
}
private
void
updateProgress
(
ThreadPoolExecutor
executor
)
{
Consumer
<
ITaskProgress
>
onProgressListener
=
task
.
get
On
ProgressListener
();
Consumer
<
ITaskProgress
>
onProgressListener
=
task
.
getProgressListener
();
ITaskProgress
taskProgress
=
task
.
getTaskProgress
();
if
(
taskProgress
==
null
)
{
setProgress
(
calcProgress
(
executor
.
getCompletedTaskCount
(),
jobsCount
));
...
...
@@ -231,13 +239,16 @@ public class BackgroundExecutor {
// force termination
task
.
cancel
();
executor
.
shutdown
();
if
(
executor
.
awaitTermination
(
2
,
TimeUnit
.
SECONDS
))
{
LOG
.
debug
(
"Task cancel complete"
);
return
;
int
cancelTimeout
=
task
.
getCancelTimeoutMS
();
if
(
cancelTimeout
!=
0
)
{
if
(
executor
.
awaitTermination
(
cancelTimeout
,
TimeUnit
.
MILLISECONDS
))
{
LOG
.
debug
(
"Task cancel complete"
);
return
;
}
}
LOG
.
debug
(
"Forcing tasks cancel"
);
executor
.
shutdownNow
();
boolean
complete
=
executor
.
awaitTermination
(
5
,
TimeUnit
.
SECONDS
);
boolean
complete
=
executor
.
awaitTermination
(
task
.
getShutdownTimeoutMS
(),
TimeUnit
.
MILLI
SECONDS
);
LOG
.
debug
(
"Forced task cancel status: {}"
,
complete
?
"success"
:
"fail, still active: "
+
executor
.
getActiveCount
());
}
...
...
@@ -301,5 +312,13 @@ public class BackgroundExecutor {
public
long
getTime
()
{
return
time
;
}
@Override
public
String
toString
()
{
return
"TaskWorker{status="
+
status
+
", jobsCount="
+
jobsCount
+
", jobsComplete="
+
jobsComplete
+
", time="
+
time
+
'}'
;
}
}
}
jadx-gui/src/main/java/jadx/gui/jobs/Cancelable.java
浏览文件 @
e641b773
...
...
@@ -4,4 +4,12 @@ public interface Cancelable {
boolean
isCanceled
();
void
cancel
();
default
int
getCancelTimeoutMS
()
{
return
2000
;
}
default
int
getShutdownTimeoutMS
()
{
return
5000
;
}
}
jadx-gui/src/main/java/jadx/gui/jobs/IBackgroundTask.java
浏览文件 @
e641b773
...
...
@@ -54,7 +54,7 @@ public interface IBackgroundTask extends Cancelable {
/**
* Return progress notifications listener (use executor tick rate and thread) (Optional)
*/
default
@Nullable
Consumer
<
ITaskProgress
>
get
On
ProgressListener
()
{
default
@Nullable
Consumer
<
ITaskProgress
>
getProgressListener
()
{
return
null
;
}
}
jadx-gui/src/main/java/jadx/gui/search/SearchTask.java
浏览文件 @
e641b773
...
...
@@ -4,8 +4,10 @@ import java.util.ArrayList;
import
java.util.List
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.function.BiConsumer
;
import
java.util.function.Consumer
;
import
org.jetbrains.annotations.NotNull
;
...
...
@@ -27,8 +29,8 @@ public class SearchTask extends CancelableBackgroundTask {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SearchTask
.
class
);
private
final
BackgroundExecutor
backgroundExecutor
;
private
final
Consumer
<
ITaskInfo
>
onFinish
;
private
final
Consumer
<
JNode
>
results
;
private
final
Consumer
<
JNode
>
resultsListener
;
private
final
BiConsumer
<
ITaskInfo
,
Boolean
>
onFinish
;
private
final
List
<
SearchJob
>
jobs
=
new
ArrayList
<>();
private
final
TaskProgress
taskProgress
=
new
TaskProgress
();
...
...
@@ -39,9 +41,9 @@ public class SearchTask extends CancelableBackgroundTask {
private
Consumer
<
ITaskProgress
>
progressListener
;
public
SearchTask
(
MainWindow
mainWindow
,
Consumer
<
JNode
>
results
,
Consumer
<
ITaskInfo
>
onFinish
)
{
public
SearchTask
(
MainWindow
mainWindow
,
Consumer
<
JNode
>
results
,
BiConsumer
<
ITaskInfo
,
Boolean
>
onFinish
)
{
this
.
backgroundExecutor
=
mainWindow
.
getBackgroundExecutor
();
this
.
results
=
results
;
this
.
results
Listener
=
results
;
this
.
onFinish
=
onFinish
;
}
...
...
@@ -55,8 +57,7 @@ public class SearchTask extends CancelableBackgroundTask {
public
synchronized
void
fetchResults
()
{
if
(
future
!=
null
)
{
cancel
();
waitTask
();
throw
new
IllegalStateException
(
"Previous task not yet finished"
);
}
resetCancel
();
complete
.
set
(
false
);
...
...
@@ -70,9 +71,10 @@ public class SearchTask extends CancelableBackgroundTask {
// ignore new results after cancel
return
true
;
}
this
.
results
.
accept
(
resultNode
);
this
.
results
Listener
.
accept
(
resultNode
);
if
(
resultsLimit
!=
0
&&
resultsCount
.
incrementAndGet
()
>=
resultsLimit
)
{
cancel
();
complete
.
set
(
false
);
return
true
;
}
return
false
;
...
...
@@ -81,14 +83,17 @@ public class SearchTask extends CancelableBackgroundTask {
public
synchronized
void
waitTask
()
{
if
(
future
!=
null
)
{
try
{
future
.
get
(
2
,
TimeUnit
.
SECONDS
);
future
.
get
(
200
,
TimeUnit
.
MILLISECONDS
);
}
catch
(
TimeoutException
e
)
{
LOG
.
debug
(
"Search task wait timeout"
);
}
catch
(
Exception
e
)
{
LOG
.
warn
(
"
Wait search task failed
"
,
e
);
LOG
.
warn
(
"
Search task wait error
"
,
e
);
}
finally
{
future
.
cancel
(
true
);
future
=
null
;
}
}
}
@Override
...
...
@@ -101,18 +106,12 @@ public class SearchTask extends CancelableBackgroundTask {
return
jobs
;
}
public
boolean
isSearchComplete
()
{
return
complete
.
get
()
&&
!
isCanceled
();
}
@Override
public
void
onDone
(
ITaskInfo
taskInfo
)
{
this
.
complete
.
set
(
true
);
}
@Override
public
void
onFinish
(
ITaskInfo
status
)
{
this
.
onFinish
.
accept
(
status
);
public
void
onFinish
(
ITaskInfo
task
)
{
boolean
complete
=
!
isCanceled
()
&&
task
.
getStatus
()
==
TaskStatus
.
COMPLETE
&&
task
.
getJobsComplete
()
==
task
.
getJobsCount
();
this
.
onFinish
.
accept
(
task
,
complete
);
}
@Override
...
...
@@ -131,7 +130,17 @@ public class SearchTask extends CancelableBackgroundTask {
}
@Override
public
@Nullable
Consumer
<
ITaskProgress
>
get
On
ProgressListener
()
{
public
@Nullable
Consumer
<
ITaskProgress
>
getProgressListener
()
{
return
this
.
progressListener
;
}
@Override
public
int
getCancelTimeoutMS
()
{
return
0
;
}
@Override
public
int
getShutdownTimeoutMS
()
{
return
10
;
}
}
jadx-gui/src/main/java/jadx/gui/ui/dialog/CommonSearchDialog.java
浏览文件 @
e641b773
...
...
@@ -14,11 +14,8 @@ import java.awt.event.WindowAdapter;
import
java.awt.event.WindowEvent
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Enumeration
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
javax.swing.AbstractAction
;
import
javax.swing.BorderFactory
;
...
...
@@ -77,9 +74,7 @@ public abstract class CommonSearchDialog extends JFrame {
protected
JLabel
warnLabel
;
protected
ProgressPanel
progressPane
;
private
String
highlightText
;
protected
boolean
highlightTextCaseInsensitive
=
false
;
protected
boolean
highlightTextUseRegex
=
false
;
private
SearchContext
highlightContext
;
public
CommonSearchDialog
(
MainWindow
mainWindow
,
String
title
)
{
this
.
mainWindow
=
mainWindow
;
...
...
@@ -88,7 +83,7 @@ public abstract class CommonSearchDialog extends JFrame {
this
.
codeFont
=
mainWindow
.
getSettings
().
getFont
();
this
.
windowTitle
=
title
;
UiUtils
.
setWindowIcons
(
this
);
updateTitle
();
updateTitle
(
""
);
}
protected
abstract
void
openInit
();
...
...
@@ -103,17 +98,24 @@ public abstract class CommonSearchDialog extends JFrame {
}
}
private
void
updateTitle
()
{
if
(
highlightText
==
null
||
highlight
Text
.
trim
().
isEmpty
())
{
private
void
updateTitle
(
String
searchText
)
{
if
(
searchText
==
null
||
searchText
.
isEmpty
()
||
search
Text
.
trim
().
isEmpty
())
{
setTitle
(
windowTitle
);
}
else
{
setTitle
(
windowTitle
+
": "
+
highlight
Text
);
setTitle
(
windowTitle
+
": "
+
search
Text
);
}
}
public
void
setHighlightText
(
String
highlightText
)
{
this
.
highlightText
=
highlightText
;
updateTitle
();
public
void
updateHighlightContext
(
String
text
,
boolean
caseSensitive
,
boolean
regexp
)
{
updateTitle
(
text
);
highlightContext
=
new
SearchContext
(
text
);
highlightContext
.
setMatchCase
(
caseSensitive
);
highlightContext
.
setRegularExpression
(
regexp
);
highlightContext
.
setMarkAll
(
true
);
}
public
void
disableHighlight
()
{
highlightContext
=
null
;
}
protected
void
registerInitOnOpen
()
{
...
...
@@ -174,16 +176,16 @@ public abstract class CommonSearchDialog extends JFrame {
openBtn
.
addActionListener
(
event
->
openSelectedItem
());
getRootPane
().
setDefaultButton
(
openBtn
);
JPanel
buttonPane
=
new
JPanel
();
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
JCheckBox
cbKeepOpen
=
new
JCheckBox
(
NLS
.
str
(
"search_dialog.keep_open"
));
cbKeepOpen
.
setSelected
(
mainWindow
.
getSettings
().
getKeepCommonDialogOpen
());
cbKeepOpen
.
addActionListener
(
e
->
{
mainWindow
.
getSettings
().
setKeepCommonDialogOpen
(
cbKeepOpen
.
isSelected
());
mainWindow
.
getSettings
().
sync
();
});
cbKeepOpen
.
setAlignmentY
(
Component
.
CENTER_ALIGNMENT
);
JPanel
buttonPane
=
new
JPanel
();
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
add
(
cbKeepOpen
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
15
,
0
)));
buttonPane
.
add
(
progressPane
);
...
...
@@ -197,7 +199,7 @@ public abstract class CommonSearchDialog extends JFrame {
protected
JPanel
initResultsTable
()
{
ResultsTableCellRenderer
renderer
=
new
ResultsTableCellRenderer
();
resultsModel
=
new
ResultsModel
(
renderer
);
resultsModel
=
new
ResultsModel
();
resultsModel
.
addTableModelListener
(
e
->
updateProgressLabel
(
false
));
resultsTable
=
new
ResultsTable
(
resultsModel
,
renderer
);
...
...
@@ -247,7 +249,6 @@ public abstract class CommonSearchDialog extends JFrame {
warnLabel
.
setVisible
(
false
);
JScrollPane
scroll
=
new
JScrollPane
(
resultsTable
,
VERTICAL_SCROLLBAR_AS_NEEDED
,
HORIZONTAL_SCROLLBAR_AS_NEEDED
);
// scroll.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
JPanel
resultsActionsPanel
=
new
JPanel
();
resultsActionsPanel
.
setLayout
(
new
BoxLayout
(
resultsActionsPanel
,
BoxLayout
.
LINE_AXIS
));
...
...
@@ -261,7 +262,6 @@ public abstract class CommonSearchDialog extends JFrame {
JPanel
resultsPanel
=
new
JPanel
();
resultsPanel
.
setLayout
(
new
BoxLayout
(
resultsPanel
,
BoxLayout
.
PAGE_AXIS
));
resultsPanel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
resultsPanel
.
add
(
warnLabel
,
BorderLayout
.
PAGE_START
);
resultsPanel
.
add
(
scroll
,
BorderLayout
.
CENTER
);
resultsPanel
.
add
(
resultsActionsPanel
,
BorderLayout
.
PAGE_END
);
...
...
@@ -288,13 +288,12 @@ public abstract class CommonSearchDialog extends JFrame {
protected
static
final
class
ResultsTable
extends
JTable
{
private
static
final
long
serialVersionUID
=
3901184054736618969L
;
private
final
transient
ResultsTableCellRenderer
renderer
;
private
final
transient
ResultsModel
model
;
public
ResultsTable
(
ResultsModel
resultsModel
,
ResultsTableCellRenderer
renderer
)
{
super
(
resultsModel
);
this
.
model
=
resultsModel
;
this
.
renderer
=
renderer
;
setRowHeight
(
renderer
.
getMaxRowHeight
())
;
}
public
void
initColumnWidth
()
{
...
...
@@ -309,6 +308,11 @@ public abstract class CommonSearchDialog extends JFrame {
public
void
updateTable
()
{
UiUtils
.
uiThreadGuard
();
int
rowCount
=
getRowCount
();
if
(
rowCount
==
0
)
{
updateUI
();
return
;
}
long
start
=
System
.
currentTimeMillis
();
int
width
=
getParent
().
getWidth
();
TableColumn
firstColumn
=
columnModel
.
getColumn
(
0
);
...
...
@@ -325,30 +329,6 @@ public abstract class CommonSearchDialog extends JFrame {
}
else
{
firstColumn
.
setPreferredWidth
(
width
);
}
int
rowCount
=
getRowCount
();
int
columnCount
=
getColumnCount
();
Map
<
Class
<?>,
Integer
>
heightByType
=
new
HashMap
<>();
for
(
int
row
=
0
;
row
<
rowCount
;
row
++)
{
Object
value
=
model
.
getValueAt
(
row
,
0
);
Class
<?>
valueType
=
value
.
getClass
();
Integer
cachedHeight
=
heightByType
.
get
(
valueType
);
if
(
cachedHeight
!=
null
)
{
setRowHeight
(
row
,
cachedHeight
);
}
else
{
int
height
=
0
;
for
(
int
col
=
0
;
col
<
columnCount
;
col
++)
{
Component
comp
=
prepareRenderer
(
renderer
,
row
,
col
);
if
(
comp
==
null
)
{
continue
;
}
Dimension
preferredSize
=
comp
.
getPreferredSize
();
int
h
=
Math
.
max
(
comp
.
getHeight
(),
preferredSize
.
height
);
height
=
Math
.
max
(
height
,
h
);
}
heightByType
.
put
(
valueType
,
height
);
setRowHeight
(
row
,
height
);
}
}
updateUI
();
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Update results table in {}ms, count: {}"
,
System
.
currentTimeMillis
()
-
start
,
rowCount
);
...
...
@@ -365,14 +345,9 @@ public abstract class CommonSearchDialog extends JFrame {
private
static
final
long
serialVersionUID
=
-
7821286846923903208L
;
private
static
final
String
[]
COLUMN_NAMES
=
{
NLS
.
str
(
"search_dialog.col_node"
),
NLS
.
str
(
"search_dialog.col_code"
)
};
private
final
transient
List
<
JNode
>
rows
=
Collections
.
synchronizedList
(
new
ArrayList
<>());
private
final
transient
ResultsTableCellRenderer
renderer
;
private
final
transient
List
<
JNode
>
rows
=
new
ArrayList
<>();
private
transient
boolean
addDescColumn
;
public
ResultsModel
(
ResultsTableCellRenderer
renderer
)
{
this
.
renderer
=
renderer
;
}
public
void
addAll
(
Collection
<?
extends
JNode
>
nodes
)
{
rows
.
addAll
(
nodes
);
if
(!
addDescColumn
)
{
...
...
@@ -388,7 +363,6 @@ public abstract class CommonSearchDialog extends JFrame {
public
void
clear
()
{
addDescColumn
=
false
;
rows
.
clear
();
renderer
.
clear
();
}
public
boolean
isAddDescColumn
()
{
...
...
@@ -417,38 +391,36 @@ public abstract class CommonSearchDialog extends JFrame {
}
protected
final
class
ResultsTableCellRenderer
implements
TableCellRenderer
{
private
final
JLabel
emptyLabel
=
new
JLabel
();
private
final
Font
font
;
private
final
JLabel
label
;
private
final
RSyntaxTextArea
codeArea
;
private
final
JLabel
emptyLabel
;
private
final
Color
codeSelectedColor
;
private
final
Color
codeBackground
;
private
final
Map
<
Integer
,
Component
>
componentCache
=
new
HashMap
<>();
public
ResultsTableCellRenderer
()
{
RSyntaxTextArea
area
=
AbstractCodeArea
.
getDefaultArea
(
mainWindow
);
this
.
font
=
area
.
getFont
();
this
.
codeSelectedColor
=
area
.
getSelectionColor
();
this
.
codeBackground
=
area
.
getBackground
();
codeArea
=
AbstractCodeArea
.
getDefaultArea
(
mainWindow
);
codeArea
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
0
,
10
));
codeArea
.
setRows
(
1
);
codeBackground
=
codeArea
.
getBackground
();
codeSelectedColor
=
codeArea
.
getSelectionColor
();
label
=
new
JLabel
();
label
.
setOpaque
(
true
);
label
.
setFont
(
codeArea
.
getFont
());
label
.
setHorizontalAlignment
(
SwingConstants
.
LEFT
);
emptyLabel
=
new
JLabel
();
emptyLabel
.
setOpaque
(
true
);
}
@Override
public
Component
getTableCellRendererComponent
(
JTable
table
,
Object
obj
,
boolean
isSelected
,
boolean
hasFocus
,
int
row
,
int
column
)
{
Component
comp
=
componentCache
.
computeIfAbsent
(
makeID
(
row
,
column
),
id
->
{
if
(
obj
instanceof
JNode
)
{
return
makeCell
((
JNode
)
obj
,
column
);
}
return
emptyLabel
;
});
updateSelection
(
table
,
comp
,
isSelected
);
Component
comp
=
makeCell
((
JNode
)
obj
,
column
);
updateSelection
(
table
,
comp
,
column
,
isSelected
);
return
comp
;
}
private
int
makeID
(
int
row
,
int
col
)
{
return
row
<<
2
|
(
col
&
0b11
);
}
private
void
updateSelection
(
JTable
table
,
Component
comp
,
boolean
isSelected
)
{
if
(
comp
instanceof
RSyntaxTextArea
)
{
private
void
updateSelection
(
JTable
table
,
Component
comp
,
int
column
,
boolean
isSelected
)
{
if
(
column
==
1
)
{
if
(
isSelected
)
{
comp
.
setBackground
(
codeSelectedColor
);
}
else
{
...
...
@@ -467,39 +439,32 @@ public abstract class CommonSearchDialog extends JFrame {
private
Component
makeCell
(
JNode
node
,
int
column
)
{
if
(
column
==
0
)
{
JLabel
label
=
new
JLabel
(
node
.
makeLongStringHtml
(),
node
.
getIcon
(),
SwingConstants
.
LEFT
);
label
.
setFont
(
font
);
label
.
setOpaque
(
true
);
label
.
setText
(
node
.
makeLongStringHtml
());
label
.
setToolTipText
(
label
.
getText
());
label
.
setIcon
(
node
.
getIcon
());
return
label
;
}
if
(!
node
.
hasDescString
())
{
return
emptyLabel
;
}
RSyntaxTextArea
textArea
=
AbstractCodeArea
.
getDefaultArea
(
mainWindow
);
textArea
.
setSyntaxEditingStyle
(
node
.
getSyntaxName
());
codeArea
.
setSyntaxEditingStyle
(
node
.
getSyntaxName
());
String
descStr
=
node
.
makeDescString
();
textArea
.
setText
(
descStr
);
if
(
descStr
.
contains
(
"\n"
))
{
textArea
.
setRows
(
textArea
.
getLineCount
());
}
else
{
textArea
.
setRows
(
1
);
textArea
.
setColumns
(
descStr
.
length
()
+
1
);
}
if
(
highlightText
!=
null
)
{
SearchContext
searchContext
=
new
SearchContext
(
highlightText
);
searchContext
.
setMatchCase
(!
highlightTextCaseInsensitive
);
searchContext
.
setRegularExpression
(
highlightTextUseRegex
);
searchContext
.
setMarkAll
(
true
);
SearchEngine
.
markAll
(
textArea
,
searchContext
);
codeArea
.
setText
(
descStr
);
codeArea
.
setColumns
(
descStr
.
length
()
+
1
);
if
(
highlightContext
!=
null
)
{
SearchEngine
.
markAll
(
codeArea
,
highlightContext
);
}
textArea
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
0
,
10
));
return
textArea
;
return
codeArea
;
}
public
void
clear
()
{
componentCache
.
clear
();
public
int
getMaxRowHeight
()
{
label
.
setText
(
"Text"
);
codeArea
.
setText
(
"Text"
);
return
Math
.
max
(
getCompHeight
(
label
),
getCompHeight
(
codeArea
));
}
private
int
getCompHeight
(
Component
comp
)
{
return
Math
.
max
(
comp
.
getHeight
(),
comp
.
getPreferredSize
().
height
);
}
}
...
...
jadx-gui/src/main/java/jadx/gui/ui/dialog/SearchDialog.java
浏览文件 @
e641b773
...
...
@@ -2,7 +2,6 @@ package jadx.gui.ui.dialog;
import
java.awt.BorderLayout
;
import
java.awt.Color
;
import
java.awt.Container
;
import
java.awt.Dimension
;
import
java.awt.FlowLayout
;
import
java.awt.event.KeyAdapter
;
...
...
@@ -13,6 +12,8 @@ import java.util.EnumSet;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Set
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
javax.swing.BorderFactory
;
...
...
@@ -25,21 +26,20 @@ import javax.swing.JPanel;
import
javax.swing.JTextField
;
import
javax.swing.WindowConstants
;
import
javax.swing.event.ChangeListener
;
import
javax.swing.event.DocumentEvent
;
import
javax.swing.event.DocumentListener
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
hu.akarnokd.rxjava2.swing.SwingSchedulers
;
import
io.reactivex.BackpressureStrategy
;
import
io.reactivex.Emitter
;
import
io.reactivex.Flowable
;
import
io.reactivex.disposables.Disposable
;
import
io.reactivex.schedulers.Schedulers
;
import
jadx.api.JavaClass
;
import
jadx.core.utils.ListUtils
;
import
jadx.gui.jobs.ITaskInfo
;
import
jadx.gui.jobs.ITaskProgress
;
import
jadx.gui.search.SearchSettings
;
import
jadx.gui.search.SearchTask
;
...
...
@@ -58,6 +58,7 @@ import jadx.gui.utils.NLS;
import
jadx.gui.utils.TextStandardActions
;
import
jadx.gui.utils.UiUtils
;
import
jadx.gui.utils.layout.WrapLayout
;
import
jadx.gui.utils.ui.DocumentUpdateListener
;
import
static
jadx
.
gui
.
ui
.
dialog
.
SearchDialog
.
SearchOptions
.
ACTIVE_TAB
;
import
static
jadx
.
gui
.
ui
.
dialog
.
SearchDialog
.
SearchOptions
.
CLASS
;
...
...
@@ -128,6 +129,11 @@ public class SearchDialog extends CommonSearchDialog {
// temporal list for pending results
private
final
List
<
JNode
>
pendingResults
=
new
ArrayList
<>();
/**
* Use single thread to do all background work, so additional synchronisation not needed
*/
private
final
Executor
searchBackgroundExecutor
=
Executors
.
newSingleThreadExecutor
();
private
SearchDialog
(
MainWindow
mainWindow
,
SearchPreset
preset
,
Set
<
SearchOptions
>
additionalOptions
)
{
super
(
mainWindow
,
NLS
.
str
(
"menu.text_search"
));
this
.
searchPreset
=
preset
;
...
...
@@ -148,13 +154,10 @@ public class SearchDialog extends CommonSearchDialog {
}
resultsModel
.
clear
();
removeActiveTabListener
();
if
(
searchTask
!=
null
)
{
searchTask
.
cancel
();
mainWindow
.
getBackgroundExecutor
().
execute
(
NLS
.
str
(
"progress.load"
),
()
->
{
stopSearchTask
();
unloadTempData
();
});
}
searchBackgroundExecutor
.
execute
(()
->
{
stopSearchTask
();
unloadTempData
();
});
super
.
dispose
();
}
...
...
@@ -167,7 +170,7 @@ public class SearchDialog extends CommonSearchDialog {
case
TEXT:
if
(
searchOptions
.
isEmpty
())
{
searchOptions
.
add
(
SearchOptions
.
CODE
);
searchOptions
.
add
(
SearchOptions
.
IGNORE_CASE
);
searchOptions
.
add
(
IGNORE_CASE
);
}
break
;
...
...
@@ -205,16 +208,20 @@ public class SearchDialog extends CommonSearchDialog {
searchField
.
setAlignmentX
(
LEFT_ALIGNMENT
);
TextStandardActions
.
attach
(
searchField
);
JPanel
searchLinePanel
=
new
JPanel
();
searchLinePanel
.
setLayout
(
new
BoxLayout
(
searchLinePanel
,
BoxLayout
.
LINE_AXIS
));
searchLinePanel
.
add
(
searchField
);
searchLinePanel
.
setAlignmentX
(
LEFT_ALIGNMENT
);
JLabel
findLabel
=
new
JLabel
(
NLS
.
str
(
"search_dialog.open_by_name"
));
findLabel
.
setAlignmentX
(
LEFT_ALIGNMENT
);
JPanel
searchFieldPanel
=
new
JPanel
();
searchFieldPanel
.
setLayout
(
new
BoxLayout
(
searchFieldPanel
,
BoxLayout
.
PAGE_AXIS
));
searchFieldPanel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
5
,
0
,
5
));
searchFieldPanel
.
setAlignmentX
(
LEFT_ALIGNMENT
);
searchFieldPanel
.
add
(
findLabel
);
searchFieldPanel
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
0
,
5
)));
searchFieldPanel
.
add
(
search
Field
);
searchFieldPanel
.
add
(
search
LinePanel
);
JPanel
searchInPanel
=
new
JPanel
(
new
FlowLayout
(
FlowLayout
.
LEFT
));
searchInPanel
.
setBorder
(
BorderFactory
.
createTitledBorder
(
NLS
.
str
(
"search_dialog.search_in"
)));
...
...
@@ -227,18 +234,17 @@ public class SearchDialog extends CommonSearchDialog {
JPanel
searchOptions
=
new
JPanel
(
new
FlowLayout
(
FlowLayout
.
LEFT
));
searchOptions
.
setBorder
(
BorderFactory
.
createTitledBorder
(
NLS
.
str
(
"search_dialog.options"
)));
searchOptions
.
add
(
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.ignorecase"
),
SearchOptions
.
IGNORE_CASE
));
searchOptions
.
add
(
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.regex"
),
SearchOptions
.
USE_REGEX
));
searchOptions
.
add
(
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.ignorecase"
),
IGNORE_CASE
));
searchOptions
.
add
(
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.regex"
),
USE_REGEX
));
searchOptions
.
add
(
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.active_tab"
),
SearchOptions
.
ACTIVE_TAB
));
JPanel
optionsPanel
=
new
JPanel
(
new
WrapLayout
(
WrapLayout
.
LEFT
));
JPanel
optionsPanel
=
new
JPanel
(
new
WrapLayout
(
WrapLayout
.
LEFT
,
0
,
0
));
optionsPanel
.
setAlignmentX
(
LEFT_ALIGNMENT
);
optionsPanel
.
add
(
searchInPanel
);
optionsPanel
.
add
(
searchOptions
);
JPanel
searchPane
=
new
JPanel
();
searchPane
.
setLayout
(
new
BoxLayout
(
searchPane
,
BoxLayout
.
PAGE_AXIS
));
searchPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
searchPane
.
add
(
searchFieldPanel
);
searchPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
0
,
5
)));
searchPane
.
add
(
optionsPanel
);
...
...
@@ -247,10 +253,13 @@ public class SearchDialog extends CommonSearchDialog {
JPanel
resultsPanel
=
initResultsTable
();
JPanel
buttonPane
=
initButtonsPanel
();
Container
contentPane
=
getContentPane
();
contentPane
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPane
.
add
(
resultsPanel
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
JPanel
contentPanel
=
new
JPanel
();
contentPanel
.
setLayout
(
new
BorderLayout
(
5
,
5
));
contentPanel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
contentPanel
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPanel
.
add
(
resultsPanel
,
BorderLayout
.
CENTER
);
contentPanel
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
getContentPane
().
add
(
contentPanel
);
searchField
.
addKeyListener
(
new
KeyAdapter
()
{
@Override
...
...
@@ -269,11 +278,11 @@ public class SearchDialog extends CommonSearchDialog {
protected
void
addCustomResultsActions
(
JPanel
resultsActionsPanel
)
{
loadAllButton
=
new
JButton
(
NLS
.
str
(
"search_dialog.load_all"
));
loadAllButton
.
addActionListener
(
e
->
load
All
(
));
loadAllButton
.
addActionListener
(
e
->
load
MoreResults
(
true
));
loadAllButton
.
setEnabled
(
false
);
loadMoreButton
=
new
JButton
(
NLS
.
str
(
"search_dialog.load_more"
));
loadMoreButton
.
addActionListener
(
e
->
loadMore
(
));
loadMoreButton
.
addActionListener
(
e
->
loadMore
Results
(
false
));
loadMoreButton
.
setEnabled
(
false
);
resultsActionsPanel
.
add
(
loadAllButton
);
...
...
@@ -307,21 +316,36 @@ public class SearchDialog extends CommonSearchDialog {
Flowable
<
String
>
textChanges
=
onTextFieldChanges
(
searchField
);
Flowable
<
String
>
searchEvents
=
Flowable
.
merge
(
textChanges
,
searchEmitter
.
getFlowable
());
searchDisposable
=
searchEvents
.
debounce
(
50
0
,
TimeUnit
.
MILLISECONDS
)
.
observeOn
(
S
wingSchedulers
.
edt
(
))
.
debounce
(
50
,
TimeUnit
.
MILLISECONDS
)
.
observeOn
(
S
chedulers
.
from
(
searchBackgroundExecutor
))
.
subscribe
(
this
::
search
);
}
@Nullable
private
synchronized
void
search
(
String
text
)
{
UiUtils
.
uiThreadGuard
();
resetSearch
();
if
(
text
==
null
||
options
.
isEmpty
())
{
private
void
search
(
String
text
)
{
UiUtils
.
notUiThreadGuard
();
stopSearchTask
();
UiUtils
.
uiRun
(
this
::
resetSearch
);
searchTask
=
prepareSearch
(
text
);
if
(
searchTask
==
null
)
{
return
;
}
UiUtils
.
uiRunAndWait
(()
->
{
updateTableHighlight
();
prepareForSearch
();
});
this
.
searchTask
.
setResultsLimit
(
50
);
this
.
searchTask
.
setProgressListener
(
this
::
updateProgress
);
this
.
searchTask
.
fetchResults
();
LOG
.
debug
(
"Total search items count estimation: {}"
,
this
.
searchTask
.
getTaskProgress
().
total
());
}
private
SearchTask
prepareSearch
(
String
text
)
{
if
(
text
==
null
||
options
.
isEmpty
())
{
return
null
;
}
// allow empty text for comments search
if
(
text
.
isEmpty
()
&&
!
options
.
contains
(
SearchOptions
.
COMMENT
))
{
return
;
return
null
;
}
LOG
.
debug
(
"Building search for '{}', options: {}"
,
text
,
options
);
boolean
ignoreCase
=
options
.
contains
(
IGNORE_CASE
);
...
...
@@ -335,24 +359,16 @@ public class SearchDialog extends CommonSearchDialog {
}
else
{
searchField
.
setBackground
(
SEARCH_FIELD_ERROR_COLOR
);
resultsInfoLabel
.
setText
(
error
);
return
;
return
null
;
}
searchTask
=
new
SearchTask
(
mainWindow
,
this
::
addSearchResult
,
s
->
searchComplete
()
);
if
(!
buildSearch
(
text
,
searchSettings
))
{
return
;
SearchTask
newSearchTask
=
new
SearchTask
(
mainWindow
,
this
::
addSearchResult
,
this
::
searchFinished
);
if
(!
buildSearch
(
newSearchTask
,
text
,
searchSettings
))
{
return
null
;
}
updateTableHighlight
();
startSearch
();
searchTask
.
setResultsLimit
(
100
);
searchTask
.
setProgressListener
(
this
::
updateProgress
);
searchTask
.
fetchResults
();
LOG
.
debug
(
"Total search items count estimation: {}"
,
searchTask
.
getTaskProgress
().
total
());
return
newSearchTask
;
}
private
boolean
buildSearch
(
String
text
,
SearchSettings
searchSettings
)
{
Objects
.
requireNonNull
(
searchTask
);
private
boolean
buildSearch
(
SearchTask
newSearchTask
,
String
text
,
SearchSettings
searchSettings
)
{
List
<
JavaClass
>
allClasses
;
if
(
options
.
contains
(
ACTIVE_TAB
))
{
JumpPosition
currentPos
=
mainWindow
.
getTabbedPane
().
getCurrentPosition
();
...
...
@@ -368,7 +384,7 @@ public class SearchDialog extends CommonSearchDialog {
}
// allow empty text for comments search
if
(
text
.
isEmpty
()
&&
options
.
contains
(
SearchOptions
.
COMMENT
))
{
s
earchTask
.
addProviderJob
(
new
CommentSearchProvider
(
mainWindow
,
searchSettings
));
newS
earchTask
.
addProviderJob
(
new
CommentSearchProvider
(
mainWindow
,
searchSettings
));
return
true
;
}
// using ordered execution for fast tasks
...
...
@@ -384,84 +400,92 @@ public class SearchDialog extends CommonSearchDialog {
}
if
(
options
.
contains
(
CODE
))
{
if
(
allClasses
.
size
()
==
1
)
{
s
earchTask
.
addProviderJob
(
new
CodeSearchProvider
(
mainWindow
,
searchSettings
,
allClasses
));
newS
earchTask
.
addProviderJob
(
new
CodeSearchProvider
(
mainWindow
,
searchSettings
,
allClasses
));
}
else
{
List
<
JavaClass
>
topClasses
=
ListUtils
.
filter
(
allClasses
,
c
->
!
c
.
isInner
());
for
(
List
<
JavaClass
>
batch
:
mainWindow
.
getWrapper
().
buildDecompileBatches
(
topClasses
))
{
searchTask
.
addProviderJob
(
new
CodeSearchProvider
(
mainWindow
,
searchSettings
,
batch
));
List
<
List
<
JavaClass
>>
batches
=
mainWindow
.
getCacheObject
().
getDecompileBatches
();
if
(
batches
==
null
)
{
List
<
JavaClass
>
topClasses
=
ListUtils
.
filter
(
allClasses
,
c
->
!
c
.
isInner
());
batches
=
mainWindow
.
getWrapper
().
buildDecompileBatches
(
topClasses
);
mainWindow
.
getCacheObject
().
setDecompileBatches
(
batches
);
}
for
(
List
<
JavaClass
>
batch
:
batches
)
{
newSearchTask
.
addProviderJob
(
new
CodeSearchProvider
(
mainWindow
,
searchSettings
,
batch
));
}
}
}
if
(
options
.
contains
(
RESOURCE
))
{
s
earchTask
.
addProviderJob
(
new
ResourceSearchProvider
(
mainWindow
,
searchSettings
));
newS
earchTask
.
addProviderJob
(
new
ResourceSearchProvider
(
mainWindow
,
searchSettings
));
}
if
(
options
.
contains
(
COMMENT
))
{
s
earchTask
.
addProviderJob
(
new
CommentSearchProvider
(
mainWindow
,
searchSettings
));
newS
earchTask
.
addProviderJob
(
new
CommentSearchProvider
(
mainWindow
,
searchSettings
));
}
merged
.
prepare
();
s
earchTask
.
addProviderJob
(
merged
);
newS
earchTask
.
addProviderJob
(
merged
);
return
true
;
}
private
synchronized
void
stopSearchTask
()
{
private
void
stopSearchTask
()
{
UiUtils
.
notUiThreadGuard
();
if
(
searchTask
!=
null
)
{
searchTask
.
cancel
();
searchTask
.
waitTask
();
searchTask
=
null
;
}
}
private
synchronized
void
loadMore
()
{
if
(
searchTask
==
null
)
{
return
;
}
startSearch
();
searchTask
.
fetchResults
();
}
private
synchronized
void
loadAll
()
{
if
(
searchTask
==
null
)
{
return
;
}
startSearch
();
searchTask
.
setResultsLimit
(
0
);
searchTask
.
fetchResults
();
private
void
loadMoreResults
(
boolean
all
)
{
searchBackgroundExecutor
.
execute
(()
->
{
if
(
searchTask
==
null
)
{
return
;
}
searchTask
.
cancel
();
searchTask
.
waitTask
();
UiUtils
.
uiRunAndWait
(
this
::
prepareForSearch
);
if
(
all
)
{
searchTask
.
setResultsLimit
(
0
);
}
searchTask
.
fetchResults
();
});
}
private
synchronized
void
resetSearch
()
{
private
void
resetSearch
()
{
UiUtils
.
uiThreadGuard
();
resultsModel
.
clear
();
updateTable
();
resultsTable
.
updateTable
();
synchronized
(
pendingResults
)
{
pendingResults
.
clear
();
}
progressPane
.
setVisible
(
false
);
warnLabel
.
setVisible
(
false
);
loadAllButton
.
setEnabled
(
false
);
loadMoreButton
.
setEnabled
(
false
);
stopSearchTask
();
}
private
void
start
Search
()
{
private
void
prepareFor
Search
()
{
showSearchState
();
progressStartCommon
();
}
private
void
addSearchResult
(
JNode
node
)
{
synchronized
(
pendingResults
)
{
UiUtils
.
notUiThreadGuard
();
pendingResults
.
add
(
node
);
}
}
private
void
updateTable
()
{
synchronized
(
pendingResults
)
{
UiUtils
.
uiThreadGuard
();
Collections
.
sort
(
pendingResults
);
resultsModel
.
addAll
(
pendingResults
);
pendingResults
.
clear
();
resultsTable
.
updateTable
();
}
resultsTable
.
updateTable
();
}
private
void
updateTableHighlight
()
{
String
text
=
searchField
.
getText
();
setHighlightText
(
text
);
highlightTextCaseInsensitive
=
options
.
contains
(
SearchOptions
.
IGNORE_CASE
);
highlightTextUseRegex
=
options
.
contains
(
SearchOptions
.
USE_REGEX
);
updateHighlightContext
(
text
,
!
options
.
contains
(
IGNORE_CASE
),
options
.
contains
(
USE_REGEX
));
cache
.
setLastSearch
(
text
);
cache
.
getLastSearchOptions
().
put
(
searchPreset
,
options
);
}
...
...
@@ -473,17 +497,14 @@ public class SearchDialog extends CommonSearchDialog {
});
}
private
synchronized
void
searchComplete
(
)
{
private
void
searchFinished
(
ITaskInfo
status
,
Boolean
complete
)
{
UiUtils
.
uiThreadGuard
();
LOG
.
debug
(
"Search complete"
);
updateTable
();
boolean
complete
=
searchTask
==
null
||
searchTask
.
isSearchComplete
();
LOG
.
debug
(
"Search complete: {}, complete: {}"
,
status
,
complete
);
loadAllButton
.
setEnabled
(!
complete
);
loadMoreButton
.
setEnabled
(!
complete
);
updateProgressLabel
(
complete
);
unloadTempData
();
progressFinishedCommon
();
updateTable
();
updateProgressLabel
(
complete
);
}
private
void
unloadTempData
()
{
...
...
@@ -493,26 +514,8 @@ public class SearchDialog extends CommonSearchDialog {
private
static
Flowable
<
String
>
onTextFieldChanges
(
final
JTextField
textField
)
{
return
Flowable
.<
String
>
create
(
emitter
->
{
DocumentListener
listener
=
new
DocumentListener
()
{
@Override
public
void
insertUpdate
(
DocumentEvent
e
)
{
change
();
}
@Override
public
void
removeUpdate
(
DocumentEvent
e
)
{
change
();
}
@Override
public
void
changedUpdate
(
DocumentEvent
e
)
{
change
();
}
public
void
change
()
{
emitter
.
onNext
(
textField
.
getText
());
}
};
DocumentUpdateListener
listener
=
new
DocumentUpdateListener
(
ev
->
emitter
.
onNext
(
textField
.
getText
()));
textField
.
getDocument
().
addDocumentListener
(
listener
);
emitter
.
setDisposable
(
new
Disposable
()
{
...
...
jadx-gui/src/main/java/jadx/gui/ui/dialog/UsageDialog.java
浏览文件 @
e641b773
package
jadx.gui.ui.dialog
;
import
java.awt.BorderLayout
;
import
java.awt.Container
;
import
java.awt.FlowLayout
;
import
java.awt.Font
;
import
java.util.ArrayList
;
...
...
@@ -132,8 +131,7 @@ public class UsageDialog extends CommonSearchDialog {
Collections
.
sort
(
usageList
);
resultsModel
.
addAll
(
usageList
);
// TODO: highlight only needed node usage
setHighlightText
(
null
);
updateHighlightContext
(
node
.
getName
(),
true
,
false
);
resultsTable
.
initColumnWidth
();
resultsTable
.
updateTable
();
updateProgressLabel
(
true
);
...
...
@@ -163,10 +161,13 @@ public class UsageDialog extends CommonSearchDialog {
JPanel
resultsPanel
=
initResultsTable
();
JPanel
buttonPane
=
initButtonsPanel
();
Container
contentPane
=
getContentPane
();
contentPane
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPane
.
add
(
resultsPanel
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
JPanel
contentPanel
=
new
JPanel
();
contentPanel
.
setLayout
(
new
BorderLayout
(
5
,
5
));
contentPanel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
contentPanel
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPanel
.
add
(
resultsPanel
,
BorderLayout
.
CENTER
);
contentPanel
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
getContentPane
().
add
(
contentPanel
);
pack
();
setSize
(
800
,
500
);
...
...
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
浏览文件 @
e641b773
package
jadx.gui.utils
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.api.JavaClass
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.treemodel.JRoot
;
import
jadx.gui.ui.dialog.SearchDialog
;
...
...
@@ -19,6 +21,8 @@ public class CacheObject {
private
JRoot
jRoot
;
private
JadxSettings
settings
;
private
List
<
List
<
JavaClass
>>
decompileBatches
;
public
CacheObject
()
{
reset
();
}
...
...
@@ -29,6 +33,7 @@ public class CacheObject {
lastSearch
=
null
;
jNodeCache
=
new
JNodeCache
();
lastSearchOptions
=
new
HashMap
<>();
decompileBatches
=
null
;
}
@Nullable
...
...
@@ -63,4 +68,12 @@ public class CacheObject {
public
void
setJRoot
(
JRoot
jRoot
)
{
this
.
jRoot
=
jRoot
;
}
public
@Nullable
List
<
List
<
JavaClass
>>
getDecompileBatches
()
{
return
decompileBatches
;
}
public
void
setDecompileBatches
(
List
<
List
<
JavaClass
>>
decompileBatches
)
{
this
.
decompileBatches
=
decompileBatches
;
}
}
jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java
浏览文件 @
e641b773
...
...
@@ -374,6 +374,8 @@ public class UiUtils {
}
try
{
SwingUtilities
.
invokeAndWait
(
runnable
);
}
catch
(
InterruptedException
e
)
{
LOG
.
warn
(
"UI thread interrupted"
,
e
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
...
...
@@ -385,6 +387,12 @@ public class UiUtils {
}
}
public
static
void
notUiThreadGuard
()
{
if
(
SwingUtilities
.
isEventDispatchThread
())
{
LOG
.
warn
(
"Expect background thread, got: {}"
,
Thread
.
currentThread
(),
new
JadxRuntimeException
());
}
}
@TestOnly
public
static
void
debugTimer
(
int
periodInSeconds
,
Runnable
action
)
{
if
(!
LOG
.
isDebugEnabled
())
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录