Adding an ActionListener to a JList - swing

I have a JList with an array of strings. Basically it displays a restaurant menu.
right next to the JList i have another JList which is empty. Whenever a user double clicks on a string in the first JList (where the menu is displayed) I want it to show up on the next JList which is right next to it.
how do i do that?

You can try
final JList list = new JList(dataModel);
MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
String selectedItem = (String) list.getSelectedValue();
// add selectedItem to your second list.
DefaultListModel model = (DefaultListModel) list2.getModel();
if(model == null)
{
model = new DefaultListModel();
list2.setModel(model);
}
model.addElement(selectedItem);
}
}
};
list.addMouseListener(mouseListener);

You may also want to do it with the Enter key pressed by adding a KeyListener:
jlist.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_ENTER){
//do what you want to do
}
}
});
I know that this is not for a double click but some people want to do it with the Enter button instead as I wanted to do.

I have done it already in your code in the other question?
[link] I want to add an action listener from one JList to another JList and how can a JList appear with out any text inside?
The only think you must do there is to put it into the #Bala R's if statement doing the check of number of clicks:
if (e.getClickCount() == 2) {
//your code
}
Actually you would be better to use addElement(selectedItem); method, as in the #Bala R's code instead of
add(orderList.getModel().getSize(), selectedItem); in my code. Both add the item to the end but addElement looks nicer and you do not need to retrieve the model's size.
Oi, Boro.

public void addActionListener(final ActionListener al) {
jList.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
al.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "ENTER"));
}
}
});
jList().addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
al.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "ENTER"));
}
}
});
}

Related

How to add timer to change image for selected item in ListPicker

what would be the steps to add timer to change selected item's image in listpicker. Any suggestions? FYI, have never used ListPicker before. So i am finding it kind of hard to understand where to start and what to do.
You will need an ObservableCollection of your ImageSources and a DispatcherTimer to fire the events every TimeSpan of your choosing.
Here's some code to help you get started. You can modify it to do exactly what you want. It basically contains a ListPicker that has a collection of images as its ItemTemplate. Every one second the DispatchTimer fires and switches the selectedItem's Image between the 2 default images that are created in about every single WP8.0 application.
Make it a habit to use ObervableCollection when you want to display something to the user instead of a List, it will make your WP8 development life a lot easier.
XAML
<toolkit:ListPicker x:Name="my_listpicker" SelectionChanged="my_listpicker_SelectionChanged_1" Background="Black">
<toolkit:ListPicker.HeaderTemplate>
<DataTemplate/>
</toolkit:ListPicker.HeaderTemplate>
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Background="Black">
<Image Source="{Binding ImageSource}" Height="200"></Image>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
C# Namespaces
using System.ComponentModel; // ObservableCollection
using System.Collections.ObjectModel; // INotifyPropertyChanged
using System.Windows.Threading; // Dispatch Timer
C# Model of your Images (pretty basic, but pay attention to the INotifyPropertyChanged
public class MyBindingImage : INotifyPropertyChanged
{
public MyBindingImage() { }
public MyBindingImage(string source)
{
this.ImageSource = source;
}
// Create the OnPropertyChanged method to raise the event
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
string image_source;
public String ImageSource {
get { return image_source; }
set
{
image_source = value;
OnPropertyChanged("ImageSource");
}
}
}
C# (Create the Timer and ObservableCollection and Set the ItemSource)
DispatcherTimer timer;
// Constructor
public MainPage()
{
// create our dispatch timer
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += OnTimerTick;
InitializeComponent();
// create our list picker elements
ObservableCollection<MyBindingImage> my_image_list = new ObservableCollection<MyBindingImage>();
my_image_list.Add(new MyBindingImage("Assets/ApplicationIcon.png"));
my_image_list.Add(new MyBindingImage("Assets/AlignmentGrid.png"));
my_listpicker.ItemsSource = my_image_list;
}
C# Events (For the Timer & ListPicker SelectionChange)
// each time the selection has changd: stop the timer, then start it again
private void my_listpicker_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
if (timer != null)
{
timer.Stop();
timer.Start();
}
}
// if the timer is on, cycle the images of the selected item
private void OnTimerTick(object sender, EventArgs e)
{
try
{
MyBindingImage item = (MyBindingImage) my_listpicker.SelectedItem;
// cycle the selected image between to different images
if (item.ImageSource == "Assets/AlignmentGrid.png")
{
item.ImageSource = "Assets/ApplicationIcon.png";
}
else
{
item.ImageSource = "Assets/AlignmentGrid.png";
}
}
catch (Exception ex)
{
string error_message = ex.Message;
}
}
[APPLICATION SCREENSHOT]

