Show popup menu on a jlist - java

I have problem with popup menu. That that I want is that when the user click the right mouse button on a jlist a popup menu appear. I have created a class where I create the popup menu, a class that extend mouselistener, and another class where I add mouse listener to the jlist.
In the class that extend mouselistener I call the class of the popup menu and i show it.
The problem is that the popup menu doesn't appear.
package mouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import view.___poupupmenu___;
public class Add_popupmenu_categoria implements MouseListener
{
JList <String> l = new JList <String> ();
public Add_popupmenu_categoria (JList <String> l)
{
this.l = l;
}
public void mouseClicked(MouseEvent evt)
{
System.out.println("clicked");
if (evt.isPopupTrigger())
{
System.out.println("enter in clicked");
___poupupmenu___ p = new ___poupupmenu___();
l.setSelectedIndex(l.locationToIndex(evt.getPoint()));
System.out.println(evt.getComponent());
l.setComponentPopupMenu(p.menu_categoria);
p.menu_categoria.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent evt)
{
System.out.println("pressed");
if (evt.isPopupTrigger())
{
System.out.println("enter in pressed");
___poupupmenu___ p = new ___poupupmenu___();
l.setSelectedIndex(l.locationToIndex(evt.getPoint()));
System.out.println(evt.getComponent());
l.setComponentPopupMenu(p.menu_categoria);
p.menu_categoria.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
public void mouseReleased(MouseEvent evt)
{
System.out.println("released");
if (evt.isPopupTrigger())
{
System.out.println("enter in released");
___poupupmenu___ p = new ___poupupmenu___();
l.setSelectedIndex(l.locationToIndex(evt.getPoint()));
System.out.println(evt.getComponent());
l.setComponentPopupMenu(p.menu_categoria);
p.menu_categoria.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
}
package view;
import javax.swing.*;
import java.awt.*;
public class ___poupupmenu___ {
public JPopupMenu menu_categoria = new JPopupMenu();
public JPopupMenu menu_scuola = new JPopupMenu();
public JPopupMenu menu_maschile_femminile = new JPopupMenu();
public JPopupMenu menu_dirigenti_allenatori = new JPopupMenu();
public JPopupMenu menu_img_profilo = new JPopupMenu();
JMenuItem menu_elimina = new JMenuItem("Elimina");
JMenuItem menu_modifica = new JMenuItem("Modifica");
JMenuItem menu_apri = new JMenuItem("Apri...");
JMenuItem menu_pagamento = new JMenuItem("Visualizza pagamenti");
JMenuItem menu_genitore = new JMenuItem("Visualizza genitore");
JMenuItem menu_visita_medica = new JMenuItem("Visualizza scadenza visita medica");
public ___poupupmenu___ ()
{
menu_elimina.setFont(new Font("Segoe UI", 1, 15));
menu_modifica.setFont(new Font("Segoe UI", 1, 15));
menu_apri.setFont(new Font("Segoe UI", 1, 15));
menu_pagamento.setFont(new Font("Segoe UI", 1, 15));
menu_genitore.setFont(new Font("Segoe UI", 1, 15));
menu_categoria.add(menu_modifica);
menu_categoria.add(menu_elimina);
menu_scuola.add(menu_apri);
menu_scuola.add(menu_visita_medica);
menu_scuola.add(menu_genitore);
menu_scuola.add(menu_pagamento);
menu_scuola.add(menu_modifica);
menu_scuola.add(menu_pagamento);
menu_maschile_femminile.add(menu_apri);
menu_maschile_femminile.add(menu_visita_medica);
menu_maschile_femminile.add(menu_modifica);
menu_maschile_femminile.add(menu_elimina);
menu_dirigenti_allenatori.add(menu_apri);
menu_dirigenti_allenatori.add(menu_modifica);
menu_dirigenti_allenatori.add(menu_elimina);
}
}
package controller;
import javax.swing.*;
import mouseListener.Add_popupmenu_categoria;
public class CategoriaController
{
public void add_popupmenu_Categoria (JList <String> l)
{
Add_popupmenu_categoria apmc = new Add_popupmenu_categoria (l);
l.addMouseListener(apmc);
}
}
When I click what I get is:
pressed
released
enter in released
javax.swing.JList[,0,0,897x797,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]
clicked
Someone can help me?

Edit: The simplest way is to just use the setComponentPopupMenu Method of the JList:
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("Hello World"));
JList<String> jList = new JList<String>();
jList.setComponentPopupMenu(popup);
setComponentPopupMenu(popup) appends the popup to the component. It will show automatically if you right-click the component. No MouseListener needed.
Another easy way to implement Popup-Menus for swing components is to override the getComponentPopupMenu() Method of JComponent. For you the solution would look something like this:
public class MyJListWithPopupMenu extends JList {
//...
#Override
public JPopupMenu getComponentPopupMenu() {
// create your PopupMenu
return myJPopupMenu;
}
//...
}
When you then use the MyJListWithPopupMenu instead of a regular JList, the popup wil show in the right place when you right-click on it.

Related

Is there a way to detect current selection in JPopupMenu (SelectionModel ChangeListener doesn't work)

I want to detect when selection changes inside a JPopupMenu. Not when a menu item is clicked, but when a menu item is selected (armed). With simpler words, I want to detect this:
The thing that should work is to add a ChangeListener to its SelectionModel, but it doesn't seem to respond to selection events:
public class PopupSelection extends JFrame {
private static final long serialVersionUID = 363879723515243543L;
public PopupSelection() {
super("something");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel label = new JLabel("right click me");
JPopupMenu menu = new JPopupMenu();
menu.getSelectionModel().addChangeListener(System.out::println);
JMenuItem menuItem1 = new JMenuItem("Item1");
JMenuItem menuItem2 = new JMenuItem("Item2");
JMenuItem menuItem3 = new JMenuItem("Item3");
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);
label.setComponentPopupMenu(menu);
getContentPane().add(label);
setSize(400, 400);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupSelection().setVisible(true));
}
}
Second thing I tried is with a PropertyChangeListener, but it does not work (does not detect this specific event) either:
menu.addPropertyChangeListener(System.out::println);
I know there is the alternative of adding a ChangeListener to each JMenuItem and each time iterate all components of the JPopupMenu in order to find which one is selected, but this is not a solution I want to follow since it will add unwanted complexity in my code.
So, is there a way to detect the selection?
In case of a XY problem, my final goal is to increase/decrease this scrollbar properly when user changes menu's selection with arrow buttons: ↑ ↓
Use change listener on button model of your items. Here is the solution:
import java.awt.Component;
import java.awt.FlowLayout;
import java.util.stream.Stream;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* <code>PopupSelection</code>.
*/
public class PopupSelection extends JFrame {
private static final long serialVersionUID = 363879723515243543L;
public PopupSelection() {
super("something");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel label = new JLabel("right click me");
JPopupMenu menu = new MyPopupMenu();
menu.getSelectionModel().addChangeListener(System.out::println);
JMenuItem menuItem1 = new JMenuItem("Item1");
JMenuItem menuItem2 = new JMenuItem("Item2");
JMenuItem menuItem3 = new JMenuItem("Item3");
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);
label.setComponentPopupMenu(menu);
getContentPane().add(label);
setSize(400, 400);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupSelection().setVisible(true));
}
private static class MyPopupMenu extends JPopupMenu {
private final ChangeListener listener = this::changed;
#Override
protected void addImpl(Component comp, Object constraints, int index) {
super.addImpl(comp, constraints, index);
if (comp instanceof AbstractButton) {
((AbstractButton) comp).getModel().addChangeListener(listener);
}
}
#Override
public void remove(int index) {
Component comp = getComponent(index);
if (comp instanceof AbstractButton) {
((AbstractButton) comp).getModel().removeChangeListener(listener);
}
super.remove(index);
}
private void changed(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
AbstractButton selected = Stream.of(getComponents()).filter(AbstractButton.class::isInstance)
.map(AbstractButton.class::cast)
.filter(b -> b.getModel().isArmed() && b.getModel() == model).findAny().orElse(null);
setSelected(selected);
}
}
}
Instead of adding a ChangeListener to each JMenuItem, you might be able to add a ChangeListener to the MenuSelectionManager.
MenuSelectionManager.defaultManager().addChangeListener(e -> {
Object o = e.getSource();
if (o instanceof MenuSelectionManager) {
MenuSelectionManager m = (MenuSelectionManager) o;
printMenuElementArray(m.getSelectedPath());
}
});
PopupSelection2.java
import java.awt.*;
import javax.swing.*;
public class PopupSelection2 extends JFrame {
public PopupSelection2() {
super("something");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JLabel label = new JLabel("right click me");
JPopupMenu menu = new JPopupMenu();
menu.getSelectionModel().addChangeListener(System.out::println);
JMenuItem menuItem1 = new JMenuItem("Item1");
JMenuItem menuItem2 = new JMenuItem("Item2");
JMenuItem menuItem3 = new JMenuItem("Item3");
menu.add(menuItem1);
menu.add(menuItem2);
menu.add(menuItem3);
label.setComponentPopupMenu(menu);
MenuSelectionManager.defaultManager().addChangeListener(e -> {
Object o = e.getSource();
if (o instanceof MenuSelectionManager) {
MenuSelectionManager m = (MenuSelectionManager) o;
printMenuElementArray(m.getSelectedPath());
}
});
getContentPane().add(label);
setSize(400, 400);
setLocationRelativeTo(null);
}
// #see javax/swing/MenuSelectionManager.java
private static void printMenuElementArray(MenuElement[] path) {
System.out.println("Path is(");
for (int i = 0, j = path.length; i < j ; i++) {
for (int k = 0; k <= i; k++) {
System.out.print(" ");
}
MenuElement me = path[i];
if (me instanceof JMenuItem) {
System.out.println(((JMenuItem)me).getText() + ", ");
} else if (me instanceof JMenuBar) {
System.out.println("JMenuBar, ");
} else if (me instanceof JPopupMenu) {
System.out.println("JPopupMenu, ");
} else if (me == null) {
System.out.println("NULL , ");
} else {
System.out.println("" + me + ", ");
}
}
System.out.println(")");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PopupSelection2().setVisible(true));
}
}

