FindDialog.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.gui.se.element;
017 
018 import java.awt.Container;
019 import java.awt.Dimension;
020 import java.awt.event.ActionEvent;
021 import java.awt.event.ActionListener;
022 import java.util.ArrayList;
023 import java.util.List;
024 
025 import javax.swing.BorderFactory;
026 import javax.swing.Box;
027 import javax.swing.BoxLayout;
028 import javax.swing.JButton;
029 import javax.swing.JCheckBox;
030 import javax.swing.JComboBox;
031 import javax.swing.JComponent;
032 import javax.swing.JDialog;
033 import javax.swing.JFrame;
034 import javax.swing.JLabel;
035 import javax.swing.JPanel;
036 import javax.swing.JTabbedPane;
037 import javax.swing.text.BadLocationException;
038 import javax.swing.text.Document;
039 import javax.swing.text.JTextComponent;
040 import javax.swing.text.Segment;
041 
042 import org.qedeq.base.trace.Trace;
043 import org.qedeq.gui.se.util.GuiHelper;
044 
045 import com.jgoodies.forms.builder.ButtonBarBuilder;
046 import com.jgoodies.forms.builder.DefaultFormBuilder;
047 import com.jgoodies.forms.layout.FormLayout;
048 
049 /**
050  * Configures the application.
051  *
052  @author  Michael Meyling
053  */
054 
055 public class FindDialog extends JDialog {
056 
057     /** This class. */
058     private static final Class CLASS = FindDialog.class;
059 
060     /** Number of previous search texts we remember. */
061     private static final int MAX_HISTORY_SIZE = 20;
062 
063     /** Here we remember all previous search texts. */
064     public static final List HISTORY = new ArrayList();
065 
066     /** Search in this text field. */
067     private JTextComponent text;
068 
069     /** Case sensitive search?*/
070     private JCheckBox caseSensitive;
071 
072     /** Search for this text. */
073     private JComboBox searchText;
074 
075     /** Search for this text. */
076     private JLabel status;
077 
078     /**
079      * Creates new Panel.
080      *
081      @param   text    Text to search within.
082      */
083     public FindDialog(final JTextComponent text) {
084         super((JFrametext.getTopLevelAncestor()"Find");
085         final String method = "Constructor";
086         Trace.begin(CLASS, this, method);
087         try {
088 //            setModal(true);
089             setDefaultCloseOperation(DISPOSE_ON_CLOSE);
090             setupView(text);
091             updateView();
092         catch (Throwable e) {
093             Trace.fatal(CLASS, this, "Initalization of FindDialog failed.", method, e);
094         finally {
095             Trace.end(CLASS, this, method);
096         }
097     }
098 
099     /**
100      * Assembles checkbox settings panel.
101      *
102      @return  Created panel.
103      */
104     private JComponent searchPanel() {
105         FormLayout layout = new FormLayout(
106 //        "left:pref, fill:50dlu:grow");    // columns
107 //        "fill:50dlu:grow");    // columns
108         "right:pref, 5dlu, fill:pref:grow");    // columns
109 
110         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
111         builder.setBorder(BorderFactory.createEmptyBorder(0000));
112         builder.getPanel().setOpaque(false);
113 
114         searchText = new JComboBox();
115         for (int i = 0; i < HISTORY.size() && i < MAX_HISTORY_SIZE; i++) {
116             searchText.addItem(HISTORY.get(i));
117         }
118 //        searchText.setPreferredSize(new Dimension(GuiHelper.getSearchTextBoxWidth(),
119 //        searchText.getPreferredSize().height));
120         searchText.setEditable(true);
121 
122         builder.append("Search:", searchText);
123 
124 //      caseSensitive = new JCheckBox(" Case sensitive", false);
125         caseSensitive = new JCheckBox(""false);
126         builder.append(caseSensitive);
127         builder.append(new JLabel("Case sensitive"));
128 
129 
130         return GuiHelper.addSpaceAndTitle(builder.getPanel()"Find");
131 
132     }
133 
134     /**
135      * Assembles the GUI components of the panel.
136      *
137      @param   text    We search in this text component.
138      */
139     public final void setupView(final JTextComponent text) {
140         this.text = text;
141         final Container content = getContentPane();
142         content.setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
143 
144         final JPanel allOptions = new JPanel();
145         allOptions.setBorder(GuiHelper.getEmptyBorder());
146         allOptions.setLayout(new BoxLayout(allOptions, BoxLayout.Y_AXIS));
147         allOptions.add(searchPanel());
148         allOptions.add(Box.createVerticalStrut(GuiHelper.getEmptyBorderPixelsY()));
149 
150 
151         final JTabbedPane tabbedPane = new JTabbedPane();
152         tabbedPane.setOpaque(false);
153         tabbedPane.addTab("Main Options", allOptions);
154 
155         content.add(tabbedPane);
156 
157         content.add(GuiHelper.addSpaceAndAlignRight(createButtonPanel()));
158         status = new JLabel("");
159         final JPanel panel = new JPanel();
160         panel.add(status);
161         content.add(GuiHelper.alignLeft(panel));
162 
163         // let the container calculate the ideal size
164         pack();
165 
166         final Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
167         setBounds((screenSize.width - getWidth()) 2(screenSize.height - getHeight()) 2,
168             getWidth(), getHeight() 20);
169     }
170 
171     /**
172      * Create button panel.
173      *
174      @return  Main buttons.
175      */
176     private JPanel createButtonPanel() {
177         ButtonBarBuilder bbuilder = ButtonBarBuilder.createLeftToRightBuilder();
178         JButton findB = new JButton("Find");
179         findB.addActionListener(new  ActionListener() {
180             public void actionPerformed(final ActionEvent actionEvent) {
181                 try {
182 //                    text.getCaret().setVisible(true);
183 
184                     int pos1 = findCaretPosition(text.getCaretPosition());
185                     if (pos1 < 0) {
186                         status.setText("Search from beginning");
187                         pos1 = findCaretPosition(0);
188                         if (pos1 < 0) {
189                             status.setText("String not found");
190                             return;
191                         }
192                     else {
193                         status.setText("");
194                     }
195                     final int pos2 = pos1 + searchText.getSelectedItem().toString().length();
196 //                    JTextPane pane = (JTextPane) text;
197 //                    pane.getDocument().
198                     text.setCaretPosition(pos1);
199                     text.moveCaretPosition(pos2);
200                     text.requestFocus();
201 //                    text.setCaretPosition(pos2);
202                 catch (Exception e) {
203                     e.printStackTrace(System.out);
204                 }
205             }
206         });
207 
208         JButton close = new JButton("Close");
209         close.addActionListener(new  ActionListener() {
210             public void actionPerformed(final ActionEvent actionEvent) {
211                 FindDialog.this.dispose();
212             }
213         });
214 
215         bbuilder.addGriddedButtons(new JButton[]{findB, close});
216 
217         final JPanel buttons = bbuilder.getPanel();
218         return buttons;
219     }
220 
221     /**
222      * Update from model.
223      */
224     public void updateView() {
225         invalidate();
226         repaint();
227     }
228 
229     private final int findCaretPosition(final int start) {
230         final Document doc = text.getDocument();
231         int nleft = doc.getLength();
232         String data = "";
233         Segment s = new Segment();
234         int offs = 0;
235         s.setPartialReturn(false);
236         try {
237             doc.getText(offs, nleft, s);
238             data = s.toString();
239         catch (BadLocationException e) {
240             data = text.getText();
241         }
242         String m = searchText.getSelectedItem().toString();
243         HISTORY.remove(m);
244         HISTORY.add(0, m);
245         // consolidate combo box
246         searchText.removeAllItems();
247         for (int i = 0; i < HISTORY.size(); i++) {
248             searchText.addItem(HISTORY.get(i));
249         }
250         final boolean cs = caseSensitive.isSelected();
251         if (!cs) {
252             data = data.toLowerCase();
253             m = m.toLowerCase();
254         }
255         Trace.trace(CLASS, "findCaretPosition(int)""searching for " + m + " from " + start);
256         final int result =  data.indexOf(m, start);
257         Trace.trace(CLASS, "findCaretPosition(int)""result = " + result);
258         return result;
259     }
260 }