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((JFrame) text.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(0, 0, 0, 0));
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 }
|