Java: Right Click Copy Cut Paste On TextField

I've made a program which prints a value in a text field. The problem is that when a user right clicks in the text field, a menu like this won't open:
Is there a way the user can have this menu open upon right click?
This is my code:
public class A extends JFrame{
private JTextField txt1;
private JTextField txt2;
private JLabel val;
private JLabel prt;
private JButton bt1;
public A() {
getContentPane().setLayout(null);
txt1 = new JTextField();
txt1.setBounds(178, 93, 87, 28);
getContentPane().add(txt1);
txt2 = new JTextField();
txt2.setBounds(178, 148, 87, 28);
getContentPane().add(txt2);
val = new JLabel("Enter Value");
val.setBounds(84, 93, 69, 28);
getContentPane().add(val);
prt = new JLabel("Printed Value");
prt.setBounds(80, 148, 87, 28);
getContentPane().add(prt);
bt1 = new JButton("Click This");
bt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int n=Integer.parseInt(txt1.getText());
txt2.setText(n+"");
}
});
bt1.setBounds(178, 188, 105, 28);
getContentPane().add(bt1);
setSize(400, 399);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
}
Main Method:
public class Main {
public static void main(String[] args) {
A object = new A();
}
}
Read the Swing tutorial on How to Use Menus for the basics of creating a popup menu.
Then you can use the Actions provided by the DefaultEditorKit to create your popup menu.
For the "Delete" action you will need to create your own custom Action. Read the Swing tutorial on How to Use Actions for the basics. Except you would extend TextAction since it has methods that allow you to access the text component with focus so you can create reusable code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class TextFieldPopup extends JPanel
{
public TextFieldPopup()
{
JTextField textField = new JTextField(10);
add( textField );
JPopupMenu menu = new JPopupMenu();
Action cut = new DefaultEditorKit.CutAction();
cut.putValue(Action.NAME, "Cut");
cut.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control X"));
menu.add( cut );
Action copy = new DefaultEditorKit.CopyAction();
copy.putValue(Action.NAME, "Copy");
copy.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control C"));
menu.add( copy );
Action paste = new DefaultEditorKit.PasteAction();
paste.putValue(Action.NAME, "Paste");
paste.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control V"));
menu.add( paste );
Action selectAll = new SelectAll();
menu.add( selectAll );
textField.setComponentPopupMenu( menu );
}
static class SelectAll extends TextAction
{
public SelectAll()
{
super("Select All");
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control S"));
}
public void actionPerformed(ActionEvent e)
{
JTextComponent component = getFocusedComponent();
component.selectAll();
component.requestFocusInWindow();
}
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TextFieldPopup");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TextFieldPopup() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Static class to instantly add regular popup menu to a textfield.
import javax.swing.*;
import java.awt.event.ActionEvent;
import javax.swing.undo.*;
public class JTextFieldRegularPopupMenu {
public static void addTo(JTextField txtField)
{
JPopupMenu popup = new JPopupMenu();
UndoManager undoManager = new UndoManager();
txtField.getDocument().addUndoableEditListener(undoManager);
Action undoAction = new AbstractAction("Undo") {
#Override
public void actionPerformed(ActionEvent ae) {
if (undoManager.canUndo()) {
undoManager.undo();
}
else {
System.out.println("No Undo Buffer.");
}
}
};
Action copyAction = new AbstractAction("Copy") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.copy();
}
};
Action cutAction = new AbstractAction("Cut") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.cut();
}
};
Action pasteAction = new AbstractAction("Paste") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.paste();
}
};
Action selectAllAction = new AbstractAction("Select All") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.selectAll();
}
};
cutAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control X"));
copyAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control C"));
pasteAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control V"));
selectAllAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control A"));
popup.add (undoAction);
popup.addSeparator();
popup.add (cutAction);
popup.add (copyAction);
popup.add (pasteAction);
popup.addSeparator();
popup.add (selectAllAction);
txtField.setComponentPopupMenu(popup);
}
}
Usage:
JTextFieldRegularPopupMenu.addTo(jTxtMsg);
Instantly adds popup menu to the chosen JTextFIeld.
I'd start with How to use menus and Bringing Up a Popup Menu (although I'd personally use JComponent#setComponentPopupMenu instead of a MouseListener)
Then I'd have a look at JTextField#copy, JTextField#cut and JTextField#paste

