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;
}
}
Related
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));
}
}
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.
How can I retrieve the currently selected menu or menu item when clicked on it and the subsequent path will be printed on console. In this code I have done the menus and sub menus up to 4 levels. And want to print the path of selected menus and submenus when clicked on. I am using swing concept for this program. Please help. Thanks in advance.
import java.awt.Component;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Menu {
public static void main(final String args[]) {
JFrame frame = new JFrame("MenuSample Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu worldMenu = new JMenu("world");
menuBar.add(worldMenu);
JMenu indMenu = new JMenu("India");
worldMenu.add(indMenu);
/* creates menu */
JMenu odMenu = new JMenu("Odisha");
indMenu.add(odMenu);
JMenu delhiMenu = new JMenu("Delhi");
indMenu.add(delhiMenu);
JMenu upMenu = new JMenu("Uttar Pradesh");
indMenu.add(upMenu);
JMenu mpMenu = new JMenu("Madhya Pradesh");
indMenu.add(mpMenu);
JMenu ausMenu = new JMenu("Australia");
worldMenu.add(ausMenu);
JMenu AmericaMenu = new JMenu("America");
worldMenu.add(AmericaMenu);
/* creates submenu */
JMenu bbMenu = new JMenu("Bhubaneswar");
odMenu.add(bbMenu);
JMenu bmMenu = new JMenu("Berhampur");
odMenu.add(bmMenu);
/*creates sub sub menu */
JMenuItem rjMenuItem = new JMenuItem("Raj Mahal");
bbMenu.add(rjMenuItem);
JMenuItem abMenuItem = new JMenuItem("Acharya Bihar");
bbMenu.add(abMenuItem);
JMenuItem bnMenuItem = new JMenuItem("Bani Bihar");
bbMenu.add(bnMenuItem);
/* retrieving path */
MenuSelectionManager.defaultManager().addChangeListener(
new ChangeListener() {
public void stateChanged(ChangeEvent evt) {
MenuElement[] path = MenuSelectionManager.defaultManager()
.getSelectedPath();
//
int s=0;
for (int i = 0; i < path.length; i++) {
Component c = path[i].getComponent();
if (c instanceof JMenuItem) {
JMenuItem mi = (JMenuItem) c;
String label = mi.getText();
System.out.println("LEVEL----" + s);
System.out.println("you hv selected:"+label);
s++;
}
}
}
});
//
frame.setJMenuBar(menuBar);
frame.setSize(350, 250);
frame.setVisible(true);
}
}
How to get the currently selected
Menu - A parent JMenu cannot be selected. Why would you want to know
if the mouse is over it?
MenuItem - Embrace the Action interface
It is an all too common oversight to not use the Action interface. When developing with Swing make Action your friend, it will treat you well. You went down the wrong path with MenuSelectionManager.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class MenuExample {
private JFrame frame;
private JLabel choiceIndicator;
MenuExample create() {
frame = createFrame();
choiceIndicator = new JLabel();
frame.setJMenuBar(createMenuBar());
frame.getContentPane().add(createContent());
return this;
}
private Component createContent() {
JPanel panel = new JPanel();
panel.add(new JLabel("Last menu item choice:"));
panel.add(choiceIndicator);
return panel;
}
private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
menuBar.add(createWorld());
return menuBar;
}
private JMenu createWorld() {
JMenu worldMenu = new JMenu("World");
worldMenu.add(createIndia());
worldMenu.add(new JMenu("Australia"));
worldMenu.add(new JMenu("America"));
return worldMenu;
}
private JMenu createIndia() {
JMenu india = new JMenu("India");
india.add(createOdisha());
india.add(new JMenu("Delhi"));
india.add(new JMenu("Uttar Pradesh"));
india.add(new JMenu("Madhya Pradesh"));
return india;
}
private JMenuItem createOdisha() {
JMenu menu = new JMenu("Odisha");
menu.add(createBhubaneswar());
menu.add(new JMenu("Berhampur"));
return menu;
}
private JMenuItem createBhubaneswar() {
JMenu menu = new JMenu("Bhubaneswar");
menu.add(choiceItem("Raj Mahal"));
menu.add(choiceItem("Acharya Bihar"));
menu.add(choiceItem("Bani Bihar"));
return menu;
}
private JMenuItem choiceItem(String text) {
return new JMenuItem(new Choice(text, choiceIndicator));
}
private JFrame createFrame() {
JFrame frame = new JFrame(getClass().getSimpleName());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
void show() {
frame.setSize(350, 250);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MenuExample().create().show();
}
});
}
class Choice extends AbstractAction {
private final JLabel choiceIndicator;
public Choice(String text, JLabel choiceIndicator) {
this(text, null, null, null, choiceIndicator);
}
public Choice(String text, ImageIcon icon, String desc, Integer mnemonic, JLabel choiceIndicator) {
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
this.choiceIndicator = choiceIndicator;
}
public void actionPerformed(ActionEvent e) {
choiceIndicator.setText(e.getActionCommand());
}
}
}
Sorry if I'm double positing but I totally suck at Java.
I am trying to make my form have the ability to change dynamically if you select a radio button. The functions save, delete, new will remain the same but the contents of the body e.g. the UPC will change to ISBN of the novel and the other fields.
Is there a way to when you press Novel to load the items from Novel to replace Comic book items?
I tried to separate but I've hit a block and with my limited skills unsure what to do.
I just want it to be able to change it so that it works.
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.MenuBar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
public class FormFictionCatelogue extends JFrame implements ActionListener {
// Constants
// =========
private final String FORM_TITLE = "Fiction Adiction Catelogue";
private final int X_LOC = 400;
private final int Y_LOC = 80;
private final int WIDTH = 600;
private final int HEIGHT = 450;
private String gradeCode;
//final static String filename = "data/comicBookData.txt";
private JButton firstPageButton;
private JButton backPageButton;
private JButton forwardPageButton;
private JButton lastPageButton;
private JRadioButton comicBookRadioButton;
private JRadioButton novelRadioButton;
private final String FIRSTPAGE_BUTTON_TEXT = "|<";
private final String BACKPAGE_BUTTON_TEXT = "<";
private final String FORWARDPAGE_BUTTON_TEXT = ">";
private final String LASTPAGE_BUTTON_TEXT = ">|";
private final String COMICBOOK_BUTTON_TEXT = "Comic";
private final String NOVEL_BUTTON_TEXT = "Novel";
private final String SAVE_BUTTON_TEXT = "Save";
private final String EXIT_BUTTON_TEXT = "Exit";
private final String CLEAR_BUTTON_TEXT = "Clear";
private final String FIND_BUTTON_TEXT = "Find";
private final String DELETE_BUTTON_TEXT = "Delete";
private final String ADDPAGE_BUTTON_TEXT = "New";
// Attributes
private JTextField upcTextField;
private JTextField isbnTextField;
private JTextField titleTextField;
private JTextField issueNumTextField;
private JTextField bookNumTextField;
private JTextField writerTextField;
private JTextField authorTextField;
private JTextField artistTextField;
private JTextField publisherTextField;
private JTextField seriesTextField;
private JTextField otherBooksTextField;
private JTextField gradeCodeTextField;
private JTextField charactersTextField;
private JButton saveButton;
private JButton deleteButton;
private JButton findButton;
private JButton clearButton;
private JButton exitButton;
private JButton addPageButton;
FictionCatelogue fc;
/**
* #param args
* #throws Exception
*/
public static void main(String[] args) {
try {
FormFictionCatelogue form = new FormFictionCatelogue();
form.fc = new FictionCatelogue();
form.setVisible(true);
//comicBook selected by default
form.populatefields(form.fc.returnComic(0));
//if novel is selected change fields to novel and populate
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
/**
*
*/
public FormFictionCatelogue() {
// Set form properties
// ===================
setTitle(FORM_TITLE);
setSize(WIDTH, HEIGHT);
setLocation(X_LOC, Y_LOC);
// Create and set components
// -------------------------
// Create panels to hold components
JPanel menuBarPanel = new JPanel();
JPanel fieldsPanel = new JPanel();
JPanel buttonsPanel = new JPanel();
JPanel navigationPanel = new JPanel();
//JPanel radioButtonsPanel = new JPanel();
ButtonGroup bG = new ButtonGroup();
// Set the layout of the panels
GridLayout fieldsPanelLayout = new GridLayout(9, 6);
// Menu
JMenuBar menubar = new JMenuBar();
ImageIcon icon = new ImageIcon("exit.png");
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenu about = new JMenu("About");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem eMenuItem = new JMenuItem("Exit", icon);
eMenuItem.setMnemonic(KeyEvent.VK_E);
eMenuItem.setToolTipText("Exit application");
eMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
JMenuItem eMenuItem1 = new JMenuItem("Reports", icon);
eMenuItem.setMnemonic(KeyEvent.VK_E);
eMenuItem.setToolTipText("Reports are located here");
eMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
//calls reports
//System.exit(0);
}
});
file.add(eMenuItem);
about.add(eMenuItem1);
menubar.add(file);
menubar.add(about);
setJMenuBar(menubar);
setTitle("Menu");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//if comic is selected
ComicBookFields(fieldsPanel);
//else
//NovelFields(fieldsPanel);
// Buttons
comicBookRadioButton = new JRadioButton(COMICBOOK_BUTTON_TEXT);
novelRadioButton = new JRadioButton(NOVEL_BUTTON_TEXT);
bG.add(comicBookRadioButton);
bG.add(novelRadioButton);
this.setLayout(new FlowLayout());
this.add(comicBookRadioButton);
this.add(novelRadioButton);
comicBookRadioButton.setSelected(true);
bG.add(comicBookRadioButton);
bG.add(novelRadioButton);
addPageButton = new JButton(ADDPAGE_BUTTON_TEXT);
buttonsPanel.add(addPageButton);
saveButton = new JButton(SAVE_BUTTON_TEXT);
buttonsPanel.add(saveButton);
clearButton = new JButton(CLEAR_BUTTON_TEXT);
buttonsPanel.add(clearButton);
deleteButton = new JButton(DELETE_BUTTON_TEXT);
buttonsPanel.add(deleteButton);
findButton = new JButton(FIND_BUTTON_TEXT);
buttonsPanel.add(findButton);
exitButton = new JButton(EXIT_BUTTON_TEXT);
buttonsPanel.add(exitButton);
firstPageButton = new JButton(FIRSTPAGE_BUTTON_TEXT);
navigationPanel.add(firstPageButton);
backPageButton = new JButton(BACKPAGE_BUTTON_TEXT);
navigationPanel.add(backPageButton);
forwardPageButton = new JButton(FORWARDPAGE_BUTTON_TEXT);
navigationPanel.add(forwardPageButton);
lastPageButton = new JButton(LASTPAGE_BUTTON_TEXT);
navigationPanel.add(lastPageButton);
// Get the container holding the components of this class
Container con = getContentPane();
// Set layout of this class
con.setLayout(new BorderLayout());
con.setLayout( new FlowLayout());
// Add the fieldsPanel and buttonsPanel to this class.
// con.add(menuBarPanel, BorderLayout);
con.add(fieldsPanel, BorderLayout.CENTER);
con.add(buttonsPanel, BorderLayout.LINE_END);
con.add(navigationPanel, BorderLayout.SOUTH);
//con.add(radioButtonsPanel, BorderLayout.PAGE_START);
// Register listeners
// ==================
// Register action listeners on buttons
saveButton.addActionListener(this);
clearButton.addActionListener(this);
deleteButton.addActionListener(this);
findButton.addActionListener(this);
exitButton.addActionListener(this);
firstPageButton.addActionListener(this);
backPageButton.addActionListener(this);
forwardPageButton.addActionListener(this);
lastPageButton.addActionListener(this);
addPageButton.addActionListener(this);
comicBookRadioButton.addActionListener(this);
novelRadioButton.addActionListener(this);
// Exit program when window is closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void Radiobutton (){
this.add(comicBookRadioButton);
this.add(novelRadioButton);
comicBookRadioButton.setSelected(true);
this.setVisible(true);
}
// Populate the fields at the start of the application
public void populatefields(ComicBook cb) {
String gradecode;
// radio button selection = comic do this
if (cb != null) {
upcTextField.setText(cb.getUpc());
titleTextField.setText(cb.getTitle());
issueNumTextField.setText(Integer.toString(cb.getIssuenumber()));
writerTextField.setText(cb.getWriter());
artistTextField.setText(cb.getArtist());
publisherTextField.setText(cb.getPublisher());
gradecode = cb.getGradeCode();
gradeCodeTextField.setText(cb.determineCondition(gradecode));
charactersTextField.setText(cb.getCharacters());
}
//radio button selection = novel do this
// Exit program when window is closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
/**
*
*/
public void actionPerformed(ActionEvent ae) {
try {
if(ae.getActionCommand().equals(COMICBOOK_BUTTON_TEXT)){
//FormFictionCatelogue form = new FormFictionCatelogue();
//form.populatefields(form.fc.returnObject(0));
//ComicBookFields(fieldsPanel);
populatefields(fc.returnComic(0));
} else if (ae.getActionCommand().equals(NOVEL_BUTTON_TEXT)) {
} else if (ae.getActionCommand().equals(SAVE_BUTTON_TEXT)) {
save();
} else if (ae.getActionCommand().equals(CLEAR_BUTTON_TEXT)) {
clear();
} else if (ae.getActionCommand().equals(ADDPAGE_BUTTON_TEXT)) {
add();
} else if (ae.getActionCommand().equals(DELETE_BUTTON_TEXT)) {
delete();
} else if (ae.getActionCommand().equals(FIND_BUTTON_TEXT)) {
find();
} else if (ae.getActionCommand().equals(EXIT_BUTTON_TEXT)) {
exit();
} else if (ae.getActionCommand().equals(FIRSTPAGE_BUTTON_TEXT)) {
// first record
populatefields(fc.firstRecord());
} else if (ae.getActionCommand().equals(FORWARDPAGE_BUTTON_TEXT)) {
// next record
populatefields(fc.nextRecord());
} else if (ae.getActionCommand().equals(BACKPAGE_BUTTON_TEXT)) {
// previous record
populatefields(fc.previousRecord());
} else if (ae.getActionCommand().equals(LASTPAGE_BUTTON_TEXT)) {
// last record
populatefields(fc.lastRecord());
} else {
throw new Exception("Unknown event!");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage(), "Error!",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
void clear() {
upcTextField.setText("");
titleTextField.setText("");
issueNumTextField.setText("");
writerTextField.setText("");
artistTextField.setText("");
gradeCodeTextField.setText("");
publisherTextField.setText("");
charactersTextField.setText("");
}
private void exit() {
System.exit(0);
}
void add() {
try{
clear();
ComicBook cb = new ComicBook();
fc.add(cb);
fc.lastRecord();
} catch (Exception e){
e.printStackTrace();
}
}
void save() throws Exception {
// if radio button = comic do this
ComicBook cb = new ComicBook();
String condition;
if (upcTextField.getText().length() == 16) {
//searches if there is another record if()
cb.setUpc(upcTextField.getText());
} else {
throw new Exception("Upc is not at required length ");
}
cb.setTitle(titleTextField.getText());
cb.setIssuenumber(Integer.parseInt(issueNumTextField.getText()));
cb.setWriter(writerTextField.getText());
cb.setArtist(artistTextField.getText());
cb.setPublisher(publisherTextField.getText());
condition = cb.determineString(gradeCodeTextField.getText());
if (condition.equals("Wrong Input")) {
throw new Exception("Grade code is not valid");
} else {
cb.setGradeCode(condition);
}
cb.setCharacters(charactersTextField.getText());
fc.save(cb);
// if radio button = novels do this
}
private void delete() throws Exception {
fc.delete();
populatefields(fc.getCurrentRecord());
}
private void find() {
// from
// http://www.roseindia.net/java/example/java/swing/ShowInputDialog.shtml
String str = JOptionPane.showInputDialog(null, "Enter some text : ",
"Comic Book Search", 1);
if (str != null) {
ComicBook cb = new ComicBook();
cb = fc.search(str);
if (cb != null) {
populatefields(cb);
} else {
JOptionPane.showMessageDialog(null, "No comic books found ",
"Comic Book Search", 1);
}
}
}
public JPanel ComicBookFields(JPanel fieldsPanel) {
// Create components and add to panels for ComicBook
GridLayout fieldsPanelLayout = new GridLayout(9, 6);
fieldsPanel.setLayout(fieldsPanelLayout);
fieldsPanel.add(new JLabel("UPC: "));
upcTextField = new JTextField(20);
fieldsPanel.add(upcTextField);
fieldsPanel.add(new JLabel("Title: "));
titleTextField = new JTextField(20);
fieldsPanel.add(titleTextField);
fieldsPanel.add(new JLabel("Issue Number: "));
issueNumTextField = new JTextField(20);
fieldsPanel.add(issueNumTextField);
fieldsPanel.add(new JLabel("Writer: "));
writerTextField = new JTextField(20);
fieldsPanel.add(writerTextField);
fieldsPanel.add(new JLabel("Artist: "));
artistTextField = new JTextField(20);
fieldsPanel.add(artistTextField);
fieldsPanel.add(new JLabel("Publisher: "));
publisherTextField = new JTextField(20);
fieldsPanel.add(publisherTextField);
fieldsPanel.add(new JLabel("Grade Code: "));
gradeCodeTextField = new JTextField(20);
fieldsPanel.add(gradeCodeTextField);
fieldsPanel.add(new JLabel("Characters"));
charactersTextField = new JTextField(20);
fieldsPanel.add(charactersTextField);
return fieldsPanel;
}
public JPanel NovelFields(JPanel fieldsPanel) {
// Create components and add to panels for ComicBook
GridLayout fieldsPanelLayout = new GridLayout(9, 6);
fieldsPanel.setLayout(fieldsPanelLayout);
fieldsPanel.add(new JLabel("ISBN: "));
isbnTextField = new JTextField(20);
fieldsPanel.add(isbnTextField);
fieldsPanel.add(new JLabel("Title: "));
titleTextField = new JTextField(20);
fieldsPanel.add(titleTextField);
fieldsPanel.add(new JLabel("Book Number: "));
bookNumTextField = new JTextField(20);
fieldsPanel.add(bookNumTextField);
fieldsPanel.add(new JLabel("Author: "));
authorTextField = new JTextField(20);
fieldsPanel.add(authorTextField);
fieldsPanel.add(new JLabel("Publisher: "));
publisherTextField = new JTextField(20);
fieldsPanel.add(publisherTextField);
fieldsPanel.add(new JLabel("Series: "));
seriesTextField = new JTextField(20);
fieldsPanel.add(seriesTextField);
fieldsPanel.add(new JLabel("Other Books"));
otherBooksTextField = new JTextField(20);
fieldsPanel.add(otherBooksTextField);
return fieldsPanel;
}
}
To swap forms you can use a CardLayout.
Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.
The example from the tutorial switches when you make a selection from a combo box. In your case you would change the panel when you click on the radio button. So you might also want to read the section from the tutorial on How to Use Buttons.
Otherwise you can switch JPanels on JRadioButton selection like this:
You've got a JPanel called displayPanel which contains the ComicPanel by default, if you select the Novel RadioButton the displayPanel gets cleared and the NovelPanel will be added.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class AddNovelOrComicPanel extends JPanel implements ActionListener {
private JPanel selectPanel;
private JPanel displayPanel;
private JPanel buttonPanel;
private JRadioButton comic;
private JRadioButton novel;
// we need this ButtonGroup to take care about unselecting the former selected JRadioButton
ButtonGroup radioButtons;
public AddNovelOrComicPanel() {
this.setLayout(new BorderLayout());
initComponents();
this.add(selectPanel, BorderLayout.NORTH);
this.add(displayPanel, BorderLayout.CENTER);
}
/**
* Initializes all Components
*/
private void initComponents() {
selectPanel = new JPanel(new GridLayout(1, 2));
comic = new JRadioButton("Comic");
comic.setSelected(true);
comic.addActionListener(this);
novel = new JRadioButton("Novel");
novel.addActionListener(this);
radioButtons = new ButtonGroup();
radioButtons.add(comic);
radioButtons.add(novel);
selectPanel.add(comic);
selectPanel.add(novel);
displayPanel = new JPanel();
displayPanel.add(new ComicPanel());
}
#Override
public void actionPerformed(ActionEvent e) {
// if comic is selected show the ComicPanel in the displayPanel
if(e.getSource().equals(comic)) {
displayPanel.removeAll();
displayPanel.add(new ComicPanel());
}
// if novel is selected show the NovelPanel in the displayPanel
if(e.getSource().equals(novel)) {
displayPanel.removeAll();
displayPanel.add(new NovelPanel());
}
// revalidate all to show the changes
revalidate();
}
}
/**
* The NovelPanel class
* it contains all the Items you need to register a new Novel
*/
class NovelPanel extends JPanel {
public NovelPanel() {
this.add(new JLabel("Add your Novel components here"));
}
}
/**
* The ComicPanel class
*/
class ComicPanel extends JPanel {
public ComicPanel() {
this.add(new JLabel("Add your Comic components here"));
}
}
So it is your choice what you want to do. Possible is nearly everything ;)
Patrick
I am wondering why the JTabbedPane only adds 1 tab. When I use the method addTab and then reuse it to create a new tab, it overrides the first tab created. Here is the code: BTW, most of the code that might be related to the problem is at actionlistener.
package com.james.client;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.Element;
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
public static void main(String [] args)
{
//JTextArea
final JTextArea code = new JTextArea();
final JTextArea lines = new JTextArea("1");
final JScrollPane scroll = new JScrollPane(code);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
lines.setBackground(Color.LIGHT_GRAY);
lines.setEditable(false);
code.getDocument().addDocumentListener(new DocumentListener(){
public String getText(){
int caretPosition = code.getDocument().getLength();
Element root = code.getDocument().getDefaultRootElement();
String text = "1" + System.getProperty("line.separator");
for(int i = 2; i < root.getElementIndex( caretPosition ) + 2; i++){
text += i + System.getProperty("line.separator");
}
return text;
}
#Override
public void changedUpdate(DocumentEvent de) {
lines.setText(getText());
}
#Override
public void insertUpdate(DocumentEvent de) {
lines.setText(getText());
}
#Override
public void removeUpdate(DocumentEvent de) {
lines.setText(getText());
}
});
scroll.getViewport().add(code);
scroll.setRowHeaderView(lines);
//JFrame
JFrame window = new JFrame("MinecraftProgrammer++");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(1000, 700);
window.setResizable(false);
window.setLocationRelativeTo(null);
//JMenuBar
JMenuBar menu = new JMenuBar();
JMenu file = new JMenu("File");
JMenu newfile = new JMenu("New");
//JTabbedPane
final JTabbedPane tabs = new JTabbedPane();
tabs.setBackground(Color.gray);
//JMenu items
JMenuItem classfile = new JMenuItem("Class");
JMenuItem packagefolder = new JMenuItem("Package");
JMenuItem other = new JMenuItem("Other");
JMenuItem open = new JMenuItem("Open");
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
try {
JFileChooser chooseFile = new JFileChooser();
chooseFile.setAcceptAllFileFilterUsed(false);
FileFilter filter1 = new ExtensionFileFilter("Java Class", new String[] {"JAVA"});
FileFilter filter2 = new ExtensionFileFilter("Text File", new String[] {"TXT"});
chooseFile.setFileFilter(filter2);
chooseFile.setFileFilter(filter1);
chooseFile.showOpenDialog(chooseFile);
String filePath = chooseFile.getSelectedFile().getAbsolutePath();
FileReader readFile = new FileReader(filePath);
String fileName = chooseFile.getSelectedFile().getName();
tabs.addTab(fileName, scroll);
#SuppressWarnings("resource")
Scanner fileReaderScan = new Scanner(readFile);
String storeAllString = "";
while(fileReaderScan.hasNextLine())
{
String temp = fileReaderScan.nextLine() + "\n";
storeAllString = storeAllString + temp;
}
code.setText(storeAllString);
code.setLineWrap(true);
code.setWrapStyleWord(true);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println(e);
}
}
});
JMenuItem save = new JMenuItem("Save");
JMenuItem saveas = new JMenuItem("Save As...");
//Compile menu bar
file.add(newfile);
file.add(open);
file.add(save);
file.add(saveas);
newfile.add(classfile);
newfile.add(packagefolder);
newfile.add(other);
menu.add(file);
window.add(tabs);
window.setJMenuBar(menu);
window.setVisible(true);
}
}
You're adding the JScrollPane "scroll" to the JTabbedPane. How many times do you construct this component? Answer -- once only. So you're only adding and re-adding the same component every time.
final JScrollPane scroll = new JScrollPane(code); // here you create scroll
// .....
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
try {
JFileChooser chooseFile = new JFileChooser();
// ....
// you add the same component here
tabs.addTab(fileName, scroll);
// ....
}
Since you can't add a component to a container more than once and see it in both containers, the solution is to create any components needed for the new tab inside of the ActionListener's actionPerformed(...) method each time you need to add something to the JTabbedPane.