I am creating a word processor for my own use.I want to add a JTextArea to the frame after i click "NEW" in the menu bar. I am using GUI programing in netbeans.
It'll be hard to answer your question without your source code but here is a working solution (Assuming that by menu bar button you mean a JMenuBar with a JMenuItem):
import java.awt.event.*;
import javax.swing.*;
class WordProcessor extends JFrame implements ActionListener{
JMenuBar menuBar;
JMenu file;
JMenuItem newFile;
JTextArea textArea; //The text area object
public WordProcessor(){
super("WordProcessor");
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
menuBar = new JMenuBar();
file = new JMenu("File");
newFile = new JMenuItem("new");
file.add(newFile);
menuBar.add(file);
setJMenuBar(menuBar);
textArea = new JTextArea(5, 37); //Instantiate text area object
newFile.addActionListener(this); //listen for events on the 'new' item of the 'file' menu
}
public void actionPerformed(ActionEvent event){
if(event.getSource() == newFile){
add(textArea); //Add the text area to the JFrame if the 'new' item is clicked
}
}
public static void main(String[] args){
WordProcessor window = new WordProcessor();
}
}
This answers your request however I wouldn't add a JTextArea object to the window every time you click the new file menu item, instead I would add the JTextArea on load up and just clear the text area every time they click the new file menu item:
if(event.getSource() == newFile){
textArea.setText(" ");
}
Related
As in title, I struggle to get my JMenu to resize when programatically adding components. In my application I need JMenu with JCheckBoxes. Whenever I tick one of them, JSlider should appear just below. Below is the code that makes that happen. The problem I have is that when there's lot of sliders visible, items in JMenu get clumped - see image below.
How can I force redraw/resize/expansion of JMenu to perserve original checkboxes/sliders height?
Also note - JMenu stays visible at all times when selecting checkboxes. It closes only when I click outside of it. But after such 'restart' menu grows and problem is no longer present.
Many thanks in advance!
public class Window extends JFrame implements ActionListener {
private JPanel panel;
private JMenuBar menuBar;
private JMenu menu;
private JSlider slider1;
private JCheckBoxMenuItem checkBox1;
private JCheckBoxMenuItem checkBox2;
private JCheckBoxMenuItem checkBox3;
public Window() {
super("Example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(300,300));
panel = new JPanel();
panel.setMinimumSize(new Dimension(300,300));
menuBar = new JMenuBar();
menu = new JMenu("Options");
checkBox1 = new JCheckBoxMenuItem("option 1");
checkBox2 = new JCheckBoxMenuItem("option 2");
checkBox3 = new JCheckBoxMenuItem("option 3");
checkBox1.addActionListener(this);
//prevent JMenu from closing after selecting CheckBox
checkBox1.setUI(new BasicCheckBoxMenuItemUI() {
#Override
protected void doClick(MenuSelectionManager msm) {
checkBox1.doClick(0);
}
});
slider1 = new JSlider();
slider1.setVisible(false);
menu.add(checkBox1);
menu.add(slider1);
menu.add(checkBox2);
menu.add(checkBox3);
menuBar.add(menu);
setJMenuBar(menuBar);
add(panel);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(checkBox1)) {
slider1.setVisible(checkBox1.isSelected());
}
}
}
Here's screen from my main application:
Hiding and reshowing the popup menu will cause it to be resized:
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(checkBox1)) {
slider1.setVisible(checkBox1.isSelected());
menu.setPopupMenuVisible(false);
menu.setPopupMenuVisible(true);
}
}
Call revalidate() it is supposed to do the trick, call it on the newly added components. https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Component.html#revalidate()
But i would say a use case like this is not what menus are meant for? why not use a dialog for dynamic components?
For background https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Component.html#revalidate() call it o the newly added component and see https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Component.html#invalidate() and https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Container.html#isValidateRoot()
I'm trying to exit menu using the ActionListener, however my code doesn't work properly and the "Quit the Program" button doesn't do anything. Below is the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.ButtonGroup;
import javax.swing.JMenuBar;
import javax.swing.KeyStroke;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JFrame;
public class testCoinSorterGUI extends testCoinSorter{
JTextArea output;
JScrollPane scrollPane;
public JMenuBar createMenuBar() {
JMenuBar menuBar;
JMenu menu, submenu;
JMenuItem menuItem;
JRadioButtonMenuItem rbMenuItem;
JCheckBoxMenuItem cbMenuItem;
//Create the menu bar.
menuBar = new JMenuBar();
//Build the first menu.
menu = new JMenu("Calculator");
menu.setMnemonic(KeyEvent.VK_A);
menu.getAccessibleContext().setAccessibleDescription(
"The only menu in this program that has menu items");
menuBar.add(menu);
menuItem = new JMenuItem("Coin calculator");
menu.add(menuItem);
menuItem = new JMenuItem("Multi Coin calculator");
menu.add(menuItem);
//Build second menu in the menu bar.
menu = new JMenu("Print coin list");
menu.setMnemonic(KeyEvent.VK_N);
menu.getAccessibleContext().setAccessibleDescription("This menu does nothing");
menuBar.add(menu);
//Build third menu in the menu bar.
menu = new JMenu("Set details");
menuBar.add(menu);
menuItem = new JMenuItem("Set currency");
menu.add(menuItem);
menuItem = new JMenuItem("Set minimum coin input value");
menu.add(menuItem);
menuItem = new JMenuItem("Set maximum coin input value");
menu.add(menuItem);
menu.addSeparator();
menuItem = new JMenuItem("Display program configurations");
menu.add(menuItem);
//Build fifth menu in the menu bar.
menu = new JMenu("Quit the program");
menuBar.add(menu);
menu.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
);
return menuBar;
}
public Container createContentPane() {
//Create the content-pane-to-be.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setOpaque(true);
//Create a scrolled text area.
output = new JTextArea(5, 30);
output.setEditable(false);
scrollPane = new JScrollPane(output);
//Add the text area to the content pane.
contentPane.add(scrollPane, BorderLayout.CENTER);
return contentPane;
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = testCoinSorterGUI.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("*** CoinSorterGUI ***");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
testCoinSorterGUI demo = new testCoinSorterGUI();
frame.setJMenuBar(demo.createMenuBar());
frame.setContentPane(demo.createContentPane());
//Display the window.
frame.setSize(680, 480);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Currently I only want to test the "quit the program" button, so please ignore all the other menu.
Any help would be appreciated, I am really stucked though I think I have put the code in the correct order.
First of all:
public class testCoinSorterGUI extends testCoinSorter{
Class names should start with an upper case character. Follow the conventions used by the JDK.
I'm trying to exit menu using the ActionListener
A JMenuBar is designed to display JMenu objects.
A JMenu is designed to be clicked and display a list of JMenuItems.
An ActionListener only works on a JMenuItem.
So the logical structure of your code should be:
JMenuBar
JMenu
JMenuItem
When you add the JMenuItem you can add an "accelerator" to the menu item so the application by be closed directly from the keyboard. This save the user from using the mouse all the time and having to click on the menu and menu item.
Use a menuitem, not a menu
menu = new JMenu("Quit the program");
menuBar.add(menu);
menu.addActionListener(
Should be
JMenuItem menuI = new JMenuItem("Quit the program");
menuBar.add(menuI);
menuI.addActionListener(
I have the following code for a JMenuBar (This code has been taken from a free java program call JGuiD and edited for personal purposes)
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Dimension;
import java.awt.Color;
public class GuiDMenuBar extends JMenuBar
{
JMenu m_file,m_edit,m_help;
JMenuItem mi_f_new,mi_f_open,mi_f_save,mi_f_saveas,mi_f_exit;
JMenuItem mi_e_cut,mi_e_copy,mi_e_paste,mi_e_delete;
JMenuItem mi_v_motif,mi_v_java,mi_v_windows,mi_v_nimbus;
JMenuItem mi_h_help,mi_h_about;
JButton m_code;
public GuiDMenuBar()
{
setBorderPainted(true);
makeFileMenu();
makeEditMenu();
makeCodeButton();
makeHelpMenu();
}
void makeFileMenu()
{
m_file = new JMenu("File");
m_file.setMnemonic('F');
mi_f_new = new JMenuItem("New",new ImageIcon("icons/new_project.png"));
mi_f_new.setMnemonic('N');
mi_f_open = new JMenuItem("Open",new ImageIcon("icons/open_project.png"));
mi_f_open.setMnemonic('O');
mi_f_save = new JMenuItem("Save",new ImageIcon("icons/save.png"));
mi_f_save.setMnemonic('S');
mi_f_saveas = new JMenuItem("Save Java File",new ImageIcon("icons/saveas.png"));
mi_f_saveas.setMnemonic('J');
mi_f_exit = new JMenuItem("Exit",new ImageIcon("icons/exit.png"));
mi_f_exit.setMnemonic('X');
mi_f_new.setAccelerator(KeyStroke.getKeyStroke("control N"));
mi_f_open.setAccelerator(KeyStroke.getKeyStroke("control O"));
mi_f_save.setAccelerator(KeyStroke.getKeyStroke("control S"));
mi_f_saveas.setAccelerator(KeyStroke.getKeyStroke("control J"));
mi_f_exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,InputEvent.ALT_MASK));
m_file.add(mi_f_new);
m_file.add(mi_f_open);
m_file.addSeparator();
m_file.add(mi_f_save);
m_file.add(mi_f_saveas);
m_file.addSeparator();
m_file.add(mi_f_exit);
add(m_file);
}
void makeEditMenu()
{
m_edit = new JMenu("Edit");
m_edit.setMnemonic('E');
mi_e_cut = new JMenuItem("Cut",new ImageIcon("icons/cut.png"));
mi_e_cut.setMnemonic('X');
mi_e_copy = new JMenuItem("Copy",new ImageIcon("icons/copy.png"));
mi_e_copy.setMnemonic('C');
mi_e_paste = new JMenuItem("Paste",new ImageIcon("icons/paste.png"));
mi_e_paste.setMnemonic('P');
mi_e_delete = new JMenuItem("Delete",new ImageIcon("icons/delete.png"));
mi_e_delete.setMnemonic('D');
mi_e_cut.setAccelerator(KeyStroke.getKeyStroke("control X"));
mi_e_copy.setAccelerator(KeyStroke.getKeyStroke("control C"));
mi_e_paste.setAccelerator(KeyStroke.getKeyStroke("control V"));
mi_e_delete.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0));
m_edit.add(mi_e_cut);
m_edit.add(mi_e_copy);
m_edit.add(mi_e_paste);
m_edit.add(mi_e_delete);
add(m_edit);
}
void makeHelpMenu()
{
m_help = new JMenu("Help");
m_help.setMnemonic('H');
mi_h_help = new JMenuItem("Help",new ImageIcon("icons/help.png"));
mi_h_help.setMnemonic('H');
mi_h_about = new JMenuItem("About");
mi_h_about.setMnemonic('A');
mi_h_help.setAccelerator(KeyStroke.getKeyStroke("F1"));
mi_h_about.setAccelerator(KeyStroke.getKeyStroke("control A"));
m_help.add(mi_h_help);
m_help.addSeparator();
m_help.add(mi_h_about);
add(m_help);
}
void makeCodeButton()
{
m_code = new JButton();
m_code.setOpaque(false);
m_code.setContentAreaFilled(false);
m_code.setBorder(null);
m_code.setFocusable(false);
m_code.setText("Code Shift C");
Dimension dBt = new Dimension(75,25);
m_code.setMinimumSize(dBt);
m_code.setPreferredSize(dBt);
m_code.setMaximumSize(dBt);
m_code.getModel().addChangeListener(new ChangeListener()
{
#Override
public void stateChanged(ChangeEvent e)
{
ButtonModel model = (ButtonModel) e.getSource();
if(model.isRollover())
{
m_code.setBackground(Color.RED);
m_code.setOpaque(true);
}
else
{
m_code.setBackground(null);
m_code.setOpaque(false);
m_code.setContentAreaFilled(false);
}
}
});
m_code.setMnemonic('C');
add(m_code);
}
public void addListeners(ActionListener al)
{
mi_f_new.addActionListener(al);
mi_f_open.addActionListener(al);
mi_f_save.addActionListener(al);
mi_f_saveas.addActionListener(al);
mi_f_exit.addActionListener(al);
mi_e_cut.addActionListener(al);
mi_e_copy.addActionListener(al);
mi_e_paste.addActionListener(al);
mi_e_delete.addActionListener(al);
mi_h_help.addActionListener(al);
mi_h_about.addActionListener(al);
m_code.addActionListener(al);
}
}
My aim is to make the JButton to appear like it is a JMenu. This would entail that the button only changes colour when I am interacting with the rest of the JMenuBar not just when I hover over it. For example if I had clicked on the JMenu m_file and then hovered over the JButton the background would change, however if I was not previously interacting with the JMenuBar it should not change the background when I hover over the JButton. The next thing required would be the JMenuBar treats it as a JMenu. I mean this in the sense that when F10 is clicked and the first JMenu is selected. After which you can then click on the right arrow on the arrow key pad on your keyboard, this will select the next JMenu. However using this method of navigation skips the JButton and does not allow you to interact with the JButton in anyway. I also mean this in the sense that if you interact with a JMenu and then hover over the JButton the JMenuBar shows you are still hovering over the JMenu as well (See Image).
So I suppose I have three questions.
How do you get the JButton to only change colour if the JMenuBar is already being interacted with?
How do you get the JMenuBar to treat the JButton as a JMenu in the senses that I described?
Is anyone aware of the exact colour of the background of the JMenu when you hover over it? Since I would prefer to change my JButton's background to the same colour of the JMenu's background instead of it just being red.
Thanks,
Dan
My Program has a JMenuBar with JMenuItems.
They have a ActionListener, and I set a Shortcut with setAccelerator.
Now I am hiding the menu bar when the window become unfocused, to get more space for a displayed image.
But after the first hiding of the menubar, the hotkeys just stop working.
How can I fix that?
I created a little example code to illustrate that strange behavior:
import javax.swing.*;
import java.awt.event.*;
class Example extends JFrame{
public static void main(String[] args) {
new Example(); //main is static
}
static JMenuBar menubar; //be accessable for the ActionListener
Example() {
//JPanel
this.setSize(50,50);
this.setVisible(true);
//Menubar, static
menubar = new JMenuBar();
this.setJMenuBar(menubar);
//Menu
JMenu filemenu = new JMenu("File");
menubar.add(filemenu);
//Item
JMenuItem menuitem = new JMenuItem("Do Something...");
filemenu.add(menuitem);
menuitem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, KeyEvent.SHIFT_DOWN_MASK)); // Shift + D
menuitem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action!");
}
});
JButton button = new JButton("Show/Hide menubar");
this.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Toggle Bar!");
menubar.setVisible(!menubar.isVisible()); //Toggle
}
});
}
}
For reference:
I'm using Java 1.7.0_60-ea (Java 7) on a Mac.
But this error occurs independent of using the Mac native menu bar or the normal java menu bar inside the JFrame.
You could try to add global keybindings. How to add keybindings is explained here.
Here is an example of what you could do:
//Any component that is always visible in the window (like the image)
JComponent c;
//Get input and action map
InputMap imap = c.getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap amap = c.getActionMap();
//Put keybinding and action
imap.put(KeyStroke.getKeyStroke("shift D"), "doSomething");
amap.put("doSomething", anAction);
Note that it only works in the focused window. But should work regardless of the menubar being visible or not.
Any idea why the menu bar menuBar is not showing? everything looks fine to me.
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class mySticky extends JFrame implements ActionListener{
//weStart!
JFrame frame = new JFrame("Sticky Note");
JMenuBar menuBar = new JMenuBar();
JMenu noteMenu = new JMenu("Note");
JMenuItem newNote = new JMenuItem("New Note");
JMenuItem open = new JMenuItem("Open");
JMenuItem saveAs = new JMenuItem("Save As");
JMenuItem save = new JMenuItem("Save");
//Constructor
public mySticky(){
setSize(400,300);
setLocation(500,250);
setTitle("Sticky Note");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
menuBar.add(noteMenu);
noteMenu.add(newNote);
noteMenu.add(open);
noteMenu.add(saveAs);
noteMenu.add(save);
frame.setJMenuBar(menuBar);
}
public void actionPerformed (ActionEvent e){
}
public static void main (String [] args ){
mySticky sticky = new mySticky ();
sticky.setVisible(true);
}
}
You add the menubar to frame, which is never added to any UI. Replace
frame.setJMenuBar(menuBar);
by
setJMenuBar(menuBar);
and your menubar will become visible. Or you should add frame to the UI as well. Not sure what you tried to achieve.
And you should wrap the code of your main method in a Runnable and execute it on the EDT (for example using EventQueue.invokeLater)
Instead of frame.setJMenuBar(menuBar), try this.setJMenuBar(menuBar) in your constructor.