Adding a checkbox group to a java menu

Im trying to add a checkboxgroup to my menu but keep getting a "Cannot find symbol" error.
MenuBar mb = new MenuBar();
Menu file = new Menu("File");
Menu colorM = new Menu("Color");
MenuItem quitM = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q));
CheckboxGroup cbg = new CheckboxGroup();
Checkbox cb1 = new Checkbox("Black",cbg,true);
Checkbox cb2 = new Checkbox("Red",cbg,false);
Checkbox cb3 = new Checkbox("Blue",cbg,false);
Checkbox cb4 = new Checkbox("Green",cbg,false);
Then in my initialization i have
chatF.setMenuBar(mb);
mb.add(file);
mb.add(colorM);
file.add(quitM);
colorM.add(cbg);
I tried adding a MenuItem and putting the cbg in there but same problem
CheckboxGroup is not a Component (or, more specifically, a MenuItem), so you can't add it to the menu. Instead, you can create a CheckboxMenuItem, but I think CheckboxGroup only works with instances of Checkbox so you'll have to write your own code to enforce single-selection.
If Swing is an option, you can instead use JRadioButtonMenuItem and ButtonGroup:
package com.example.checkboxmenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
public class CheckboxMenu extends JFrame {
public CheckboxMenu() {
JMenuBar mb = new JMenuBar();
JMenu file = new JMenu("File"); //$NON-NLS-1$
JMenu colorM = new JMenu("Color");
JMenuItem quitM = new JMenuItem("Quit", KeyEvent.VK_Q);
JRadioButtonMenuItem cb1 = new JRadioButtonMenuItem("Black", true);
JRadioButtonMenuItem cb2 = new JRadioButtonMenuItem("Red", true);
JRadioButtonMenuItem cb3 = new JRadioButtonMenuItem("Blue", true);
JRadioButtonMenuItem cb4 = new JRadioButtonMenuItem("Green", true);
ButtonGroup group = new ButtonGroup();
group.add(cb1);
group.add(cb2);
group.add(cb3);
group.add(cb4);
setJMenuBar(mb);
mb.add(file);
mb.add(colorM);
file.add(quitM);
colorM.add(cb1);
colorM.add(cb2);
colorM.add(cb3);
colorM.add(cb4);
quitM.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400,300);
setVisible(true);
}
/**
* #param args
*/
public static void main(String[] args) {
new CheckboxMenu();
}
}
You can't add a CheckboxGroup to a Menu... you can only add MenuItem instances. You can add a CheckboxMenuItem, but this doesn't understand CheckboxGroup either.
So you need to change the CheckBoxs to CheckboxMenuItems, add them individually to the menu, roll your own CheckboxMenuItemGroup class and use it to bind the CheckboxMenuItems together.
Something like the following should work:
public class CheckboxMenuItemGroup implements ItemListener {
private Set<CheckboxMenuItem> items = new HashSet<CheckboxMenuItem>();
public void add(CheckboxMenuItem cbmi) {
cbmi.addItemListener(this);
cbmi.setState(false);
items.add(cbmi);
}
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
String itemAffected = (String) e.getItem();
for (CheckboxMenuItem item : items) {
// Use this line to allow user to toggle the selected item off
if (!item.getLabel().equals(itemAffected)) item.setState(false);
// Use this line to force one of the items to always be selected
// item.setState(item.getLabel().equals(itemAffected));
}
}
}
public void selectItem(CheckboxMenuItem itemToSelect) {
for (CheckboxMenuItem item : items) {
item.setState(item == itemToSelect);
}
}
public CheckboxMenuItem getSelectedItem() {
for (CheckboxMenuItem item : items) {
if (item.getState()) return item;
}
return null;
}
}
This should work because ItemListeners don't get called when code calls item.setState(), only when the user clicks on the item in the menu. Just make sure you only set the state of the items with the CheckboxMenuItemGroup.selectItem() call, otherwise you could end up with more than one item selected.
Then you just need to build your menu like this:
public static void main(String[] args) {
final Frame f = new Frame("Test CheckboxMenuItemGroup");
MenuBar mb = new MenuBar();
Menu menu = new Menu("Menu");
CheckboxMenuItem cb1 = new CheckboxMenuItem("Black");
CheckboxMenuItem cb2 = new CheckboxMenuItem("Red");
CheckboxMenuItem cb3 = new CheckboxMenuItem("Blue");
CheckboxMenuItem cb4 = new CheckboxMenuItem("Green");
CheckboxMenuItemGroup mig = new CheckboxMenuItemGroup();
mig.add(cb1);
mig.add(cb2);
mig.add(cb3);
mig.add(cb4);
mig.selectItem(cb1);
menu.add(cb1);
menu.add(cb2);
menu.add(cb3);
menu.add(cb4);
f.setMenuBar(mb);
f.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setSize(300, 200);
f.setVisible(true);
}
Using swing instead of awt.
JMenuBar menuBar = new JMenuBar();
JMenu color = new JMenu("Color");
JCheckBoxMenuItem cb1 = new JCheckBoxMenuItem("Black");
JCheckBoxMenuItem cb2 = new JCheckBoxMenuItem("Red");
JCheckBoxMenuItem cb3 = new JCheckBoxMenuItem("Blue");
JCheckBoxMenuItem cb4 = new JCheckBoxMenuItem("Green");
ButtonGroup group = new ButtonGroup();
group.add(cb1);
group.add(cb2);
group.add(cb3);
group.add(cb4);
menuBar.add(cb1);
menuBar.add(cb2);
menuBar.add(cb3);
menuBar.add(cb4);
setJMenuBar(menuBar); // Set the JMenuBar of the JFrame
You can add any AbstractButton to a ButtonGroup.
On OSX Java 7 (1.7.0_40) Julians answer doesnt quite work because the object returned by ItemEvent is actually a String rather than a CheckBoxItem, soiunds like a bug in OSX but got it working by modifying the itemStateChanged method
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashSet;
import java.util.Set;
public class CheckboxMenuItemGroup implements ItemListener
{
private Set<CheckboxMenuItem> items = new HashSet<CheckboxMenuItem>();
public void add(CheckboxMenuItem cbmi) {
cbmi.addItemListener(this);
cbmi.setState(false);
items.add(cbmi);
}
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
String itemAffected = (String)e.getItem();
for (CheckboxMenuItem item : items) {
if (item.getLabel() != itemAffected) item.setState(false);
}
}
}
public void selectItem(CheckboxMenuItem itemToSelect) {
for (CheckboxMenuItem item : items) {
item.setState(item == itemToSelect);
}
}
public CheckboxMenuItem getSelectedItem() {
for (CheckboxMenuItem item : items) {
if (item.getState()) return item;
}
return null;
}
}

