mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-15 18:02:58 +08:00
chore!: migrate to version 2.x
This commit is contained in:
19
plugins/editor/build.gradle.kts
Normal file
19
plugins/editor/build.gradle.kts
Normal file
@@ -0,0 +1,19 @@
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.jvm)
|
||||
}
|
||||
|
||||
|
||||
|
||||
project.version = "0.0.3"
|
||||
|
||||
|
||||
dependencies {
|
||||
testImplementation(kotlin("test"))
|
||||
compileOnly(project(":"))
|
||||
implementation("com.fifesoft:rsyntaxtextarea:3.6.0")
|
||||
implementation("com.fifesoft:languagesupport:3.3.0")
|
||||
implementation("com.fifesoft:autocomplete:3.3.2")
|
||||
}
|
||||
|
||||
apply(from = "$rootDir/plugins/common.gradle.kts")
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package app.termora.plugins.editor
|
||||
|
||||
import app.termora.DialogWrapper
|
||||
import app.termora.Disposable
|
||||
import app.termora.Disposer
|
||||
import app.termora.OptionPane
|
||||
import app.termora.sftp.absolutePathString
|
||||
import org.apache.commons.vfs2.FileObject
|
||||
import java.awt.Dimension
|
||||
import java.awt.Window
|
||||
import java.awt.event.WindowAdapter
|
||||
import java.awt.event.WindowEvent
|
||||
import java.io.File
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JOptionPane
|
||||
import javax.swing.UIManager
|
||||
|
||||
|
||||
class EditorDialog(file: FileObject, owner: Window, myDisposable: Disposable) : DialogWrapper(null) {
|
||||
|
||||
private val filename = file.name.baseName
|
||||
private val filepath = File(file.absolutePathString())
|
||||
private val editorPanel = EditorPanel(this, filepath)
|
||||
|
||||
init {
|
||||
Disposer.register(disposable, myDisposable)
|
||||
|
||||
size = Dimension(UIManager.getInt("Dialog.width"), UIManager.getInt("Dialog.height"))
|
||||
isModal = false
|
||||
controlsVisible = true
|
||||
isResizable = true
|
||||
title = filename
|
||||
iconImages = owner.iconImages
|
||||
escapeDispose = false
|
||||
defaultCloseOperation = DO_NOTHING_ON_CLOSE
|
||||
|
||||
initEvents()
|
||||
|
||||
setLocationRelativeTo(owner)
|
||||
|
||||
init()
|
||||
}
|
||||
|
||||
|
||||
private fun initEvents() {
|
||||
addWindowListener(object : WindowAdapter() {
|
||||
override fun windowClosing(e: WindowEvent?) {
|
||||
doCancelAction()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun doCancelAction() {
|
||||
if (editorPanel.changes()) {
|
||||
if (OptionPane.showConfirmDialog(
|
||||
this,
|
||||
"文件尚未保存,你确定要退出吗?",
|
||||
optionType = JOptionPane.OK_CANCEL_OPTION,
|
||||
) != JOptionPane.OK_OPTION
|
||||
) {
|
||||
return
|
||||
}
|
||||
}
|
||||
super.doCancelAction()
|
||||
}
|
||||
|
||||
override fun createCenterPanel(): JComponent {
|
||||
return editorPanel
|
||||
}
|
||||
|
||||
override fun createSouthPanel(): JComponent? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package app.termora.plugins.editor
|
||||
|
||||
import app.termora.DocumentAdaptor
|
||||
import app.termora.DynamicColor
|
||||
import app.termora.Icons
|
||||
import app.termora.database.DatabaseManager
|
||||
import com.formdev.flatlaf.FlatLaf
|
||||
import com.formdev.flatlaf.extras.components.FlatTextField
|
||||
import com.formdev.flatlaf.extras.components.FlatToolBar
|
||||
import org.apache.commons.io.FilenameUtils
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants
|
||||
import org.fife.ui.rsyntaxtextarea.Theme
|
||||
import org.fife.ui.rtextarea.RTextScrollPane
|
||||
import org.fife.ui.rtextarea.SearchContext
|
||||
import org.fife.ui.rtextarea.SearchEngine
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Insets
|
||||
import java.awt.event.ActionEvent
|
||||
import java.awt.event.KeyEvent
|
||||
import java.awt.event.WindowAdapter
|
||||
import java.awt.event.WindowEvent
|
||||
import java.io.File
|
||||
import javax.swing.*
|
||||
import javax.swing.event.DocumentEvent
|
||||
import kotlin.math.max
|
||||
|
||||
class EditorPanel(private val window: JDialog, private val file: File) : JPanel(BorderLayout()) {
|
||||
private var text = file.readText(Charsets.UTF_8)
|
||||
private val layeredPane = LayeredPane()
|
||||
|
||||
private val textArea = RSyntaxTextArea()
|
||||
private val scrollPane = RTextScrollPane(textArea)
|
||||
private val findPanel = FlatToolBar().apply { isFloatable = false }
|
||||
private val searchTextField = FlatTextField()
|
||||
private val closeFindPanelBtn = JButton(Icons.close)
|
||||
private val nextBtn = JButton(Icons.down)
|
||||
private val prevBtn = JButton(Icons.up)
|
||||
private val context = SearchContext()
|
||||
|
||||
init {
|
||||
initView()
|
||||
initEvents()
|
||||
}
|
||||
|
||||
|
||||
private fun initView() {
|
||||
textArea.font = textArea.font.deriveFont(DatabaseManager.getInstance().terminal.fontSize.toFloat())
|
||||
textArea.text = text
|
||||
textArea.antiAliasingEnabled = true
|
||||
|
||||
val theme = if (FlatLaf.isLafDark())
|
||||
Theme.load(javaClass.getResourceAsStream("/org/fife/ui/rsyntaxtextarea/themes/dark.xml"))
|
||||
else
|
||||
Theme.load(javaClass.getResourceAsStream("/org/fife/ui/rsyntaxtextarea/themes/idea.xml"))
|
||||
|
||||
theme.apply(textArea)
|
||||
|
||||
val extension = FilenameUtils.getExtension(file.name)?.lowercase()
|
||||
textArea.syntaxEditingStyle = when (extension) {
|
||||
"java" -> SyntaxConstants.SYNTAX_STYLE_JAVA
|
||||
"kt" -> SyntaxConstants.SYNTAX_STYLE_KOTLIN
|
||||
"properties" -> SyntaxConstants.SYNTAX_STYLE_PROPERTIES_FILE
|
||||
"cpp", "c++" -> SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS
|
||||
"c" -> SyntaxConstants.SYNTAX_STYLE_C
|
||||
"cs" -> SyntaxConstants.SYNTAX_STYLE_CSHARP
|
||||
"css" -> SyntaxConstants.SYNTAX_STYLE_CSS
|
||||
"html", "htm", "htmlx" -> SyntaxConstants.SYNTAX_STYLE_HTML
|
||||
"js" -> SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT
|
||||
"ts" -> SyntaxConstants.SYNTAX_STYLE_TYPESCRIPT
|
||||
"xml", "svg" -> SyntaxConstants.SYNTAX_STYLE_XML
|
||||
"yaml", "yml" -> SyntaxConstants.SYNTAX_STYLE_YAML
|
||||
"sh", "shell" -> SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL
|
||||
"sql" -> SyntaxConstants.SYNTAX_STYLE_SQL
|
||||
"bat" -> SyntaxConstants.SYNTAX_STYLE_WINDOWS_BATCH
|
||||
"py" -> SyntaxConstants.SYNTAX_STYLE_PYTHON
|
||||
"php" -> SyntaxConstants.SYNTAX_STYLE_PHP
|
||||
"lua" -> SyntaxConstants.SYNTAX_STYLE_LUA
|
||||
"less" -> SyntaxConstants.SYNTAX_STYLE_LESS
|
||||
"jsp" -> SyntaxConstants.SYNTAX_STYLE_JSP
|
||||
"json" -> SyntaxConstants.SYNTAX_STYLE_JSON
|
||||
"ini" -> SyntaxConstants.SYNTAX_STYLE_INI
|
||||
"hosts" -> SyntaxConstants.SYNTAX_STYLE_HOSTS
|
||||
"go" -> SyntaxConstants.SYNTAX_STYLE_GO
|
||||
"dtd" -> SyntaxConstants.SYNTAX_STYLE_DTD
|
||||
"dart" -> SyntaxConstants.SYNTAX_STYLE_DART
|
||||
"csv" -> SyntaxConstants.SYNTAX_STYLE_CSV
|
||||
"md" -> SyntaxConstants.SYNTAX_STYLE_MARKDOWN
|
||||
else -> SyntaxConstants.SYNTAX_STYLE_NONE
|
||||
}
|
||||
|
||||
textArea.discardAllEdits()
|
||||
|
||||
scrollPane.border = BorderFactory.createMatteBorder(1, 0, 0, 0, DynamicColor.BorderColor)
|
||||
|
||||
findPanel.isVisible = false
|
||||
findPanel.isOpaque = true
|
||||
findPanel.background = DynamicColor("window")
|
||||
|
||||
searchTextField.background = findPanel.background
|
||||
searchTextField.padding = Insets(0, 4, 0, 0)
|
||||
searchTextField.border = BorderFactory.createEmptyBorder()
|
||||
|
||||
findPanel.add(searchTextField)
|
||||
findPanel.add(prevBtn)
|
||||
findPanel.add(nextBtn)
|
||||
findPanel.add(closeFindPanelBtn)
|
||||
findPanel.border = BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createMatteBorder(0, 1, 1, 0, DynamicColor.BorderColor),
|
||||
BorderFactory.createEmptyBorder(2, 2, 2, 2)
|
||||
)
|
||||
|
||||
layeredPane.add(findPanel, JLayeredPane.MODAL_LAYER as Any)
|
||||
layeredPane.add(scrollPane, JLayeredPane.DEFAULT_LAYER as Any)
|
||||
|
||||
add(layeredPane, BorderLayout.CENTER)
|
||||
}
|
||||
|
||||
|
||||
private fun initEvents() {
|
||||
|
||||
window.addWindowListener(object : WindowAdapter() {
|
||||
override fun windowOpened(e: WindowEvent?) {
|
||||
scrollPane.verticalScrollBar.value = 0
|
||||
window.removeWindowListener(this)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
textArea.inputMap.put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_S, toolkit.menuShortcutKeyMaskEx),
|
||||
"Save"
|
||||
)
|
||||
textArea.inputMap.put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_F, toolkit.menuShortcutKeyMaskEx),
|
||||
"Find"
|
||||
)
|
||||
|
||||
searchTextField.inputMap.put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
|
||||
"Esc"
|
||||
)
|
||||
|
||||
searchTextField.actionMap.put("Esc", object : AbstractAction("Esc") {
|
||||
override fun actionPerformed(e: ActionEvent) {
|
||||
textArea.clearMarkAllHighlights()
|
||||
textArea.requestFocusInWindow()
|
||||
findPanel.isVisible = false
|
||||
}
|
||||
})
|
||||
|
||||
closeFindPanelBtn.addActionListener { searchTextField.actionMap.get("Esc").actionPerformed(it) }
|
||||
|
||||
textArea.actionMap.put("Save", object : AbstractAction("Save") {
|
||||
override fun actionPerformed(e: ActionEvent) {
|
||||
file.writeText(textArea.text, Charsets.UTF_8)
|
||||
text = textArea.text
|
||||
window.title = file.name
|
||||
}
|
||||
})
|
||||
|
||||
textArea.actionMap.put("Find", object : AbstractAction("Find") {
|
||||
override fun actionPerformed(e: ActionEvent) {
|
||||
findPanel.isVisible = true
|
||||
searchTextField.selectAll()
|
||||
searchTextField.requestFocusInWindow()
|
||||
}
|
||||
})
|
||||
|
||||
textArea.document.addDocumentListener(object : DocumentAdaptor() {
|
||||
override fun changedUpdate(e: DocumentEvent) {
|
||||
window.title = if (textArea.text.hashCode() != text.hashCode()) {
|
||||
"${file.name} *"
|
||||
} else {
|
||||
file.name
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
searchTextField.document.addDocumentListener(object : DocumentAdaptor() {
|
||||
override fun changedUpdate(e: DocumentEvent) {
|
||||
search()
|
||||
}
|
||||
})
|
||||
|
||||
searchTextField.addActionListener { nextBtn.doClick(0) }
|
||||
|
||||
prevBtn.addActionListener { search(false) }
|
||||
nextBtn.addActionListener { search(true) }
|
||||
}
|
||||
|
||||
private fun search(searchForward: Boolean = true) {
|
||||
textArea.clearMarkAllHighlights()
|
||||
|
||||
|
||||
val text: String = searchTextField.getText()
|
||||
if (text.isEmpty()) return
|
||||
context.searchFor = text
|
||||
context.searchForward = searchForward
|
||||
context.wholeWord = false
|
||||
val result = SearchEngine.find(textArea, context)
|
||||
|
||||
prevBtn.isEnabled = result.markedCount > 0
|
||||
nextBtn.isEnabled = result.markedCount > 0
|
||||
|
||||
}
|
||||
|
||||
fun changes() = text != textArea.text
|
||||
|
||||
private inner class LayeredPane : JLayeredPane() {
|
||||
override fun doLayout() {
|
||||
synchronized(treeLock) {
|
||||
for (c in components) {
|
||||
if (c == findPanel) {
|
||||
val height = max(findPanel.preferredSize.height, findPanel.height)
|
||||
val x = width / 2
|
||||
c.setBounds(x, 1, width - x, height)
|
||||
} else {
|
||||
c.setBounds(0, 0, width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package app.termora.plugins.editor
|
||||
|
||||
import app.termora.plugin.Extension
|
||||
import app.termora.plugin.ExtensionSupport
|
||||
import app.termora.plugin.Plugin
|
||||
import app.termora.sftp.SFTPEditFileExtension
|
||||
|
||||
class EditorPlugin : Plugin {
|
||||
private val support = ExtensionSupport()
|
||||
|
||||
init {
|
||||
support.addExtension(SFTPEditFileExtension::class.java) { MySFTPEditFileExtension.instance }
|
||||
}
|
||||
|
||||
override fun getAuthor(): String {
|
||||
return "TermoraDev"
|
||||
}
|
||||
|
||||
|
||||
override fun getName(): String {
|
||||
return "SFTP File Editor"
|
||||
}
|
||||
|
||||
override fun <T : Extension> getExtensions(clazz: Class<T>): List<T> {
|
||||
return support.getExtensions(clazz)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package app.termora.plugins.editor
|
||||
|
||||
import app.termora.Disposable
|
||||
import app.termora.Disposer
|
||||
import app.termora.sftp.SFTPEditFileExtension
|
||||
import app.termora.sftp.absolutePathString
|
||||
import org.apache.commons.vfs2.FileObject
|
||||
import java.awt.Window
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
class MySFTPEditFileExtension private constructor() : SFTPEditFileExtension {
|
||||
companion object {
|
||||
val instance = MySFTPEditFileExtension()
|
||||
}
|
||||
|
||||
override fun edit(owner: Window, file: FileObject): Disposable {
|
||||
val disposable = Disposer.newDisposable()
|
||||
SwingUtilities.invokeLater { EditorDialog(file, owner, disposable).isVisible = true }
|
||||
return disposable
|
||||
}
|
||||
}
|
||||
22
plugins/editor/src/main/resources/META-INF/plugin.xml
Normal file
22
plugins/editor/src/main/resources/META-INF/plugin.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<termora-plugin>
|
||||
|
||||
<id>editor</id>
|
||||
|
||||
<name>SFTP File Editor</name>
|
||||
|
||||
<version>${projectVersion}</version>
|
||||
|
||||
<termora-version since=">=${rootProjectVersion}" until=""/>
|
||||
|
||||
<entry>app.termora.plugins.editor.EditorPlugin</entry>
|
||||
|
||||
<descriptions>
|
||||
<description>Edit SFTP files using the built-in editor</description>
|
||||
<description language="zh_CN">使用内置编辑器编辑 SFTP 文件</description>
|
||||
<description language="zh_TW">使用內建編輯器編輯 SFTP 文件</description>
|
||||
</descriptions>
|
||||
|
||||
<vendor url="https://github.com/TermoraDev">TermoraDev</vendor>
|
||||
|
||||
|
||||
</termora-plugin>
|
||||
@@ -0,0 +1,6 @@
|
||||
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 3.86667C1 2.83574 1.7835 2 2.75 2H6.03823C6.29871 2 6.5489 2.10163 6.73559 2.28327L8.5 4L13 4C14.1046 4 15 4.89543 15 6V7.47774C14.2142 6.80872 13.0333 6.84543 12.2909 7.58786L7 12.8787V14H2.75C1.7835 14 1 13.1643 1 12.1333V3.86667Z" />
|
||||
<path d="M8.09379 5H13C13.5523 5 14 5.44772 14 6V7.02381C14.3594 7.07711 14.7072 7.22842 15 7.47774V6C15 4.89543 14.1046 4 13 4L8.5 4L6.73559 2.28327C6.5489 2.10163 6.29871 2 6.03823 2H2.75C1.7835 2 1 2.83574 1 3.86667V12.1333C1 13.1643 1.7835 14 2.75 14H7V13H2.75C2.3956 13 2 12.6738 2 12.1333V3.86667C2 3.32624 2.3956 3 2.75 3H6.03823L8.09379 5Z" fill="#6C707E"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4122 8.29497C14.0217 7.90444 13.3885 7.90444 12.998 8.29497L11.6466 9.64633L8 13.2929V16H10.7071L15.7051 11.0021C16.0956 10.6116 16.0956 9.97839 15.7051 9.58786L14.4122 8.29497ZM14 11.2929L14.998 10.295L13.7051 9.00208L12.7071 10L14 11.2929ZM12 10.7072L13.2929 12L10.2929 15H9V13.7072L12 10.7072Z" fill="#6C707E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,6 @@
|
||||
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 3.86667C1 2.83574 1.7835 2 2.75 2H6.03823C6.29871 2 6.5489 2.10163 6.73559 2.28327L8.5 4L13 4C14.1046 4 15 4.89543 15 6V7.47774C14.2142 6.80872 13.0333 6.84543 12.2909 7.58786L7 12.8787V14H2.75C1.7835 14 1 13.1643 1 12.1333V3.86667Z" />
|
||||
<path d="M8.09379 5H13C13.5523 5 14 5.44772 14 6V7.02381C14.3594 7.07711 14.7072 7.22842 15 7.47774V6C15 4.89543 14.1046 4 13 4L8.5 4L6.73559 2.28327C6.5489 2.10163 6.29871 2 6.03823 2H2.75C1.7835 2 1 2.83574 1 3.86667V12.1333C1 13.1643 1.7835 14 2.75 14H7V13H2.75C2.3956 13 2 12.6738 2 12.1333V3.86667C2 3.32624 2.3956 3 2.75 3H6.03823L8.09379 5Z" fill="#CED0D6"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4122 8.29497C14.0217 7.90444 13.3885 7.90444 12.998 8.29497L11.6466 9.64633L8 13.2929V16H10.7071L15.7051 11.0021C16.0956 10.6116 16.0956 9.97839 15.7051 9.58786L14.4122 8.29497ZM14 11.2929L14.998 10.295L13.7051 9.00208L12.7071 10L14 11.2929ZM12 10.7072L13.2929 12L10.2929 15H9V13.7072L12 10.7072Z" fill="#CED0D6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,107 @@
|
||||
package app.termora.plugins.editor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import org.fife.ui.rtextarea.*;
|
||||
import org.fife.ui.rsyntaxtextarea.*;
|
||||
|
||||
/**
|
||||
* A simple example showing how to do search and replace in a RSyntaxTextArea.
|
||||
* The toolbar isn't very user-friendly, but this is just to show you how to use
|
||||
* the API.<p>
|
||||
*
|
||||
* This example uses RSyntaxTextArea 2.5.6.
|
||||
*/
|
||||
public class FindAndReplaceDemo extends JFrame implements ActionListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private RSyntaxTextArea textArea;
|
||||
private JTextField searchField;
|
||||
private JCheckBox regexCB;
|
||||
private JCheckBox matchCaseCB;
|
||||
|
||||
public FindAndReplaceDemo() {
|
||||
|
||||
JPanel cp = new JPanel(new BorderLayout());
|
||||
|
||||
textArea = new RSyntaxTextArea(20, 60);
|
||||
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
|
||||
textArea.setCodeFoldingEnabled(true);
|
||||
RTextScrollPane sp = new RTextScrollPane(textArea);
|
||||
cp.add(sp);
|
||||
|
||||
// Create a toolbar with searching options.
|
||||
JToolBar toolBar = new JToolBar();
|
||||
searchField = new JTextField(30);
|
||||
toolBar.add(searchField);
|
||||
final JButton nextButton = new JButton("Find Next");
|
||||
nextButton.setActionCommand("FindNext");
|
||||
nextButton.addActionListener(this);
|
||||
toolBar.add(nextButton);
|
||||
searchField.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
nextButton.doClick(0);
|
||||
}
|
||||
});
|
||||
JButton prevButton = new JButton("Find Previous");
|
||||
prevButton.setActionCommand("FindPrev");
|
||||
prevButton.addActionListener(this);
|
||||
toolBar.add(prevButton);
|
||||
regexCB = new JCheckBox("Regex");
|
||||
toolBar.add(regexCB);
|
||||
matchCaseCB = new JCheckBox("Match Case");
|
||||
toolBar.add(matchCaseCB);
|
||||
cp.add(toolBar, BorderLayout.NORTH);
|
||||
|
||||
setContentPane(cp);
|
||||
setTitle("Find and Replace Demo");
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
// "FindNext" => search forward, "FindPrev" => search backward
|
||||
String command = e.getActionCommand();
|
||||
boolean forward = "FindNext".equals(command);
|
||||
|
||||
// Create an object defining our search parameters.
|
||||
SearchContext context = new SearchContext();
|
||||
String text = searchField.getText();
|
||||
if (text.length() == 0) {
|
||||
return;
|
||||
}
|
||||
context.setSearchFor(text);
|
||||
context.setMatchCase(matchCaseCB.isSelected());
|
||||
context.setRegularExpression(regexCB.isSelected());
|
||||
context.setSearchForward(forward);
|
||||
context.setWholeWord(false);
|
||||
|
||||
boolean found = SearchEngine.find(textArea, context).wasFound();
|
||||
if (!found) {
|
||||
JOptionPane.showMessageDialog(this, "Text not found");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Start all Swing applications on the EDT.
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
String laf = UIManager.getSystemLookAndFeelClassName();
|
||||
UIManager.setLookAndFeel(laf);
|
||||
} catch (Exception e) { /* never happens */ }
|
||||
FindAndReplaceDemo demo = new FindAndReplaceDemo();
|
||||
demo.setVisible(true);
|
||||
demo.textArea.requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user