Listener on MenuBar in Vaadin

I want to add a ClickListener to an Item of a MenuBar in Vaadin.
I know about the normal situation, which i got working:
MenuBar menubar = new MenuBar();
menubar.addItem("Item", new MenuBar.Command() {
#Override
public void menuSelected(MenuItem selectedItem) {
//Do sth. when item is clicked
}
});
In my application, I'm working with MVP, so the code which should run, is in an other class than the code which is defining the menubar.
Is there a way to add a listener to a specific item in the menubar ?
When you add an item to your MenuBar the function addItem(String,Command) actually returns a MenuItem which can be used later. You can do this :
MenuItem select = menuBar.addItem("Select", null);
And in another context you can add a listener on that MenuItem like this:
select.setCommand(new Command() {
#Override
public void menuSelected(MenuItem selectedItem) {
System.out.println("You clicked on "+selectedItem.getText());
}
});

Force stop edit cell in JTable on mouse click

How to force stop editing a cell in a JTable when the user clicks on any other component than the table itself?
Tried this but it didn't work...
myTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
... or this, which also does not work as expected
Component co = myTable.getEditorComponent();
if (co != null && !(co instanceof JComboBox)) {
co.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) {
TableCellEditor tce = myTable.getCellEditor();
if (tce != null) {
tce.stopCellEditing(); // should accept partial edit
}
}
});
}
Having a button with an action listener attached to it makes it possible to force stop editing of any cell in the table, however that's not really the solution I am looking for.
It should work by clicking on any component.
SSCCE
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
public class TableExample {
public static void main(String args[]) {
final Object rowData[][] = { { "1", "one", "not empty" }, { "2", "two", "" }, { "3", "three", "" } };
final String columnNames[] = { "#", "Some Column", "Some Other Column" };
final JTable table = new JTable(rowData, columnNames);
JScrollPane scrollPane = new JScrollPane(table);
table.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
System.out.println("column: "+e.getColumn());
if(1==e.getColumn()){
System.out.println(table.getModel().getValueAt(e.getLastRow(), e.getColumn()));
String value = table.getModel().getValueAt(e.getLastRow(), e.getColumn()).toString();
int rowIndex = e.getLastRow();
if(table.getModel().getValueAt(e.getLastRow(), 2).toString().isEmpty())
table.getModel().setValueAt(value,e.getLastRow(), 2);
}
}
});
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
table.setValueAt("",0,0);
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(700, 150);
frame.setVisible(true);
}
}
The table does not take up all the space in the viewport of the scrollpane so you are actually clicking on the viewport. By default a viewport doesn't gain focus when you click on it so there is no focusLost method generated on the table.
Maybe you can just use the following so the table fills the viewport:
table.setFillsViewportHeight(true);
Otherwise, you would need to add a MouseListener to the viewport to handle the mouse click event. You would need to do this for all components on the frame that cannot receive focus, like a JPanel.
Or, maybe another approach is to use an AWTEventListener to listen for all mouse clicks. The draw back to this approach is that you can't distinguish between a click on a focusable component and a non-focusable component so you would be attempting to stop the cell editing every time a click is made. See Global Event Listeners for more information.

JTree and dropdown options on right clicking nodes