Delete a specific button

I have a JPanel in a JFrame that contains 5 buttons. In another JPanel there is a button called "delete button", what I want to do is to click this button and than choose what button of the other 5 to delete by ckicking in one of them. Can anyone help me?
public class gui extends JFrame implements ActionListener
{
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p2 = new JPanel();
JButton b1 = new JButton("Delete");
JButton b2 = new JButton("A");
JButton b3 = new JButton("B");
JButton b4 = new JButton("C");
gui()
{
p1.setLayout(new GridLayout(1,2));
p1.add(p2);
p1.add(p3);
p2.setLayout(new GridLayout(3,1));
p2.add(b2);
p2.add(b3);
p2.add(b4);
p3.add(b1);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == b1)
// When I click this button I want to be able to delete a button of my choice (one of the other 3)
}
}
Use a chain of responsibility in the button listeners. One Button listener that listens for the "to be deleted" buttons and the "delete" button. Under normal operation this button listener just sends the "to be deleted" button events to the existing button events, but when it hears a "delete" button event, it then captures the "next" button event without sending it to the existing button listener, and acts to remove the button.
Ok you provided some code. Here is a solution that uses a chain of responsibility. Basically, if one ActionListener can't handle the event, it sends it to the next one, and so on.
import java.awt.GridLayou;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Gui extends JFrame {
public static final long serialVersionUID = 1L;
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JButton b1 = new JButton("Delete");
JButton b2 = new JButton("A");
JButton b3 = new JButton("B");
JButton b4 = new JButton("C");
public Gui() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
p1.setLayout(new GridLayout(1, 2));
p1.add(p2);
p2.add(p3);
p2.setLayout(new GridLayout(3, 1));
p2.add(b2);
p2.add(b3);
p2.add(b4);
p3.add(b1);
DoItListener doIt = new DoItListener(null);
DeleteItListener deleteIt = new DeleteItListener(this, doIt);
b1.addActionListener(deleteIt);
b2.addActionListener(deleteIt);
b3.addActionListener(deleteIt);
b4.addActionListener(deleteIt);
add(p1);
pack();
}
public void deleteButton(String name) {
if (b2 != null && "A".equals(name)) {
p2.remove(b2);
b2 = null;
p2.invalidate();
p2.redraw();
}
if (b3 != null && "B".equals(name)) {
p2.remove(b3);
b3 = null;
p2.invalidate();
p2.redraw();
}
if (b4 != null && "A".equals(name)) {
p2.remove(b4);
b4 = null;
p2.invalidate();
p2.redraw();
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Gui().setVisible(true);
}
});
}
}
class DoItListener implements ActionListener {
private ActionListener delegate;
public DoItListener(ActionListener next) {
delegate = next;
}
public void actionPerformed(ActionEvent e) {
if (!("Delete".equals(e.getActionCommand()))) {
System.out.println("doing " + e.getActionCommand());
} else if (delegate != null) {
delegate.actionPerformed(e);
}
}
}
class DeleteItListener implements ActionListener {
private Gui gui;
private boolean deleteNext;
private ActionListener delegate;
public DeleteItListener(Gui container, ActionListener next) {
gui = container;
delegate = next;
deleteNext = false;
}
public void actionPerformed(ActionEvent e) {
if ("Delete".equals(e.getActionCommand())) {
deleteNext = true;
} else if (deleteNext) {
gui.deleteButton(e.getActionCommand());
deleteNext = false;
} else if (delegate != null) {
delegate.actionPerformed(e);
}
}
}
Here try this code out :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DeleteButtonExample extends JFrame
{
private boolean deleteNow = false;
private JButton deleteButton;
private JPanel leftPanel;
private JPanel rightPanel;
private JButton[] buttons = new JButton[5];
private ActionListener deleteAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JButton button = (JButton) ae.getSource();
if (deleteNow)
{
leftPanel.remove(button);
leftPanel.revalidate();
leftPanel.repaint();
deleteNow = false;
}
else
{
// Do your normal Event Handling here.
System.out.println("My COMMAND IS : " + button.getActionCommand());
}
}
};
private void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
setLayout(new GridLayout(0, 2));
leftPanel = new JPanel();
leftPanel.setLayout(new GridLayout(0, 2));
leftPanel.setBackground(Color.WHITE);
for (int i = 0; i < 5; i++)
{
buttons[i] = new JButton("" + i);
buttons[i].addActionListener(deleteAction);
buttons[i].setActionCommand("" + i);
leftPanel.add(buttons[i]);
}
rightPanel = new JPanel();
rightPanel.setBackground(Color.BLUE);
JButton deleteButton = new JButton("DELETE");
deleteButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JOptionPane.showMessageDialog(null, "Delete any Button from the Left Panel by clicking it."
, "INFO : ", JOptionPane.INFORMATION_MESSAGE);
deleteNow = true;
}
});
rightPanel.add(deleteButton);
add(leftPanel);
add(rightPanel);
pack();
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new DeleteButtonExample().createAndDisplayGUI();
}
});
}
}
OUTPUT :
, ,
Here's a snippet of code to kick you off in the right direction:
import java.awt.event.ActionEvent;
import javax.swing.*;
public class FrameTestBase extends JFrame {
public static void main(String args[]) {
FrameTestBase t = new FrameTestBase();
final JPanel p = new JPanel();
final JButton button = new JButton();
button.setAction(new AbstractAction("Remove me!") {
#Override
public void actionPerformed(ActionEvent e) {
p.remove(button);
p.revalidate();
p.repaint();
}
});
p.add(button);
t.setContentPane(p);
t.setDefaultCloseOperation(EXIT_ON_CLOSE);
t.setSize(400, 400);
t.setVisible(true);
}
}
Before click:
After click:
From the comments:
To generalize this, you could create an AbstractAction that takes the to-be-deleted button as argument. Use this AbstractAction, and update it as necessary whenever your delete-policy should change.
Have a look at the glass pane. This tutorial shows how it is used.
At a high level, clicking the 'Delete' button would put the glass pane listener into a state where it:
detects a click,
determines the target component,
determines whether the component is allowed to be deleted
and if so, delete the component.
As a design note, I would keep a Set of controls that are allowed to be deleted, and thereby separate the concerns. So when you add a button that is allowed to be deleted, it is your responsibility to also add it to the delete candidates set.
The easiest method:
Add an ActionListener to the button that will remove another one;
Repaint and revalidate the panel where is the button to remove.
Example (in this case the button that will delete another one is called by "deleteBtn" and the button in the another panel that will be removed is called by "btnToDlt" that exists in the "panel"):
deleteBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.remove(btnToDlt);
panel.revalidate();
panel.repaint();
}
});

