I want to update JComboBox when I type in the JComboBox editor. It will get the text of JComboBox editor in real time and add some items based on the text. I have tried like this:
final JTextField tfListText = (JTextField) comboBox1.getEditor().getEditorComponent();
tfListText.addCaretListener(new CaretListener() {
private String lastText;
#Override
public void caretUpdate(CaretEvent e) {
String text = tfListText.getText();
if (!text.equals(lastText)) {
lastText = text;
comboBox1.removeAllItems();
// get some items based on text
comboBox1.addItem(someItems1);
...
}
}
});
However, the selected item of JComboBox was changed when using method removeAllItems() or addItem(), and it caused an endless loop triggering the CaretListener again.
So how to update JComboBox without selected item being changed, or is there any other way to add items based on the input content in real time
Related
I am stuck with Jlist and never thought that Jlist can be that complicated.
With a left mouse click on Jlist item I want to do some action. I know that i need action listener but I was not able to get it work.
In my specific case there are saved paths to .sql files in JList. When I click on item in JList I want to read from that file and save it to JTextArea.
Maybe I am putting listener on wrong place in code? Or I am coding wrong?
Model Name = model
JList Name = SQLScriptList
Jtextarea Name = SQLEditor
With this code I tried to save item from the list in specific label or textbox just to see if action work.
//Copy from LIST to TextArea
MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1) {
String selectedItem = (String) SQLScriptList.getSelectedValue();
// add selectedItem to your second list.
DefaultListModel model = (DefaultListModel) SQLScriptList.getModel();
if (model == null) {
//model = new DefaultListModel();
SQLScriptList.setModel(model);
}
model.addElement(selectedItem);
}
SQLScriptList.addMouseListener(mouseListener);
}
//list.addMouseListener(mouseListener);
};
Solved
Here is solution that worked in my case:
private void SQLScriptListMouseClicked(java.awt.event.MouseEvent evt) {
JList list = (JList) evt.getSource();
if (evt.getClickCount() == 2) {
int index = list.locationToIndex(evt.getPoint()); //GET INDEX 0,1,2,3
try {
FileReader reader = new FileReader(files[index]);
SQLEditor.read(reader, files[index]); //Object of JTextArea
} catch (Exception e) {
e.printStackTrace();
}
}
}
When I click on item in JList I want to read from that file and save it to JTextArea.
Normally this is not done on a single mouse click.
Typically the Action is invoked when the user:
uses the Enter key, or
double clicks on the item
For this type of processing check out List Action which allows you to provide an Action to be invoked in either of the above situations.
Otherwise you should use a MouseListener, not a ListSelectionListener as suggested in the comments above, since the user should be able to navigate through the items in the list using the down/up arrow keys without causing the action to be invoked. Read the section from the Swing tutorial on How to Write a MouseListener for working examples.
private void createEvents()
{
menuFileExit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
////// Events on tree selection
jtStoryViewer.addTreeSelectionListener(new TreeSelectionListener()
{
public void valueChanged(TreeSelectionEvent arg0)
{
DefaultMutableTreeNode selection = (DefaultMutableTreeNode) jtStoryViewer.getLastSelectedPathComponent();
Object nodeObject = selection.getUserObject();
////// Checks if selected node is a String (only story title is a string)
if(selection.getUserObject().getClass().getName() == "java.lang.String" )
{
tfTitle.setText(nodeObject.toString());
////// Action listener for Change Button
btnChange.addActionListener(new ActionListener()
{
////// Title text swap
public void actionPerformed(ActionEvent arg0)
{
selection.setUserObject(tfTitle.getText());
((DefaultTreeModel)jtStoryViewer.getModel()).nodeChanged(selection);
}
});
}
///// checks if the object is a chapter object
if(selection.getUserObject().getClass().getName() == "ISW.common.Chapter")
{
Chapter chapter = (Chapter) selection.getUserObject();
tfTitle.setText(chapter.toString());
////// Action listener for Change Button
btnChange.addActionListener(new ActionListener()
{
////// Title text swap
public void actionPerformed(ActionEvent arg0)
{
chapter.setTitle(tfTitle.getText());
((DefaultTreeModel)jtStoryViewer.getModel()).nodeChanged(selection);
}
});
}
}
});
}
I am using JTree to display and modify some objects. I added a TreeSelectionListener to get the object data on selection. For now I want to be able to change the title of an object, it works fine on first selection on the tree , I change the value in the text box and the "Change" button works just fine, but when I move on to next objects, the change button also modifies the value of all previously selected objects.
I guess it is caused due to my improper usage of the ActionListeners but I can't tell for sure and at this point I'm stuck.
Will be grateful for any hints.
Don't keep adding an ActionListener to the btnChange JButton within the TreeSelectionListener#valueChanged method.
This will cause the button to call EVERY ActionListener you have previously
Instead, give the btnChange a single ActionListener, when clicked, can act on the currently selected node (by checking the JTree it self). You could have the TreeSelectionListener#valueChanged method enable or disable the btnChange based on the validity of the selection
Also, if(selection.getUserObject().getClass().getName() == "ISW.common.Chapter") isn't how String comparison is done in Java, instead you should use something more like if("ISW.common.Chapter".equals(selection.getUserObject().getClass().getName()))
I got a quite tricky problem when I do some code on JTable
I need to add one line In JTable when I click "Add" button, and I want one of the columns to render
as a JComboBox
the problem is that when I only add one line, it works fine.
but when I add multiple lines a time, no matter which combobox I choose item from, It will always trigger the last comboBox's event(seems always the same combobox since I have printed the hashcode of jComboBox in MyComboxActionListener class. it's the same).
why is that happens , I can't figure it out. Since It's totally a new comboBox and a new listener when I add one line.
Following is the code.
Thanks in advance.
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
ProducedProcedure_new addedProducedProcedure = new ProducedProcedure_new(); // the new item
componentProcedureTableModel.getWorks().add(addedProducedProcedure); //add one line to the table
componentProcedureTableModel.fireTableRowsInserted(componentProcedureTableModel.getRowCount()-1, componentProcedureTableModel.getRowCount()-1);
jTable1.changeSelection(componentProcedureTableModel.getRowCount()-1,0, false, false);
List<String> procedureNames = produceCardManager.getProcedureNames(componentIdTextField.getText().trim(),false); //get the items added to combobox
renderColumnAsCombox(1,procedureNames,addedProducedProcedure); //-------------------------------------------
}
void renderColumnAsCombox(int columnIndex , List<String> items,ProducedProcedure_new producedProcedure) {
TableColumn col = jTable1.getColumnModel().getColumn(columnIndex);
JComboBox comboBox = new JComboBox();
for(String item : items) {
comboBox.addItem(item);
}
MyComboxActionListener myComboxActionListener = new MyComboxActionListener(columnIndex,comboBox,producedProcedure);
comboBox.addActionListener(myComboxActionListener);
col.setCellEditor(new DefaultCellEditor(comboBox));
}
class MyComboxActionListener implements ActionListener { // listen for the select event of the combobox
private JComboBox jComboBox;
private ProducedProcedure_new producedProcedure;
private int columnIndex;
public MyComboxActionListener(int columnIndex,JComboBox jComboBox,ProducedProcedure_new producedProcedure) {
this.columnIndex = columnIndex;
this.jComboBox = jComboBox;
this.producedProcedure = producedProcedure;
}
#Override
public void actionPerformed(ActionEvent e) {
String selectedItem = (String)jComboBox.getSelectedItem();
producedProcedure.getProcedure().setProcedureName(selectedItem);
producedProcedure.getProcedure().setProcedureId(String.valueOf(produceCardManager.getProcedureId(selectedItem)));
producedProcedure.getProcedure().setFactor(produceCardManager.getProcedureFactor(selectedItem)); //automately update the factor
((ComponentProcedureTableModel_new)jTable1.getModel()).fireTableDataChanged();
}
}
I have 2 comboboxes and a spinner, that work like this: if the selected item of the first combo is changed, the second combo keeps its selected item but re-calls the spinner (the spinner is linked only to the second box). My problem is that I can't trigger the stateChange listener of the spinner when I do this.
Here is the code for forcing the second box to reselect its last item when the first one is changed (nothing wrong here, it works just fine):
String orientare = (String) orientareComboBox.getSelectedItem();
orientareComboBox.setSelectedItem(orientare);
This is the code for the second box actionListener:
public void actionPerformed(ActionEvent e) {
JComboBox combo = (JComboBox) e.getSource();
String value = combo.getSelectedItem().toString();
if (value.equalsIgnoreCase("oblica"))
{
unghiSpinner.setEnabled(true);
double unghi = (double) unghiSpinner.getValue();
unghiSpinner.setValue(new Double(unghi));
}
}
And the spinner's Listener:
public void stateChanged(ChangeEvent e)
{
if (unghiSpinner.isEnabled())
{
// do something
}
}
I do not know what command I should use for unghiSpinner to trigger its listener, because setValue() can't do it.
I don't see you changing the value of your JSpinner in the code above. It appears that all you do is set the spinner's value to the same value that it held previously, and that shouldn't trigger the listener. To trigger a change listener to fire you must change the state of the observed entity.
I'm using Vaadin and have a set of textfields in a form. The textfields has focusListeners that triggers a method that focuses all the text in the texfield if there is any.
My problem though is that the auto selection works literally half the time. If I paste some text in a textfield, clicks outside the textfield and then clicks inside it the text will be selected. However, if I click outside again and then in the textfield the text will for a fraction of a second be selected to then only having the input marker where ever it was I clicked in the text.
Here's the code:
class FormTextField extends FormLayout {
private static final long serialVersionUID = -2738069810605965508L;
String caption;
final STextField textField = Cf.formTextField(caption, "", 22);
public FormTextField(String textField) {
addStyleName("panelform");
setWidth(formWidth, UNITS_EM);
this.textField.setCaption(textField);
this.textField.setImmediate(true);
this.textField.addListener(new FieldEvents.FocusListener() {
#Override
public void focus(FocusEvent event) {
textFieldSelectAll();
}
});
addComponent(this.textField);
}
private void textFieldSelectAll() {
this.textField.selectAll();
}
public STextField getTextField() {
return textField;
}
}
}
I'm very interested to know if someone of you are familiar with this problem and have been able to sort it out?
If you want any more information from me then please ask!
I think you need to declare your FormTextField/STextField immediate too.
Hope this helps.