I am developing a custom search component. When clicked on the button(search image icon) inside the text field, a table is displayed. The code is in very nascent stage so lots of things is not there.
As of now, I am stuck because I am not able to navigate the table with the arrow keys. Neither am I able to move to the next text field with "tab" key, once I select a row in the table.
The objective of the component is to select a row from the table and then with the help of the supporting methods(yet to be written) values from other labels and text fields would be defaulted while defaulting 1 st column value in the text field it is attached to.
Would really appreciate your help. Thanks !!
package myTableCombo;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class SearchBox extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField editor;
private JButton arrowButton;
private JWindow jWindow;
private Component userComponent;
public SearchBox() {
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
editor = new JTextField();
editor.setPreferredSize(new Dimension(250, 25));
initialize();
addListeners();
setBorders();
}
private void addListeners() {
arrowButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showWindow();
}
});
}
protected void showWindow() {
if (null != getWindowComponent()) {
jWindow = new JWindow();
jWindow.getContentPane().add(getWindowComponent());
jWindow.setLocation(new Point(SearchBox.this.getLocationOnScreen().x, SearchBox.this.getLocationOnScreen().y + 25));
jWindow.pack();
jWindow.setVisible(true);
}
}
private Component getWindowComponent() {
return userComponent;
}
public void setWindowComponent(Component component) {
userComponent = component;
}
private void initialize() {
arrowButton = new BasicArrowButton(SwingConstants.SOUTH);//In my code there is an icon here
arrowButton.setBorder(null);
arrowButton.setContentAreaFilled(false);
}
private void setBorders() {
add(editor);
add(arrowButton);
setBackground(editor.getBackground());
setBorder(editor.getBorder());
editor.setBorder(null);
}
public JTextField getTextComponent() {
return editor;
}
public JButton getActionButton() {
return arrowButton;
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
protected static void createAndShowGUI() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setPreferredSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
panel.add(new JLabel("Test Table Combo"));
SearchBox searchBox = new SearchBox();
searchBox.userComponent = searchBox.new SearchBoxTable();
panel.add(searchBox);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class SearchBoxTable extends JScrollPane implements DocumentListener {
private static final long serialVersionUID = 1L;
private JTable table;
private Object[] columnNames;
private DefaultTableModel tableModel;
private Object[][] sheetDataInString;
private TableRowSorter<DefaultTableModel> rowSorter;
public SearchBoxTable() {
columnNames = new Object[]{"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"};
sheetDataInString = new Object[21][6];
for(int i =0; i < sheetDataInString.length; i++) {
for(int j = 0; j< 6; j++) {
sheetDataInString[i][j] = "Row Value : " + i + ", Column Value : " + j;
}
}
tableModel = new DefaultTableModel(sheetDataInString, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
rowSorter = new TableRowSorter<DefaultTableModel>(tableModel);
table = new JTable(tableModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setAutoCreateRowSorter(true);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font(null, Font.PLAIN, 13));
setPreferredSize(new Dimension(500, 225));
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
getViewport().add(table);
}
@Override
public void changedUpdate(DocumentEvent e) {
newFilter(e);
}
@Override
public void insertUpdate(DocumentEvent e) {
newFilter(e);
}
@Override
public void removeUpdate(DocumentEvent e) {
newFilter(e);
}
/**
* Update the row filter regular expression from the expression/string/data in the text box.
*
* @param documentEvent
*/
private void newFilter(DocumentEvent documentEvent) {
RowFilter<DefaultTableModel, Object> rowFilter = null;
Document document = documentEvent.getDocument();
String filterText;
try {
filterText = document.getText(0, document.getLength()).trim();
rowFilter = RowFilter.regexFilter("(?i)" + filterText);
} catch (java.util.regex.PatternSyntaxException e) {
return;
} catch (BadLocationException badLocationException) {
return;
}
rowSorter.setRowFilter(rowFilter);
table.setRowSorter(rowSorter);
}
}
}
do you meaning
use undecorated JDialog
instead of JWindow
, otherwise JTextComponets
aren't editable
JDialog
has better support for AlwaysOnTop
and ModalityTypes
(only hardcoded to the setAlwaysOnTop
)
don't to recreate basic setting again and again, don't to recreate a popup windod, use lolac variable, remove all contents and add a new ony, define all setting for JDialog once time, see exception (The dialog is displayable.) in the case that popup is hidden and value in JTextField isn't empty
missed action for hide JDialog
on ESC key event
, hide JDialog
, if is JFrame
minimalized
missed moving with JDialog
if JFrame
is resized, moved over screen on another Point
,
attach Document
to the JTextField
directly, not lost somwhere in to the JScrollPane
definitions
your code missing a few good practicies, then everything is possible but not with this code (after my edit too)
search for JCalendar by Kay Toedter
(best popup workaround as I saw for popup window)
only removed uselles methods, moved from- to, notice non_optimized_code
, simple put to the recyclebin
and wrote that again
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class SearchBox extends JPanel {
private static final long serialVersionUID = 1L;
private static JFrame frame = new JFrame();
private JTextField editor;
private JButton arrowButton;
//private JToggleButton arrowButton;
private JDialog popupWindow = new JDialog(frame);
private Component userComponent;
private JTable table;
private TableRowSorter<DefaultTableModel> rowSorter;
private Object[] columnNames;
private DefaultTableModel tableModel;
private Object[][] sheetDataInString;
public SearchBox() {
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
editor = new JTextField();
editor.setPreferredSize(new Dimension(250, 25));
editor.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
newFilter();
}
@Override
public void insertUpdate(DocumentEvent e) {
newFilter();
}
@Override
public void removeUpdate(DocumentEvent e) {
newFilter();
}
private void newFilter() {
RowFilter<DefaultTableModel, Object> rowFilter = null;
Document document = editor.getDocument();
String filterText;
try {
filterText = document.getText(0, document.getLength()).trim();
rowFilter = RowFilter.regexFilter("(?i)" + filterText);
} catch (java.util.regex.PatternSyntaxException e) {
return;
} catch (BadLocationException badLocationException) {
return;
}
rowSorter.setRowFilter(rowFilter);
table.setRowSorter(rowSorter);
}
});
initialize();
addListeners();
setBorders();
}
private void addListeners() {
arrowButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!popupWindow.isVisible()) {
showWindow();
} else {
hideWindow();
}
}
});
}
protected void showWindow() {
if (null != getWindowComponent()) {
popupWindow.getContentPane().add(getWindowComponent());
popupWindow.setLocation(new Point(SearchBox.this.getLocationOnScreen().x, SearchBox.this.getLocationOnScreen().y + 25));
popupWindow.setUndecorated(true);
popupWindow.setAlwaysOnTop(true);
popupWindow.pack();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
popupWindow.setVisible(true);
}
});
}
}
protected void hideWindow() {
popupWindow.setVisible(false);
}
private Component getWindowComponent() {
return userComponent;
}
public void setWindowComponent(Component component) {
userComponent = component;
}
private void initialize() {
arrowButton = new BasicArrowButton(SwingConstants.SOUTH);//In my code there is an icon here
arrowButton.setBorder(null);
arrowButton.setContentAreaFilled(false);
}
private void setBorders() {
add(editor);
add(arrowButton);
setBackground(editor.getBackground());
setBorder(editor.getBorder());
editor.setBorder(null);
}
public JTextField getTextComponent() {
return editor;
}
public JButton getActionButton() {
return arrowButton;
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
protected static void createAndShowGUI() {
JPanel panel = new JPanel();
frame.setPreferredSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
panel.add(new JLabel("Test Table Combo"));
SearchBox searchBox = new SearchBox();
searchBox.userComponent = searchBox.new SearchBoxTable();
panel.add(searchBox);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class SearchBoxTable extends JScrollPane {
private static final long serialVersionUID = 1L;
public SearchBoxTable() {
columnNames = new Object[]{"Column 1", "Column 2", "Column 3", "Column 4", "Column 5", "Column 6"};
sheetDataInString = new Object[21][6];
for (int i = 0; i < sheetDataInString.length; i++) {
for (int j = 0; j < 6; j++) {
sheetDataInString[i][j] = "Row Value : " + i + ", Column Value : " + j;
}
}
tableModel = new DefaultTableModel(sheetDataInString, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
};
rowSorter = new TableRowSorter<DefaultTableModel>(tableModel);
table = new JTable(tableModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setAutoCreateRowSorter(true);
table.setFillsViewportHeight(true);
table.getTableHeader().setFont(new Font(null, Font.PLAIN, 13));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
getViewport().add(table);
}
}
}