I need to highlight the text and move the entire screen/view to the searched text. for example: If view is holding 1 to 1000 numbers(rows), if i enter search text as 55 and click on Search button, first it has to move the screen to text 55 (first occurrence) and then should highlight only 55, not the other occurrences of 55. As i keep pressing on Search button, search should proceed further and highlight 155 and then 255, 355, 455, 555, etc. At once only one 55 can be highlighted.
It should have same search experience as Notepad.
Is it a valid use case ? I am new to Swings, trying to build a small application as part of learning. Have written a sample code (referred other post), but this is highlighting all the occurrences at once and not sure how to move the view to the first occurrence. Please suggest.
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Form extends JFrame {
private String textForSearch = "";
private JTable t;
public Form() {
t = new JTable();
String[] headers = new String[]{"first", "second", "third"};
DefaultTableModel model = new DefaultTableModel(0, 0);
model.setColumnIdentifiers(headers);
for(int i =0;i<1000;i++){
model.addRow(new Object[]{i});
model.addRow(new Object[]{i});
}
t.setModel(model);
for(int i =0;i<t.getColumnCount();i++){
t.getColumnModel().getColumn(0).setCellRenderer(getRenderer());
}
JScrollPane jsp = new JScrollPane(t);
final RightPanel right = new RightPanel();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(jsp, BorderLayout.CENTER);
add(right, BorderLayout.EAST);
pack();
setLocationRelativeTo(null);
}
private TableCellRenderer getRenderer() {
return new TableCellRenderer() {
JTextField f = new JTextField(5);
@Override
public Component getTableCellRendererComponent(JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4, int arg5) {
if(arg1 != null){
f.setText(arg1.toString());
String string = arg1.toString();
if(string.contains(textForSearch)){
int indexOf = string.indexOf(textForSearch);
try {
f.getHighlighter().addHighlight(indexOf,indexOf+textForSearch.length(),new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.RED));
} catch (BadLocationException e) {
e.printStackTrace();
}
}
} else {
f.setText("");
f.getHighlighter().removeAllHighlights();
}
return f;
}
};
}
class RightPanel extends JPanel{
public RightPanel(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 5, 5, 5);
c.gridy = 0;
final JTextField f = new JTextField();
add(f,c);
JButton b = new JButton("search");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
textForSearch = f.getText();
t.repaint();
}
});
c.gridy++;
add(b,c);
}
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Form().setVisible(true);
}
});
}
}
Edited: From other posts, found solution to move the pointer/screen to a particular row, but not sure how to get the rowIndex value of a searched text:
public static void scrollToVisible(JTable table, int rowIndex, int vColIndex) {
if (!(table.getParent() instanceof JViewport)) return;
JViewport viewport = (JViewport) table.getParent();
Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
Point pt = viewport.getViewPosition();
rect.setLocation(rect.x - pt.x, rect.y - pt.y);
viewport.scrollRectToVisible(rect);
}
Added for others reference :
to show the selected row in middle of the screen: http://www.java2s.com/Code/Java/Swing-JFC/ScrollingaCelltotheCenterofaJTableComponent.htm