Theme Editor: basic "find bar" added

This commit is contained in:
Karl Tauber
2020-12-31 15:08:14 +01:00
parent 0896143838
commit 6f3aea8fc1
13 changed files with 382 additions and 3 deletions

View File

@@ -0,0 +1,213 @@
/*
* Copyright 2020 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.themeeditor;
import java.awt.Container;
import javax.swing.*;
import org.fife.rsta.ui.CollapsibleSectionPanel;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rtextarea.SearchContext;
import org.fife.ui.rtextarea.SearchEngine;
import org.fife.ui.rtextarea.SearchResult;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
class FlatFindReplaceBar
extends JPanel
{
private final RSyntaxTextArea textArea;
private SearchContext context;
FlatFindReplaceBar( RSyntaxTextArea textArea ) {
this.textArea = textArea;
initComponents();
findPreviousButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/findAndShowPrevMatches.svg" ) );
findNextButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/findAndShowNextMatches.svg" ) );
matchCaseToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/matchCase.svg" ) );
matchWholeWordToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/words.svg" ) );
regexToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/regex.svg" ) );
closeButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/themeeditor/icons/close.svg" ) );
SearchContext context = new SearchContext();
context.setSearchWrap( true );
setSearchContext( context );
}
SearchContext getSearchContext() {
return context;
}
void setSearchContext( SearchContext context ) {
this.context = context;
findField.setText( context.getSearchFor() );
matchCaseToggleButton.setSelected( context.getMatchCase() );
matchWholeWordToggleButton.setSelected( context.getWholeWord() );
regexToggleButton.setSelected( context.isRegularExpression() );
}
@Override
public boolean requestFocusInWindow() {
return findField.requestFocusInWindow();
}
private void findNext() {
context.setSearchForward( true );
find();
}
private void findPrevious() {
context.setSearchForward( false );
find();
}
private void find() {
// update search context
context.setSearchFor( findField.getText() );
// find
SearchResult result = SearchEngine.find( textArea, context );
// update matches info label
matchesLabel.setText( result.getMarkedCount() + " matches" );
}
private void matchCaseChanged() {
context.setMatchCase( matchCaseToggleButton.isSelected() );
find();
}
private void matchWholeWordChanged() {
context.setWholeWord( matchWholeWordToggleButton.isSelected() );
find();
}
private void regexChanged() {
context.setRegularExpression( regexToggleButton.isSelected() );
find();
}
private void close() {
Container parent = getParent();
if( parent instanceof CollapsibleSectionPanel )
((CollapsibleSectionPanel)parent).hideBottomComponent();
else if( parent != null )
parent.remove( this );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
findLabel = new JLabel();
findField = new JTextField();
findToolBar = new JToolBar();
findPreviousButton = new JButton();
findNextButton = new JButton();
matchCaseToggleButton = new JToggleButton();
matchWholeWordToggleButton = new JToggleButton();
regexToggleButton = new JToggleButton();
matchesLabel = new JLabel();
hSpacer1 = new JPanel(null);
closeButton = new JButton();
//======== this ========
setFocusCycleRoot(true);
setLayout(new MigLayout(
"insets 3,hidemode 3",
// columns
"[fill]" +
"[fill]0" +
"[grow,fill]",
// rows
"[]"));
//---- findLabel ----
findLabel.setText("Find:");
findLabel.setDisplayedMnemonic('F');
findLabel.setLabelFor(findField);
add(findLabel, "cell 0 0");
//---- findField ----
findField.setColumns(16);
findField.addActionListener(e -> find());
add(findField, "cell 1 0");
//======== findToolBar ========
{
findToolBar.setFloatable(false);
findToolBar.setBorder(null);
//---- findPreviousButton ----
findPreviousButton.setToolTipText("Previous Occurrence");
findPreviousButton.addActionListener(e -> findPrevious());
findToolBar.add(findPreviousButton);
//---- findNextButton ----
findNextButton.setToolTipText("Next Occurrence");
findNextButton.addActionListener(e -> findNext());
findToolBar.add(findNextButton);
findToolBar.addSeparator();
//---- matchCaseToggleButton ----
matchCaseToggleButton.setToolTipText("Match Case");
matchCaseToggleButton.addActionListener(e -> matchCaseChanged());
findToolBar.add(matchCaseToggleButton);
//---- matchWholeWordToggleButton ----
matchWholeWordToggleButton.setToolTipText("Match Whole Word");
matchWholeWordToggleButton.addActionListener(e -> matchWholeWordChanged());
findToolBar.add(matchWholeWordToggleButton);
//---- regexToggleButton ----
regexToggleButton.setToolTipText("Regex");
regexToggleButton.addActionListener(e -> regexChanged());
findToolBar.add(regexToggleButton);
findToolBar.addSeparator();
//---- matchesLabel ----
matchesLabel.setEnabled(false);
findToolBar.add(matchesLabel);
findToolBar.add(hSpacer1);
//---- closeButton ----
closeButton.setToolTipText("Close");
closeButton.addActionListener(e -> close());
findToolBar.add(closeButton);
}
add(findToolBar, "cell 2 0");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel findLabel;
private JTextField findField;
private JToolBar findToolBar;
private JButton findPreviousButton;
private JButton findNextButton;
private JToggleButton matchCaseToggleButton;
private JToggleButton matchWholeWordToggleButton;
private JToggleButton regexToggleButton;
private JLabel matchesLabel;
private JPanel hSpacer1;
private JButton closeButton;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -0,0 +1,83 @@
JFDML JFormDesigner: "7.0.3.1.342" Java: "15" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 3,hidemode 3"
"$columnConstraints": "[fill][fill]0[grow,fill]"
"$rowConstraints": "[]"
} ) {
name: "this"
"focusCycleRoot": true
add( new FormComponent( "javax.swing.JLabel" ) {
name: "findLabel"
"text": "Find:"
"displayedMnemonic": 70
"labelFor": new FormReference( "findField" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "findField"
"columns": 16
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "find", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
name: "findToolBar"
"floatable": false
"border": sfield com.jformdesigner.model.FormObject NULL_VALUE
add( new FormComponent( "javax.swing.JButton" ) {
name: "findPreviousButton"
"toolTipText": "Previous Occurrence"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "findPrevious", false ) )
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "findNextButton"
"toolTipText": "Next Occurrence"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "findNext", false ) )
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator1"
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "matchCaseToggleButton"
"toolTipText": "Match Case"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "matchCaseChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "matchWholeWordToggleButton"
"toolTipText": "Match Whole Word"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "matchWholeWordChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "regexToggleButton"
"toolTipText": "Regex"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "regexChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "matchesLabel"
"enabled": false
} )
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
name: "hSpacer1"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "closeButton"
"toolTipText": "Close"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "close", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 400, 300 )
} )
}
}

View File

@@ -30,6 +30,7 @@ import javax.swing.JLayer;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.fife.rsta.ui.CollapsibleSectionPanel;
import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.CompletionProvider;
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
@@ -53,8 +54,10 @@ class FlatThemeEditorPane
private static final String FLATLAF_STYLE = "text/flatlaf";
private final CollapsibleSectionPanel collapsiblePanel;
private final RTextScrollPane scrollPane;
private final FlatSyntaxTextArea textArea;
private FlatFindReplaceBar findReplaceBar;
private File file;
@@ -114,7 +117,10 @@ class FlatThemeEditorPane
// use same font for line numbers as in editor
scrollPane.getGutter().setLineNumberFont( textArea.getFont() );
add( scrollPane, BorderLayout.CENTER );
// create collapsible panel
collapsiblePanel = new CollapsibleSectionPanel();
collapsiblePanel.add( scrollPane );
add( collapsiblePanel, BorderLayout.CENTER );
}
private static Font scaleFont( Font font ) {
@@ -198,4 +204,13 @@ class FlatThemeEditorPane
Window window = SwingUtilities.windowForComponent( this );
return (window instanceof JFrame) ? ((JFrame)window).getTitle() : null;
}
void showFindReplaceBar() {
if( findReplaceBar == null ) {
findReplaceBar = new FlatFindReplaceBar( textArea );
collapsiblePanel.addBottomComponent( findReplaceBar );
}
collapsiblePanel.showBottomComponent( findReplaceBar );
}
}

View File

@@ -179,12 +179,20 @@ public class FlatThemeFileEditor
tabbedPane.setSelectedIndex( index );
}
private void find() {
FlatThemeEditorPane themeEditorPane = (FlatThemeEditorPane) tabbedPane.getSelectedComponent();
if( themeEditorPane != null )
themeEditorPane.showFindReplaceBar();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
menuBar = new JMenuBar();
fileMenu = new JMenu();
saveAllMenuItem = new JMenuItem();
exitMenuItem = new JMenuItem();
editMenu = new JMenu();
findMenuItem = new JMenuItem();
windowMenu = new JMenu();
nextEditorMenuItem = new JMenuItem();
previousEditorMenuItem = new JMenuItem();
@@ -237,6 +245,20 @@ public class FlatThemeFileEditor
}
menuBar.add(fileMenu);
//======== editMenu ========
{
editMenu.setText("Edit");
editMenu.setMnemonic('E');
//---- findMenuItem ----
findMenuItem.setText("Find...");
findMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
findMenuItem.setMnemonic('F');
findMenuItem.addActionListener(e -> find());
editMenu.add(findMenuItem);
}
menuBar.add(editMenu);
//======== windowMenu ========
{
windowMenu.setText("Window");
@@ -294,6 +316,8 @@ public class FlatThemeFileEditor
private JMenu fileMenu;
private JMenuItem saveAllMenuItem;
private JMenuItem exitMenuItem;
private JMenu editMenu;
private JMenuItem findMenuItem;
private JMenu windowMenu;
private JMenuItem nextEditorMenuItem;
private JMenuItem previousEditorMenuItem;

View File

@@ -63,6 +63,18 @@ new FormModel {
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "exit", false ) )
} )
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "editMenu"
"text": "Edit"
"mnemonic": 69
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "findMenuItem"
"text": "Find..."
"accelerator": static javax.swing.KeyStroke getKeyStroke( 70, 4226, false )
"mnemonic": 70
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "find", false ) )
} )
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "windowMenu"
"text": "Window"