I'm trying to use the JTree and implement different drop downs for all the parent nodes and the children nodes.
Here's what I've done:
pmTree.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
try {
if(evt.getButton() == evt.BUTTON1) {
}
else if (evt.getButton() == evt.BUTTON3) {
TreePopup(evt);
//pmTree.updateUI();
}
}catch (Exception e) {}
}
});
and PopupCode:
public void TreePopup(java.awt.event.MouseEvent evt) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) pmTree.getLastSelectedPathComponent();
popup = new JPopupMenu();
popup.setInvoker(pmTree);
PopupHandler handler = new PopupHandler(pmTree, popup);
if(node.getLevel() == 1)
{
popup.add(getMenuItem("Parent Node", handler));
}
else if(node.getLevel() == 2)
{
popup.add(getMenuItem("Child", handler));
}
}
and PopUpHandler:
public class PopupHandler extends javax.swing.JFrame implements ActionListener {
JPopupMenu popup;
Point loc;
public PopupHandler(JTree tree, JPopupMenu popup) {
//this.tree = NewJFrame.pmTree;
this.popup = popup;
tree.addMouseListener(ma);
}
and also the
public void actionPerformed(java.awt.event.ActionEvent evt)
for the Child or Parent node being clicked.
However, when I run the program, I get the SAME right click popups for both the child and parent node.
Sorry for the huge chunk of code. I've been stuck with it for 2 days and yet not successful.
Thanks!
Don't go as low-level as a MouseListener, instead use the api around componentPopupMenu. Doing so, the general approach is dynamically configure the componentPopup in the getPopupLocation method, some simple example snippet:
JPopupMenu popup = new JPopupMenu();
final Action action = new AbstractAction("empty") {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
};
popup.add(action);
JTree tree = new JTree() {
/**
* #inherited <p>
*/
#Override
public Point getPopupLocation(MouseEvent e) {
if (e != null) {
// here do your custom config, like f.i add/remove menu items based on context
// this example simply changes the action name
TreePath path = getClosestPathForLocation(e.getX(), e.getY());
action.putValue(Action.NAME, String.valueOf(path.getLastPathComponent()));
return e.getPoint();
}
action.putValue(Action.NAME, "no mouse");
return null;
}
};
tree.setComponentPopupMenu(popup);
You check the selected node:
DefaultMutableTreeNode node = (DefaultMutableTreeNode)pmTree.getLastSelectedPathComponent();
to see if you have a "parent" or a "child" node. You should select the node at the mouse position first, otherwise it will not be the right node. Call
TreePath path = pmTree.getPathForLocation(evt.getX(), evt.getY());
if (path != null) {
pmTree.setSelectionPath(path);
} else {
return;
}
at the beginning of treePopup. (methods in Java should start with a lower case letter!)
Awesome. I was successfully able to put the setSelectionPath() call inside the override of getPopupLocaiton(). I had been trying to do it inside the ActionListener of my JMenuItem to no avail.
public Point getPopupLocation( MouseEvent e ) {
Point point = null;
if( e != null ) {
TreePath path = getClosestPathForLocation( e.getX(), e.getY() );
setSelectionPath( path );
point = e.getPoint();
}
return point;
}

JTable with JComboBox editor : Is it possible to edit the cell value from keyboard with one key press

I'm having a JTable containing JComboBox editors initialized somewhat like
JComboBox comboBox = ...;
TableColumn tc = table.getColumnModel().getColumn(i);
tc.setCellEditor(new DefaultCellEditor(comboBox));
This is working otherwise fine but I'd like to be able to navigate in the table and update the values with keyboard only. Now this is possible with the combo boxes but if I want to update the value "1" I must first press a key to activate the combo box and then press "1" to select the item.
So, what I want is that I could press "1" and the item would be selected with only one key press.
For the text cells I've managed to do this with prepareEditor like the following...
#Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
Component c = super.prepareEditor(editor, row, column);
if (c instanceof JTextComponent) {
((JTextComponent) c).selectAll();
}
return c;
}
... but I haven't managed to figure out what to do with the combo box.
One possibility could be own TableCellEditor but if there's a more simple solution that would be nice =)
br,
Touko
In case anyone is still interested, I do a simple modification to Touko's code and this works for me:
public class CustomTable extends JTable {
private static final long serialVersionUID = -8855616864660280561L;
public CustomTable(TableModel tableModel) {
super(tableModel);
}
#Override
public Component prepareEditor(TableCellEditor editor, int row, int column) {
final Component comp = super.prepareEditor(editor, row, column);
// Text component should select all text when initiated for editing.
if (comp instanceof JTextComponent)
((JTextComponent) comp).selectAll();
// Try to obtain focus for the editor component.
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() { comp.requestFocusInWindow(); }
});
return comp;
}
}
So basically, I'm just requesting focus for the editor component at some later time using SwingUtilities.invokeLater. The reason for this approach is because focus request will fail if the editor component is not yet visible.
Hope this can help anyone.
You must add a KeyListener to your code.
The best solution is add it to the JTable component where you are laying the JComboBox and implement the method keyPressed(KeyEvent e) or the keyReleased(KeyEvent e) one in order to know which is the key and do the necessary action.
Here I give you an example:
JTable table = new JTable();
// Your necessary code (create combo box, cell editor...etc)
table.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch(keyCode) {
case KeyEvent.VK_1:
// manage key 1
break;
case KeyEvent.VK_A:
// manage key A
break;
case KeyEvent.VK_F1:
// manage key F1
break;
case KeyEvent.VK_TAB:
// manage key TAB
break;
default:
// manage other keys
}
}
});
You also can combine this solution with a dictionary which relates the keyCode with an action interface.
This second solution needs the following code:
A global attribute (the dictionary):
Map<Integer,MyAction> keyActions = new Hashmap<Integer,MyAction>();
A own action interface:
public interface MyAction {
public void doAction();
}
And the KeyListener.keyPressed() function would be the following:
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
MyAction ma = keyActions.get(keyCode);
if (ma != null) {
ma.doAction();
}
else {
// do default action for other keys
}
}
I hope this helps you.
Regards!