I have the following problem:
There are 2 JLists in my frame:
listModel = new DefaultListModel();
ownlistModel = new DefaultListModel();
fillList();
ownBookList = new JList(ownlistModel);
ownBookList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ownBookList.setLayoutOrientation(JList.VERTICAL);
ownBookList.setSelectedIndex(-1);
userlist = new JList(listModel);
userlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
userlist.setLayoutOrientation(JList.VERTICAL);
userlist.setSelectedIndex(0);
Now, these are mutually exclusive, so if someone clicks an item in the one list, the previous selection in the other list should be cleared.
ls2Handler = new ListSelectionListener(){
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
// System.out.println(ownBookList.getSelectedValue().toString().length());
Global.selectedUser = ownBookList.getSelectedValue().toString();
Global.selectedIndex = ownBookList.getSelectedIndex();
userlist.clearSelection();
updateFields(Global.selectedUser, 1);
}
}
};
lsHandler = new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
// System.out.println(userlist.getSelectedValue().toString().length());
Global.selectedUser = userlist.getSelectedValue().toString();
Global.selectedIndex = userlist.getSelectedIndex();
ownBookList.clearSelection();
updateFields(Global.selectedUser, 0);
}
}
};
userlist.addListSelectionListener(lsHandler);
ownBookList.addListSelectionListener(ls2Handler);
On calling the Value is adjusting function I always get the nullpointerException:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Books$3.valueChanged(Books.java:199) at
javax.swing.JList.fireSelectionValueChanged(Unknown Source)
Why is that? As you can see, they have been declared and should be accessible.
The getSelectedValue() method can return null, and you are calling toString() on that null object
userlist.getSelectedValue().toString();
See the documentation of that method:
Returns the value for the smallest selected cell index; the selected value when only a single item is selected in the list. When multiple items are selected, it is simply the value for the smallest selected index. Returns null if there is no selection.
And since you clear the selection on list B when you select something on list A, you will quickly run into this exception.
Thanks to Robin I figured it out. I wasn't aware that the method clearselection() triggers the listener.
It's quick and dirty but it works:
ls2Handler = new ListSelectionListener(){
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (ownBookList.getSelectedValue()!=null) {
userlist.clearSelection();
Global.selectedUser = ownBookList.getSelectedValue().toString();
Global.selectedIndex = ownBookList.getSelectedIndex();
updateFields(Global.selectedUser);
}
else {
}
}
}
};
lsHandler = new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (userlist.getSelectedValue()!=null) {
ownBookList.clearSelection();
Global.selectedUser = userlist.getSelectedValue().toString();
Global.selectedIndex = userlist.getSelectedIndex();
updateFields(Global.selectedUser);
}
else {
}
}
}
};
Thanks again!
Related
My requirement is to use addDocumentListener, the doSearchCmb basically narrows down items in combobox, function is working if keypressed is used. If I remove the function Runnable doSearchCmb and put the narrowing down of items in insertUpdate without using invokeLater, I get an error of 'Attempt to mutate notification' exception.
In my current code, my screen freezes after I type a letter. After waiting several minutes, I get the error of java.lang.OutOfMemoryError: Java heap space.
I tried to add return; after combo.repaint();, my screen didn't freeze, there's no java heap space error but nothing happened at all. I attached the code without the return.
What can I do here to remain the use of addDocumentListener and the function which narrows down the items of the combobox?
TCombo combo = new TCombo();
JTextComponent editor = (JTextComponent) combo.getEditor().getEditorComponent();
editor.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent arg0) {
}
public void insertUpdate(DocumentEvent arg0) {
searchCmb();
}
public void removeUpdate(DocumentEvent arg0) {
searchCmb();
}
private void searchCmb() {
Runnable doSearchCmb = new Runnable() {
#Override
public void run() {
String item = combo.getEditor().getItem().toString().trim();
boolean isEmpty = item.equals("");
CmbElement[] foundList = null;
String toFind = "";
List list = new ArrayList(0);
if (!isEmpty) {
combo.removeAllItems();
combo.setItems(elements);
for (int i = 1; i < elements.length; i++) {
if (elements[i].getName().contains(toFind)) {
if (i == 1) {
list.add("");
}
list.add(elements[i]);
}
foundList = (CmbElement[]) list.toArray(new CmbElement[list.size()]);
}
if (list.size() > 0) {
combo.removeAllItems();
combo.setItems(foundList);
} else {
combo.removeAllItems();
if (toFind.equals("")) {
combo.setItems(elements);
}
list.add(new DCmbElement("", ""));
foundList = (CmbElement[]) list.toArray(new CmbElement[list.size()]);
combo.setItems(foundList);
}
combo.repaint();
}
}
};
SwingUtilities.invokeLater(doSearchCmb);
}
});
CmbElement:
public abstract interface CmbElement {
public abstract String getKey();
public abstract String getName();
}
Note: Narrow down items in combo box means when user inputs a letter, or paste a word, the items in combo box gets filtered using the current letter or word as parameter. It searches through the items and narrows it down.
For reference the behavior is like the image here: jcombobox filter in java - Look and feel independent
My function indicated in run() is working fine if keypressed of keylistener is used, but my requirement is to use addDocumentListener
I am using JList of Strings in java swing. I want to have a ListSelectionListener which returns the String of the Listentry, that was selected by the user. But I can't reach the String itself. The only thing that I could find
private void registerListeners()
{
gui.getListMeasurements().addListSelectionListener(new ListSelectionListener()
{
#Override
public void valueChanged(ListSelectionEvent event)
{
System.out.println(event.getSource());
}
});
}
Outputs the following 4 times: javax.swing.JList[,0,0,240x340,alignmentX=0.0,alignmentY=0.0,border=,flags=50331944,maximumSize=,minimumSize=,preferredSize=,fixedCellHeight=-1,fixedCellWidth=-1,horizontalScrollIncrement=-1,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],visibleRowCount=8,layoutOrientation=0]
Nothing in this output refers to the String selected in the list. Neither can I find any useful method for the event.
Is it possible to extract Strings the way I described?
gui.getListMeasurements().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
return;
}
if (e.getSource() instanceof JList) {
JList list = (JList) e.getSource();
int index = list.getSelectedIndex();
Object element = list.getModel().getElementAt(index);
if (element instanceof String) {
System.out.println("Selected value at " + index + " = " + element);
}
}
}
});
Helpful links:
How to Use Lists
JavaDocs for JList
How to Write a List Selection Listener
JavaDocs for ListSelectionListener and ListSelectionEvent
I'm doing this project and it has I'm trying to print out the selected item in the combo box but it's not working. Just wanting to know why it is not printing out properly. trying to print "eric white"
public void subList() {
//sets up sub list based on selection in managerbox
cboManager.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
Object selected = cboManager.getSelectedItem();
if (selected.equals("Eric White") ) {
System.out.println("eric white");
}
}
}
});
}
Check whether the item listed in combo box is exactly "Eric White", because equals will look for exact string including space and case sensitive.
I usually use ActionListener. Prepare for null value and case sensitivity.
public void subList() {
//sets up sub list based on selection in managerbox
cboManager.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object selected = cboManager.getSelectedItem();
if (selected != null && selected.equalsIgnoreCase("Eric White") ) {
System.out.println("eric white");
}
}
});
}
I have two JComboBoxes where the other one dynamically changing the value based on user choices. I properly get the id of those selected item. But getting the first element of my JComboBox gives me a zero value where I wanted to get the id without firing the ItemListener.
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ("Add".equals(e.getActionCommand())) {
System.out.println("Position id is " + getPositionId());
}
}
}
ItemListener itemListener = new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getSource() == department) {
Department item = (Department) department.getSelectedItem();
int departmentId = item.getId();
model.setDeptId(departmentId);
List<Position> list = model.getAllPositionId();
DefaultComboBoxModel positionModel = new DefaultComboBoxModel(list.toArray());
position.setModel(positionModel);
}
else if (e.getSource() == position) {
Position item = (Position) cbPosition.getSelectedItem();
int positionId = item.getId();
model.setPositionId(positionId);
}
}
}
Every time the user changed the selected value. DefaultComboBoxModel changed also its value with corresponding id. But getting it returns me 0.
I already found a solution. I just created a void method outside the ItemListener where it gets the first element.
first question...
I've read the tutorial at http://www.orbital-computer.de/JComboBox/ and based on that I have made modifications to create a class that you pass an existing JComboBox in order to make it searchable.
I've managed to make the JComboBox modify the results but there seems to be something going on with the caret that I've broken.
Specifically I want any JComboBox passed to this class, to auto-select any existing items in the list that return true for my .indexOf statement.
Code:
public class SearchableJComboBox extends PlainDocument {
JComboBox comboBox;
ComboBoxModel model;
JTextComponent editor;
// flag to indicate if setSelectedItem has been called
// subsequent calls to remove/insertString should be ignored
boolean selecting=false;
boolean hidePopupOnFocusLoss;
boolean hitBackspace=false;
boolean hitBackspaceOnSelection;
public SearchableJComboBox(final JComboBox comboBox) {
this.comboBox = comboBox;
model = comboBox.getModel();
editor = (JTextComponent) comboBox.getEditor().getEditorComponent();
editor.setDocument(this);
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
editor.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (comboBox.isDisplayable()) comboBox.setPopupVisible(true);
hitBackspace=false;
}
});
// Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out
hidePopupOnFocusLoss=System.getProperty("java.version").startsWith("1.5");
// Highlight whole text when gaining focus
editor.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
// Workaround for Bug 5100422 - Hide Popup on focus loss
if (hidePopupOnFocusLoss) comboBox.setPopupVisible(false);
}
});
// Handle initially selected object
Object selected = comboBox.getSelectedItem();
if (selected!=null) setText(selected.toString());
}
void setPrototypeValue(Object value, JList list) {
comboBox.setPrototypeDisplayValue(value);
list.setPrototypeCellValue(value);
}
JList getListBox() {
JList listBox;
try {
Field field = JComponent.class.getDeclaredField("ui");
field.setAccessible(true);
BasicComboBoxUI ui = (BasicComboBoxUI) field.get(comboBox);
field = BasicComboBoxUI.class.getDeclaredField("listBox");
field.setAccessible(true);
listBox = (JList) field.get(ui);
} catch (NoSuchFieldException nsfe) {
throw new RuntimeException(nsfe);
} catch (IllegalAccessException iae) {
throw new RuntimeException(iae);
}
return listBox;
}
public void remove(int offs, int len) throws BadLocationException {
// return immediately when selecting an item
if (selecting) return;
if (hitBackspace) {
// user hit backspace => move the selection backwards
// old item keeps being selected
if (offs>0) {
if (hitBackspaceOnSelection) offs--;
} else {
// User hit backspace with the cursor positioned on the start => beep
comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
}
} else {
super.remove(offs, len);
}
}
private void setText(String text) {
try {
super.remove(0, getLength());
super.insertString(0, text, null);
} catch (BadLocationException e) {
throw new RuntimeException(e.toString());
}
}
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
// return immediately when selecting an item
if (selecting) return;
// insert the string into the document
super.insertString(offs, str, a);
// lookup and select a matching item
Object item = lookupItem(getText(0, getLength()));
if (item != null)
setSelectedItem(item);
}
private void setSelectedItem(Object item) {
selecting = true;
model.setSelectedItem(item);
selecting = false;
}
private Object findStringWithin(String pattern) {
for(int i=0; i<model.getSize();i++)
{
if(model.getElementAt(i).toString().toLowerCase().indexOf(pattern.toLowerCase())!=-1)
return model.getElementAt(i);
}
return null;
}
private Object lookupItem(String pattern) {
return this.findStringWithin(pattern);
}
}
I checked your code and the website you reference.
No where do you include the line from the "curser" section:
editor.setCaretPosition(getLength());
This causes your caret to get stuck at the beginning, and essentially as you type you over-write the previous characters.
Give it a try ...