I want to create a jTree which when i right click on a node, should give me the options of "rename","add Region(parent)","add City(child)".
the name of my jTree is branches
As i am new to swing,Could any one help with code. Thanks in Advance.
Regards, Sarkwa
I recommend you to use setComponentPopupMenu method of JTree with MouseListener. In mouseListener determine Node for menu and generate popupMenu once. I write a simple example which can help you to do your work.
public class Main extends javax.swing.JFrame {
private JTree t;
private DefaultTreeModel model;
private DefaultMutableTreeNode selectedNode;
public Main() {
DefaultMutableTreeNode n = new DefaultMutableTreeNode("test");
n.add(new DefaultMutableTreeNode("test2"));
model = new DefaultTreeModel(n);
t = new JTree(model);
t.setEditable(true);
t.setComponentPopupMenu(getPopUpMenu());
t.addMouseListener(getMouseListener());
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(t);
pack();
setVisible(true);
}
private MouseListener getMouseListener() {
return new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
if(arg0.getButton() == MouseEvent.BUTTON3){
TreePath pathForLocation = t.getPathForLocation(arg0.getPoint().x, arg0.getPoint().y);
if(pathForLocation != null){
selectedNode = (DefaultMutableTreeNode) pathForLocation.getLastPathComponent();
} else{
selectedNode = null;
}
}
super.mousePressed(arg0);
}
};
}
private JPopupMenu getPopUpMenu() {
JPopupMenu menu = new JPopupMenu();
JMenuItem item = new JMenuItem("edit");
item.addActionListener(getEditActionListener());
menu.add(item);
JMenuItem item2 = new JMenuItem("add");
item2.addActionListener(getAddActionListener());
menu.add(item2);
return menu;
}
private ActionListener getAddActionListener() {
return new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if(selectedNode != null){
System.out.println("pressed" + selectedNode);
DefaultMutableTreeNode n = new DefaultMutableTreeNode("added");
selectedNode.add(n);
t.repaint();
t.updateUI();
}
}
};
}
private ActionListener getEditActionListener() {
return new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if(selectedNode != null){
//edit here
System.out.println("pressed" + selectedNode);
}
}
};
}
public static void main(String... s){
new Main();
}
}
getPopUpMenu method generate your popUp. For all items in popUp I add Listener for actions. For renaming nodes I recommend you to use CellEditor instead of menu, i write simple example of using it here.
And read this tutorial for JTree
Steps:
Add a MouseListner to the JTree
Have the mouse listener only respond to events from Button3 (right click).
Have the listner's action display a JPopupMenu.
In the menu add your options
Your options will have actions that will need to have a reference back to the JTree for the appropriate modifications to happen.
Related
How can we add a close button on the Pop up window similar to a JFrame on the right corner so that we can close that popup by clicking on it?
Thanks for the help
You can create your own PopMenu by extanding JPopupMenu. By adding an action listener to the button you can react with anything you want(for example closing popup). Here is an example:
public class TestPopupMenu extends JPopupMenu {
private JLabel testLabel;
private JButton testButton;
public TestPopupMenu() {
super();
initMenuItems();
}
private void initMenuItems() {
add(getTestLabel());
add(getTestButton());
}
private JButton getTestButton() {
if (testButton == null) {
testButton = new JButton("Test");
testButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Do something what you want
}
});
}
return testButton;
}
private JLabel getTestLabel() {
if (testLabel == null) {
testLabel = new JLabel("#Some text");
}
return testLabel;
} }
I'm getting stuck while building a forum like application which has a vote button.
I have vote up and vote down button for each content which are automatically generated. I want this button to only display the up and down arrow but not any text or label.. how can i find out which button is pressed?
Automated content..
ImageIcon upvote = new ImageIcon(getClass().getResource("vote_up.png"));
ImageIcon downvote = new ImageIcon(getClass().getResource("vote_down.png"));
JButton vote_up = new JButton(upvote);
JButton vote_down = new JButton(downvote);
vote_up.addActionListener(voting);
vote_down.addActionListener(voting);
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
//What to do here to find out which button is pressed?
}
};
any help is appreciated.
public void a(){
int crt_cnt = 0;
for(ClassA temp : listofClassA)
{
b(crt_cnt);
crt_cnt++;
}
}
public void b(crt_cnt){
//draw button
}
As from above, I have multiple vote_up and vote_down button created by the b function, how can i differentiate which crt_cnt is the button from?
There are multiple ways you might achieve this
You could...
Simply use the source of the ActionEvent
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up) {
//...
} else if (...) {
//...
}
}
};
This might be okay if you have a reference to the original buttons
You could...
Assign a actionCommand to each button
JButton vote_up = new JButton(upvote);
vote_up.setActionCommand("vote.up");
JButton vote_down = new JButton(downvote);
vote_down .setActionCommand("vote.down");
//...
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if ("vote.up".equals(e.getActionCommand())) {
//...
} else if (...) {
//...
}
}
};
You could...
Take full advantage of the Action API and make indiviual, self contained actions for each button...
public class VoteUpAction extends AbstractAction {
public VoteUpAction() {
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("vote_up.png")));
}
#Override
public void actionPerformed(ActionEvent e) {
// Specific action for up vote
}
}
Then you could simply use
JButton vote_up = new JButton(new VoteUpAction());
//...
Which will configure the button according to the properties of the Action and will trigger it's actionPerformed method when the button is triggered. This way, you know 100% what you should/need to do when the actionPerformed method is called, without any doubts.
Have a closer look at How to Use Actions for more details
You can detect by using the method getSource() of your EventAction
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up ) {
// vote up clicked
} else if (e.getSource() == vote_down){
// vote down clicked
}
}
};
hey thanks for all the help and assistance! I've finally got it! I solved it by
assigning a text on the button, +/- for vote up or down, followed by the content id which i required, then change the font size to 0
vote.setText("+"+thistopic.content.get(crt_cnt).get_id());
vote.setFont(heading.getFont().deriveFont(0.0f));
after that i could easily trace which button is pressed by comparing to the
actionEvent.getActionCommand()
which return the text on the button!
I would wrap the JButton similar to this:
JButton createMyButton(final JPanel panel, final String text,
final boolean upOrDown, final int gridx, final int gridy) {
final JButton button = new JButton();
button.setPreferredSize(new Dimension(80, 50));
final GridBagConstraints gbc = Factories.createGridBagConstraints(gridx,
gridy);
panel.add(button, gbc);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
myActionPerformed(text, upOrDown);
}
});
return button;
}
You could use an int instead of the text, if more convenient.
Newbie here.
When I added an element in the DefaultListModel, I used a class with an overriden toString.
Based on the sample code below, I want to display the selected item's ID when I click the button btnid.
The commands under displayID doesn't seem to work. Help please. Thanks!
class SomeClass {
JFrame f = new JFrame("Sample");
JScrollPane sp = new JScrollPane();
DefaultListModel dlm = new DefaultListModel();
JList lst = new JList(dlm);
public SomeClass() {
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnadd = new JButton("Add");
JButton btnid = new JButton("View ID");
Container p = f.getContentPane();
sp.getViewport().add(lst,null);
p.add(sp, BorderLayout.WEST);
p.add(btnadd, BorderLayout.EAST);
p.add(btnid, BorderLayout.SOUTH);
btnadd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dlm.addElement(new ElementDisplay(dlm.getSize(),"Element " + dlm.getSize()));
}
});
btnid.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayID();
}
});
f.pack();
f.setVisible(true);
}
private void displayID() {
ElementDisplay ed;
ed = dlm.getElementAt(lst.getSelectedIndex());
System.out.println(ed.elementID);
}
public static void main(String args[]) {
SomeClass sc = new SomeClass();
}
class ElementDisplay {
public int elementID;
private String elementDescription;
public ElementDisplay(int pid, String pdesc) {
elementID=pid;
elementDescription=pdesc;
}
#Override
public String toString() {
return elementDescription;
}
}
}
Works fine for me. What makes you think it doesn't work? You need to actually have an item selected in the list for the button press to work, you will get ArrayIndexOutOfBoundException
Instead of depending on a button press, just add a listener to the JList. That way only when the item in the JList is selected, does it print. No need for the button and trying to avoid the ArrayIndexOutOfBoundException
lst.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
JList list = (JList)e.getSource();
DefaultListModel model = (DefaultListModel)list.getModel();
ElementDisplay ed = (ElementDisplay) model.getElementAt(lst.getSelectedIndex());
System.out.println(ed.elementID);
}
}
});
See How to Write Event Listeners where you will run into possible listeners you can use for different components. As GUIs are event driven, you should take time to learn most of them.
Is there a way I can disable mouse click ? In the panel there are different components and for some of the Button Click events, I want to disable the mouse click. I mean the click of the mouse doesn't have any effect on the components. I can disable using the setEnabled() function but I don't want to do that way.
Is there any way I can disable the mouse click ?
Situation :
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
//..disable the mouse click on each component present inside the panel
}
You can add an extended ActionListener to all the buttons like this:
public abstract class ExtendedActionListener implements ActionListener{
private static boolean disabled = false;
public static void setDisabled(boolean disabled){
ExtendedActionListener.disabled = disabled;
}
#Override
public final void actionPerformed(ActionEvent e){
if(disabled)
return;
doSomething;
}
}
And now just disable all the ActionListeners by calling the method setDisabled(false). The Button visual behavior doesn't change at all, but nothing happens, when you click on it.
If the visual click behaviour doesn't matter, then you can just remove the MouseListeners.
You can create a button group like this:
public class SingleSelectionButtonGroup {
private final List<JButton> buttons;
public static SingleSelectionButtonGroup group(List<JButton> buttons) {
return new SingleSelectionButtonGroup(buttons);
}
public static SingleSelectionButtonGroup group(JButton...buttons) {
return new SingleSelectionButtonGroup(Arrays.asList(buttons));
}
private SingleSelectionButtonGroup(List<JButton> buttons) {
this.buttons = new ArrayList<JButton>(buttons);
setupListener();
}
private void setupListener() {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
SingleSelectionButtonGroup.this.disableAllExcept((JButton) e.getSource());
}
};
for (JButton button : buttons) {
button.addActionListener(listener);
}
}
private void disableAllExcept(JButton clickedButton) {
for (JButton button : buttons) {
if (!clickedButton.equals(button)) {
button.setEnabled(false);
}
}
}
}
And then uses it with a collection of buttons that you want to group:
public class Application {
public void run() {
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(400, 300));
final JPanel pane = new JPanel();
List<JButton> buttons = new ArrayList<JButton>();
String[] texts = {"A", "B", "C"};
for (String text : texts) {
JButton button = new JButton(text);
buttons.add(button);
pane.add(button);
}
SingleSelectionButtonGroup.group(buttons);
frame.getContentPane().add(pane);
frame.setVisible(true);
}
public static void main(String[] args) {
new Application().run();
}
}
you should use one common class of your listener and have static method for turn listener turn on and off
public abstract class BaseMouseListener implements ActionListener{
private static boolean active = true;
public static void setActive(boolean active){
BaseMouseListener.active = active;
}
protected abstract void doPerformAction(ActionEvent e);
#Override
public final void actionPerformed(ActionEvent e){
if(active){
doPerformAction(e);
}
}
}
your listeners would have to implements doPerformedAction()
Add empty mouse listener. This will "disable" the click because it will not have any effect.
I'm currently creating a right-click context menu by instantiating a new JMenu on right click and setting its location to that of the mouse's position... Is there a better way?
You are probably manually calling setVisible(true) on the menu. That can cause some nasty buggy behavior in the menu.
The show(Component, int x, int x) method handles all of the things you need to happen, (Highlighting things on mouseover and closing the popup when necessary) where using setVisible(true) just shows the menu without adding any additional behavior.
To make a right click popup menu simply create a JPopupMenu.
class PopUpDemo extends JPopupMenu {
JMenuItem anItem;
public PopUpDemo() {
anItem = new JMenuItem("Click Me!");
add(anItem);
}
}
Then, all you need to do is add a custom MouseListener to the components you would like the menu to popup for.
class PopClickListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger())
doPop(e);
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger())
doPop(e);
}
private void doPop(MouseEvent e) {
PopUpDemo menu = new PopUpDemo();
menu.show(e.getComponent(), e.getX(), e.getY());
}
}
// Then on your component(s)
component.addMouseListener(new PopClickListener());
Of course, the tutorials have a slightly more in-depth explanation.
Note: If you notice that the popup menu is appearing way off from where the user clicked, try using the e.getXOnScreen() and e.getYOnScreen() methods for the x and y coordinates.
This question is a bit old - as are the answers (and the tutorial as well)
The current api for setting a popupMenu in Swing is
myComponent.setComponentPopupMenu(myPopupMenu);
This way it will be shown automagically, both for mouse and keyboard triggers (the latter depends on LAF). Plus, it supports re-using the same popup across a container's children. To enable that feature:
myChild.setInheritsPopupMenu(true);
There's a section on Bringing Up a Popup Menu in the How to Use Menus article of The Java Tutorials which explains how to use the JPopupMenu class.
The example code in the tutorial shows how to add MouseListeners to the components which should display a pop-up menu, and displays the menu accordingly.
(The method you describe is fairly similar to the way the tutorial presents the way to show a pop-up menu on a component.)
The following code implements a default context menu known from Windows with copy, cut, paste, select all, undo and redo functions. It also works on Linux and Mac OS X:
import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DefaultContextMenu extends JPopupMenu
{
private Clipboard clipboard;
private UndoManager undoManager;
private JMenuItem undo;
private JMenuItem redo;
private JMenuItem cut;
private JMenuItem copy;
private JMenuItem paste;
private JMenuItem delete;
private JMenuItem selectAll;
private JTextComponent textComponent;
public DefaultContextMenu()
{
undoManager = new UndoManager();
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
addPopupMenuItems();
}
private void addPopupMenuItems()
{
undo = new JMenuItem("Undo");
undo.setEnabled(false);
undo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
undo.addActionListener(event -> undoManager.undo());
add(undo);
redo = new JMenuItem("Redo");
redo.setEnabled(false);
redo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
redo.addActionListener(event -> undoManager.redo());
add(redo);
add(new JSeparator());
cut = new JMenuItem("Cut");
cut.setEnabled(false);
cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
cut.addActionListener(event -> textComponent.cut());
add(cut);
copy = new JMenuItem("Copy");
copy.setEnabled(false);
copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
copy.addActionListener(event -> textComponent.copy());
add(copy);
paste = new JMenuItem("Paste");
paste.setEnabled(false);
paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
paste.addActionListener(event -> textComponent.paste());
add(paste);
delete = new JMenuItem("Delete");
delete.setEnabled(false);
delete.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
delete.addActionListener(event -> textComponent.replaceSelection(""));
add(delete);
add(new JSeparator());
selectAll = new JMenuItem("Select All");
selectAll.setEnabled(false);
selectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
selectAll.addActionListener(event -> textComponent.selectAll());
add(selectAll);
}
private void addTo(JTextComponent textComponent)
{
textComponent.addKeyListener(new KeyAdapter()
{
#Override
public void keyPressed(KeyEvent pressedEvent)
{
if ((pressedEvent.getKeyCode() == KeyEvent.VK_Z)
&& ((pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0))
{
if (undoManager.canUndo())
{
undoManager.undo();
}
}
if ((pressedEvent.getKeyCode() == KeyEvent.VK_Y)
&& ((pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0))
{
if (undoManager.canRedo())
{
undoManager.redo();
}
}
}
});
textComponent.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent releasedEvent)
{
handleContextMenu(releasedEvent);
}
#Override
public void mouseReleased(MouseEvent releasedEvent)
{
handleContextMenu(releasedEvent);
}
});
textComponent.getDocument().addUndoableEditListener(event -> undoManager.addEdit(event.getEdit()));
}
private void handleContextMenu(MouseEvent releasedEvent)
{
if (releasedEvent.getButton() == MouseEvent.BUTTON3)
{
processClick(releasedEvent);
}
}
private void processClick(MouseEvent event)
{
textComponent = (JTextComponent) event.getSource();
textComponent.requestFocus();
boolean enableUndo = undoManager.canUndo();
boolean enableRedo = undoManager.canRedo();
boolean enableCut = false;
boolean enableCopy = false;
boolean enablePaste = false;
boolean enableDelete = false;
boolean enableSelectAll = false;
String selectedText = textComponent.getSelectedText();
String text = textComponent.getText();
if (text != null)
{
if (text.length() > 0)
{
enableSelectAll = true;
}
}
if (selectedText != null)
{
if (selectedText.length() > 0)
{
enableCut = true;
enableCopy = true;
enableDelete = true;
}
}
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor) && textComponent.isEnabled())
{
enablePaste = true;
}
undo.setEnabled(enableUndo);
redo.setEnabled(enableRedo);
cut.setEnabled(enableCut);
copy.setEnabled(enableCopy);
paste.setEnabled(enablePaste);
delete.setEnabled(enableDelete);
selectAll.setEnabled(enableSelectAll);
// Shows the popup menu
show(textComponent, event.getX(), event.getY());
}
public static void addDefaultContextMenu(JTextComponent component)
{
DefaultContextMenu defaultContextMenu = new DefaultContextMenu();
defaultContextMenu.addTo(component);
}
}
Usage:
JTextArea textArea = new JTextArea();
DefaultContextMenu.addDefaultContextMenu(textArea);
Now the textArea will have a context menu when it is right-clicked on.
I will correct usage for that method that #BullyWillPlaza suggested. Reason is that when I try to add add textArea to only contextMenu it's not visible, and if i add it to both to contextMenu and some panel it ecounters: Different parent double association if i try to switch to Design editor.
TexetObjcet.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)){
contextmenu.add(TexetObjcet);
contextmenu.show(TexetObjcet, 0, 0);
}
}
});
Make mouse listener like this for text object you need to have popup on. What this will do is when you right click on your text object it will then add that popup and display it. This way you don't encounter that error. Solution that #BullyWillPlaza made is very good, rich and fast to implement in your program so you should try it our see how you like it.