Create menu on button click in Java

For a project we want to create a button which will make a tiny menu when it is clicked (the way it works is similar to back button's drop-down menu in Firefox although the way to activate is a simple left click). Only real constraint is that it has to be in Java (preferably swing if possible). So, any ideas, examples, codes on how to do it?
Use a JPopupMenu. E.G.
PopUpMenuDemo.java
import java.awt.event.*;
import javax.swing.*;
class PopUpMenuDemo {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
final JButton b = new JButton("Pop Up");
final JPopupMenu menu = new JPopupMenu("Menu");
menu.add("A");
menu.add("B");
menu.add("C");
b.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent ae) {
menu.show(b, b.getWidth()/2, b.getHeight()/2);
}
} );
JOptionPane.showMessageDialog(null,b);
}
};
SwingUtilities.invokeLater(r);
}
}
Screenshot
I would probably do it like this:
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnClickMe = new JButton("Click me");
btnClickMe.setBounds(10, 30, 89, 23);
frame.getContentPane().add(btnClickMe);
final JPopupMenu menu = new JPopupMenu();
JMenuItem item1 = new JMenuItem("Item1");
JMenuItem item2 = new JMenuItem("Item2");
JMenuItem item3 = new JMenuItem("Item3");
menu.add(item1);
menu.add(item2);
menu.add(item3);
btnClickMe.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e){
if ( e.getButton() == 1 ){ // 1-left, 2-middle, 3-right button
menu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
This is the code for menuButton, it looks like a button, and when you click on it a menu appears. You can customize it by adding the image icon to the menu and by methods:
setFocusable(false);
setBorderPainted(false);
setOpaque(false);
If you want to get it like FireFox then set the icon for the menu and call the above methods, and then set the rollover icon, selected icon & rollover selected icon.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class menuButton extends JFrame
{
JMenuBar fileMenuBar,editMenuBar;
JMenu fileMenu,editMenu;
JMenuItem newFile,open,save,saveas,exit;
JMenuItem cut,copy,paste,undo,redo;
public menuButton()
{
setTitle("menu Button");
setSize(500,500);
setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
fileMenuBar=new JMenuBar();
editMenuBar=new JMenuBar();
fileMenu=new JMenu("File");
editMenu=new JMenu("Edit");
newFile=new JMenuItem("New");
newFile.setAccelerator(KeyStroke.getKeyStroke('N',InputEvent.CTRL_MASK));
open=new JMenuItem("Open");
open.setAccelerator(KeyStroke.getKeyStroke('O',InputEvent.CTRL_MASK));
save=new JMenuItem("Save");
save.setAccelerator(KeyStroke.getKeyStroke('S',InputEvent.CTRL_MASK));
saveas=new JMenuItem("Save As");
saveas.setAccelerator(KeyStroke.getKeyStroke('A',InputEvent.CTRL_MASK));
exit=new JMenuItem("Exit");
exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,InputEvent.ALT_MASK));
cut=new JMenuItem("Cut");
cut.setAccelerator(KeyStroke.getKeyStroke('X',InputEvent.CTRL_MASK));
copy=new JMenuItem("Copy");
copy.setAccelerator(KeyStroke.getKeyStroke('C',InputEvent.CTRL_MASK));
paste=new JMenuItem("Paste");
paste.setAccelerator(KeyStroke.getKeyStroke('V',InputEvent.CTRL_MASK));
undo=new JMenuItem("Undo");
undo.setAccelerator(KeyStroke.getKeyStroke('Z',InputEvent.CTRL_MASK));
redo=new JMenuItem("Redo");
redo.setAccelerator(KeyStroke.getKeyStroke('R',InputEvent.CTRL_MASK));
editMenu.add(cut);
editMenu.add(copy);
editMenu.add(paste);
editMenu.addSeparator();
editMenu.add(undo);
editMenu.add(redo);
fileMenu.add(newFile);
fileMenu.add(open);
fileMenu.add(save);
fileMenu.add(saveas);
fileMenu.add(exit);
fileMenuBar.add(fileMenu);
editMenuBar.add(editMenu);
add(fileMenuBar);
add(editMenuBar);
}
public static void main(String args[])
{
new menuButton();
}
}
see this it may be help you
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class GUI implements ActionListener, MouseListener, MouseMotionListener, KeyListener {
private final BufferedImage offscreenImage; // double buffered image
private final BufferedImage onscreenImage; // double buffered image
private final Graphics2D offscreen;
private final Graphics2D onscreen;
private JFrame frame; // the top-level component
private JPanel center = new JPanel(); // center panel
// create a GUI with a menu, some buttons, and a drawing window of size width-by-height
public GUI(int width, int height) {
offscreenImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
onscreenImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
offscreen = (Graphics2D) offscreenImage.getGraphics();
onscreen = (Graphics2D) onscreenImage.getGraphics();
// the drawing panel
ImageIcon icon = new ImageIcon(onscreenImage);
JLabel draw = new JLabel(icon);
draw.addMouseListener(this);
draw.addMouseMotionListener(this);
// label cannot get keyboard focus
center.add(draw);
center.addKeyListener(this);
// west panel of buttons
JPanel west = new JPanel();
west.setLayout(new BoxLayout(west, BoxLayout.PAGE_AXIS));
JButton button1 = new JButton("button 1");
JButton button2 = new JButton("button 2");
JButton button3 = new JButton("button 3");
JButton button4 = new JButton("button 4");
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
button4.addActionListener(this);
button1.setToolTipText("Click me");
west.add(button1);
west.add(button2);
west.add(button3);
west.add(button4);
// menu
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem menuSave = new JMenuItem(" Save... ");
menuSave.addActionListener(this);
menuSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
menu.add(menuSave);
// setup the frame and add components
frame = new JFrame();
frame.setJMenuBar(menuBar);
frame.add(west, BorderLayout.WEST);
frame.add(center, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
// give the focus to the center panel
center.requestFocusInWindow();
frame.setVisible(true);
}
// draw picture (gif, jpg, or png) centered on (x, y)
public void picture(int x, int y, String filename) {
ImageIcon icon = new ImageIcon(filename);
Image image = icon.getImage();
offscreen.drawImage(image, x, y, null);
show();
}
// display the drawing canvas on the screen
public void show() {
onscreen.drawImage(offscreenImage, 0, 0, null);
frame.repaint();
}
/*************************************************************************
* Event callbacks
*************************************************************************/
// for buttons and menus
public void actionPerformed(ActionEvent e) {
Object cmd = e.getActionCommand();
if (cmd.equals(" Save... ")) System.out.println("File -> Save");
else if (cmd.equals("button 1")) System.out.println("Button 1 pressed");
else if (cmd.equals("button 2")) System.out.println("Button 2 pressed");
else if (cmd.equals("button 3")) System.out.println("Button 3 pressed");
else if (cmd.equals("button 4")) System.out.println("Button 4 pressed");
else System.out.println("Unknown action");
// don't hog the keyboard focus
center.requestFocusInWindow();
}
// for the mouse
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
System.out.println("Mouse pressed at " + x + ", " + y);
offscreen.setColor(Color.BLUE);
offscreen.fillOval(x-3, y-3, 6, 6);
show();
}
public void mouseClicked (MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
public void mouseDragged (MouseEvent e) { }
public void mouseMoved (MouseEvent e) { }
// for the keyboard
public void keyPressed (KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) {
System.out.println("Key = '" + e.getKeyChar() + "'");
}
// test client
public static void main(String[] args) {
GUI gui = new GUI(800, 471);
gui.picture(0, 0, "map.png");
gui.show();
}
}
If you like lesser code lines in your code try below code:
Inside your buttons actionPerformed:
private void yourButtonActionPerformed(java.awt.event.ActionEvent evt) {
final JPopupMenu yourMenu = new JPopupMenu("Settings");
menu.add("Name");
menu.add("Id");
menu.add(new Button()); // can even add buttons and other components as well.
menu.show(yourButton, yourButton.getWidth()/2, yourButton.getHeight()/2);
}

Categories