Is there a way to add a JMenuItem (or similar button-type object) to a JMenuBar?
Adding a JMenuItem doesn't play well with the layout of a JMenuBar, and buttons look too button-like.
Should we be tweaking the button to look like a JMenuItem or tweaking the JMenuBar to display the JMenuItem correctly? Or something else altogether?
The following code implements camickr's solution, although I would have come up with the same thing after seeing the default way JMenuItems are rendered in a JMenuBar. It looks reasonably authentic and responds to clicks, but not to the mnemonic.
I tried giving the JMenuItems accelerators (see code) and that works but that looks really weird.
public class TheDude19 extends JFrame {
private class Action1 extends AbstractAction {
private Action1() {
super("Action1");
putValue(MNEMONIC_KEY, (int) '1');
// putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK));
}
public void actionPerformed(ActionEvent arg0) {
System.out.println("Action 1!");
}
}
private class Action2 extends AbstractAction {
private Action2() {
super("Action2");
putValue(MNEMONIC_KEY, (int) '2');
}
public void actionPerformed(ActionEvent arg0) {
System.out.println("Action 2!");
}
}
private class NarrowMenuItem extends JMenuItem {
public NarrowMenuItem(Action a) {
super(a);
}
public Dimension getMaximumSize() {
return new Dimension(super.getPreferredSize().width, super.getMaximumSize().height);
}
}
public TheDude19() {
JMenuItem menu1 = new NarrowMenuItem(new Action1());
JMenuItem menu2 = new NarrowMenuItem(new Action2());
JMenuBar mb = new JMenuBar();
mb.add(menu1);
mb.add(menu2);
add(mb, BorderLayout.NORTH);
setSize(400, 300);
}
public static void main(String[] args) {
(new TheDude19()).setVisible(true);
}
}
JMenuItem doesn't play well with the
layout of a JMenuBar
A menubar use a BoxLayout which will try to strech the component to its maximum size. Try using:
menuItem.setMaximumSize( menuItem.getPreferredSize() );
If you need more help post your SSCCE showing the problem.
Just tweak the JButton.
button= new JButton("MenuItem");
button.setOpaque(true);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setFocusable(false);
button.addActionListener(new buttonHandler());
menuBar.add(button);
setContentAreaFilled makes it see-through,
setBorderPainted gets rid of the border,
setFocusable gets rid of the tiny border around the text.
Maybe you're forgetting your JMenu. You need to put the JMenuItem in a JMenu, then you add the JMenu to the JMenuBar.
To build a menu bar you need to do something like the following:
JMenuBar myBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem newFileMenuItem = new JMenuItem("New");
newFileMenuItem.addActionListener(new ActionListerner() { ... Define Action Handler here... });
fileMenu.add(newFileMenuItem);
myBar.add(fileMenu);
I had something like this happen recently I had a JMenuBar that only had 2 JMenuItems in (so note that I haven't tried this in a mixed JMenu and JMenuItem environment.
At first I ended up changing the Layout to a FlowLayout with a left alignment, but that left too much space in-between the components. I messed around with trying to do various things, but was very unsatisfied. What I ended up doing was just using a JMenu, but overriding some of it's behaviors so that it pretended to be a JMenuItem. Like so:
JMenuBar mainMenuBar = new JMenuBar();
final JMenu quitMenuItem = new JMenu("Quit");
quitMenuItem.addMenuListener(new MenuListener() {
public void menuSelected(MenuEvent e) {
System.exit(0);
}
public void menuDeselected(MenuEvent e) {}
public void menuCanceled(MenuEvent e) {}
});
quitMenuItem.setPopupMenuVisible(false);
final JMenu aboutMenuItem = new JMenu("About");
aboutMenuItem.addMenuListener(new MenuListener() {
public void menuSelected(MenuEvent e) {
JOptionPane.showMessageDialog(MainFrame.this, "Assignment 3 With Swing UI. Author: T.Byrne", "About", JOptionPane.INFORMATION_MESSAGE);
aboutMenuItem.setSelected(false);//otherwise it will still be selected after the dialog box.
}
public void menuDeselected(MenuEvent e) {}
public void menuCanceled(MenuEvent e) {}
});
aboutMenuItem.setPopupMenuVisible(false);
mainMenuBar.add(quitMenuItem);
mainMenuBar.add(aboutMenuItem);
this.setJMenuBar(mainMenuBar);
Yup. Or do it the easy way
mb.add(new JMenuItem(closeAction) {
public Dimension getMaximumSize() {
return new Dimension(
super.getPreferredSize().width,
super.getMaximumSize().height);
}
});
It creates a class file, but meh.
To get the button to look like a JMenu just add a rollover effect and remove the border of the button (See code below for example)
Required imports
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Dimension;
import java.awt.Color;
Code
JButton tstButton = new JButton(); //Button
tstButton.setText("Test"); //Button Text
tstButton.setOpaque(false); //These remove the button filling and border
tstButton.setContentAreaFilled(false);
tstButton.setBorder(null);
tstButton.setFocusable(false);
tstButton.setRolloverEnabled(true); //Allows the button to detect when mouse is over it
tstButton.getModel().addChangeListener(new ChangeListener()
{
#Override
public void stateChanged(ChangeEvent e)
{
ButtonModel model = (ButtonModel) e.getSource();
if(model.isRollover())
{
tstButton.setBackground(Color.RED); //Changes the colour of the button
tstButton.setOpaque(true);
}
else
{
tstButton.setBackground(null);
tstButton.setOpaque(false);
}
}
});
Dimension dBt = new Dimension(75,25); //Sets the size of the button in the JMenuBar
tstButton.setMinimumSize(dBt);
tstButton.setPreferredSize(dBt);
tstButton.setMaximumSize(dBt);
tstButton.setMnemonic('T'); //Allows you to press Alt+T on your keyboard to press the button
tstButton.addActionListener(new ActionListener() //Adds action listener so it can do something
{
public void actionPerformed(ActionEvent e)
{
System.out.println("Button pressed");
}
});
menuBar.add(tstButton); //Adds the button to the JMenuBar
Edit
There is a much improved way to do this
JButton tstButton = new JButton();
tstButton.setVisible(false);
tstButton.addActionListener(new CustomActionListener());
menuBar.add(tstButton);
JMenu menuButton = new JMenu();
addHotKey(menuButton, "shift C", 'm', "Menu Button","pressed");
menuButton.addMouseListener(new CustomMouseListener());
menuButton.addMenuKeyListener(new CustomKeyListener());
menuBar.add(menuButton);
public void addHotKey(JMenu J, String s, char c, String S, String key)
{
Action buttonAction = new AbstractAction(S)
{
#Override
public void actionPerformed(ActionEvent evt)
{
clcikComponent(tstButton);
}
};
J.setAction(buttonAction);
buttonAction.putValue(Action.MNEMONIC_KEY, KeyEvent.getExtendedKeyCodeForChar(c));
J.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(s), key);
J.getActionMap().put(key, buttonAction);
}
class CustomMouseListener implements MouseListener
{
public void mouseClicked(MouseEvent e)
{
clcikComponent(m_Invisible);
}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
}
class CustomKeyListener implements MenuKeyListener
{
#Override
public void menuKeyTyped(MenuKeyEvent e)
{
char c = e.getKeyChar();
if(c==KeyEvent.VK_ENTER)
{
if(m_code.isSelected())
{
clcikComponent(m_Invisible);
}
}
}
#Override
public void menuKeyPressed(MenuKeyEvent e){}
#Override
public void menuKeyReleased(MenuKeyEvent e){}
}
public void clcikComponent(JButton comp)
{
comp.doClick();
}
class CustomActionListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
//Makes Button Perform Action
}
}
Getting the UI and the code both to look good took a while. We ended up attaching a mouse adapter to the JMenu's underlying component:
JMenu selectData = new JMenu("Select data...");
selectData.getComponent().addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// Our code to open a window for choosing data series here...
// [...]
}
});
menuBar.add(selectData);
I guess we'll add a KeyAdapter as well, but haven't yet.
Related
I am still learning how to code in java and I could use a bit of help right now.
This is the current code I wrote. As you can see, it's a simple panel with a bunch of buttons and a slider. I want to make a different console output whenever I hit a different button. So if I hit Back, it's supposed to write Back in the console. If I scroll a bit on the slider, it's supposed to write the new value in the console. Stuff like that. I know it has to be done with actionListener and actionPerformed but after some experimenting I couldn't get it to work.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Gui implements ActionListener {
// Adding all the goods
JFrame frame;
JPanel panel;
JButton endButton;
JButton backButton;
JButton calcButton;
JSlider maxIterations;
JLabel view;
Gui() {
// General
this.frame = new JFrame("Trying my best, I swear");
this.frame.setSize(500, 500);
this.frame.setVisible(true);
this.panel = new JPanel();
// Buttons
this.backButton = new JButton("Back");
this.calcButton = new JButton("Calc");
this.endButton = new JButton("End");
this.panel.add(this.endButton);
this.panel.add(this.calcButton);
this.panel.add(this.backButton);
this.frame.add(this.panel);
// Label
JLabel label1 = new JLabel();
label1.setText("Space Holer");
panel.add(label1);
// Slider
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 30, 15);
panel.add(slider);
slider.setMinorTickSpacing(2);
slider.setMajorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
// Make the buttons do something
this.endButton.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
System.out.println("End");
}
public static void main(String[] args) {
#SuppressWarnings("unused")
Gui m = new Gui();
}
}
You could...
Take advantage of the actionCommand property of the button, which is set to the ActionEvent when it's created. If you don't supply an actionCommand to the button yourself, it will default to the text value, so you could do something like
public class ButtonActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case "Back":
System.out.println("Back");
break;
case "Calc":
System.out.println("Calc");
break;
case "End":
System.out.println("End");
break;
}
}
}
This is good if the ActionListener is external to the class where the buttons are defined, because you won't have access to the button references. It's also good, because you could have a number of buttons (including toolbar buttons and menu items) which do the same thing
You could...
Make use of the ActionListener's source property
public class ButtonActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == backButton) {
System.out.println("Back");
} else if (e.getSource() == calcButton) {
System.out.println("Calc");
} else if (e.getSource() == endButton) {
System.out.println("End");
}
}
}
This is useful if the ActionListener in defined as a inner class to the parent class from where the buttons are defined
You could...
Use an anonymous class registered directly against the button...
endButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("End");
}
});
This is good where the button does a single, isolated task
You could...
Make use of the Action API which allows you to define a self contained unit of work, which can be used by buttons to configure themselves completely from it. This is useful where you have a repeated action which can be executed from different locations of the UI, like a "open file" action contained in the menu bar, tool bar and some wizard. You can even use it with the key bindings API for extended functionality
See How to use actions for more details
Need to add ActionListener to all buttons,
calcButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("calcButton");
// calculation for slider.
}
});
backButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("backButton");
}
});
then u get the different console output.
Call setVisible on jframe after you placed all components into it.
Add ActionListener to each button. Add ChangeListener to slider as it cannot have ActionListener.
See full code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class Gui implements ActionListener {
// Adding all the goods
JFrame frame;
JPanel panel;
JButton endButton;
JButton backButton;
JButton calcButton;
JSlider maxIterations;
JLabel view;
Gui() {
// General
this.frame = new JFrame("Trying my best, I swear");
this.frame.setSize(500, 500);
this.panel = new JPanel();
// Buttons
this.backButton = new JButton("Back");
this.calcButton = new JButton("Calc");
this.endButton = new JButton("End");
this.panel.add(this.endButton);
this.panel.add(this.calcButton);
this.panel.add(this.backButton);
this.frame.add(this.panel);
// Label
JLabel label1 = new JLabel();
label1.setText("Space Holer");
panel.add(label1);
// Slider
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 30, 15);
panel.add(slider);
slider.setMinorTickSpacing(2);
slider.setMajorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
// Make the buttons do something
this.endButton.addActionListener(this);
this.backButton.addActionListener(this);
this.calcButton.addActionListener(this);
slider.addChangeListener(e -> {
Object source = e.getSource();
if (source instanceof JSlider) {
int value = ((JSlider) source).getValue();
System.out.println(value);
}
});
frame.pack();
this.frame.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (source instanceof JButton) {
String text = ((JButton) source).getText();
System.out.println(text);
}
}
public static void main(String[] args) {
#SuppressWarnings("unused")
Gui m = new Gui();
}
}
I have main JFrame in my project. And one main JPanel with Y-AXIS BoxLayout which is used to contain another panels in it. This is the way i use my JFrame to show this JPanel by default (I'm not quite convinced if this is the right way):
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
mainPanel = new MainScreenPanel();
MainFrame mainFrame = new MainFrame();
mainFrame.setContentPane(mainPanel);
mainFrame.invalidate();
mainFrame.validate();
mainFrame.setVisible(true);
}
});
}
Next I add two JPanels into mainPanel like this:
public class MainScreenPanel extends javax.swing.JPanel {
public MainScreenPanel() {
StatusPanel sPanel = new StatusPanel();
LogPanel lPanel = new LogPanel();
add(sPanel);
add(lPanel);
}
}
lPanel has different gui elements on it. One of them is a button which opens another panel (addConnectionPanel), and replaces mainPanel in the jFrame Here is the way i do it:
private void addCnctButtonActionPerformed(java.awt.event.ActionEvent evt) {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
topFrame.setContentPane(new AddConnectionPanel());
topFrame.invalidate();
topFrame.validate();
}
AddConectionPanel has some labels and input text boxes. It has two buttons ok and cancel. Here is the code of cancel button:
private void cancelCnctBtnActionPerformed(java.awt.event.ActionEvent evt) {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
topFrame.setContentPane(new MainScreenPanel());
topFrame.invalidate();
topFrame.validate();
}
sPanel is empty. It must be empty until input boxes on AddConnectionPanel are not filled and 'ok' button is not pressed. When these actions are performed, I want to dynamically create JLabels which take parameters from inputs on sPanel. Labels should be grouped, so when the actions performed second time new group must be created. Can some one give me advice on how to do this? And show me my mistakes? Keep in mind I'm using NetBeans.
This would be my approach:
public interface ConnectionPanelListener{
void onOkButtonClicked(String... options);
void onCancelButtonClicked();
}
public class AddConnectionPanel extends JPanel {
private static final long serialVersionUID = 1L;
private ConnectionPanelListener listener;
public AddConnectionPanel(){
final Map<ConnectionOptions, JTextField> components = new HashMap<>(ConnectionOptions.values().length);
for(ConnectionOptions option:ConnectionOptions.values()){
this.add(new JLabel(option.labelCaption));
JTextField textField = new JTextField();
//setup textField;
this.add(textField);
components.put(option, textField);
}
JButton button = new JButton("OK");
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(final MouseEvent pE) {
super.mouseClicked(pE);
//TODO validate TextFields
Collection<String> inputs = new Stack<>();
for(Entry<?,JTextField> e : components.entrySet()){
String text = e.getValue().getText();
if(text==null || text.trim().isEmpty()){
//TODO improve input validation
System.out.println("Input text is empty for: "+e.getKey());
} else {
inputs.add(e.getKey() + ": " + text);
}
}
listener.onOkButtonClicked(inputs.toArray(new String[inputs.size()]));
}
});
this.add(button);
button = new JButton("cancel");
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(final MouseEvent pE) {
super.mouseClicked(pE);
listener.onCancelButtonClicked();
}
});
this.add(button);
}
public void setConnectionPanelListener(final ConnectionPanelListener l){
listener = l;
}
private enum ConnectionOptions{
IP_ADDRESS("IP-Address:"), PORT("Port:"), WHATEVER_ATTRIBUTE_YOU_NEED("Extras:");
private String labelCaption;
private ConnectionOptions(final String caption) {
labelCaption = caption;
}
}
}
As you can see, AddConnectionPanel expects a Listener to register for the case, that "OK" or "CANCEL" are clicked. So your adjusted implementation could be like:
private void addCnctButtonActionPerformed(java.awt.event.ActionEvent evt) {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
AddConnectionPanel panel = new AddConnectionPanel();
panel.setConnectionPanelListener(new ConnectionPanelListener(){
#Override
void onOkButtonClicked(String... options){ TODO: fill sPanel using the given Strings }
#Override
void onCancelButtonClicked(){ TODO }
});
topFrame.setContentPane(panel);
topFrame.invalidate();
topFrame.validate();
}
Example code:
public class FrameMenuTextFieldTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame();
frame.getContentPane().add(new JTextField());
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenuItem item = new JMenuItem("Item1");
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Menu Item clicked");
}
});
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_5, 0));
menu.add(item);
menubar.add(menu);
frame.setJMenuBar(menubar);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
The problem here is if I type 5 into the textfield, not only the textfield gets this event, but the menu item as well, and its action is performed; message shown.
What is the simplest way to disable the key event propagation to the menu bar?
I my real application, I have a lot of menu items to disable for a few textfields.
Bind the JMenuItem with some modifiers such as Ctrl, Alt, Shift etc. if possible as mentioned here KeyStroke#getKeyStroke().
Try something like as shown below to bind it with Ctrl+5.
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_5, InputEvent.CTRL_DOWN_MASK));
EDIT
It might help you if you don't want to use any modifier.
If the current focusable component is not JTextField then perform action on JMenuItem.
Sample code:
JMenuItem item = new JMenuItem("Item1");
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Component component = frame.getFocusOwner();
if (!(component instanceof JTextField)) {
JOptionPane.showMessageDialog(frame, "Menu Item clicked");
}
}
});
Read more here on In Swing, how can I find out what object currently has focus?
I tried codes from different site's and one from here about a color. How do I get color chooser to work with the press of a jmenu item?
I looked at ColorChooser Example and also Oracle Color Chooser Example and then implementing into the original class using the following code:
JMenuItem clr = new JMenuItem("Font Color");
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo ccd = new ColorChooserDemo();
ccd.setVisible(true);
}
});
But this seems do do nothing when I press the menu item.
The class code is from the oracle webpage. These are the following class I use (shortened of course to the problem at hand). I'm making a notepad program as i'm getting back into programming and refreshing my memory of how to do things in java. Problem at hand is, I am unable to get the color chooser to come up when I click on the jmenuitem clr (which is font color) the following code show's what I have so far:
Color Chooser Class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.colorchooser.*;
/* ColorChooserDemo.java requires no other files. */
#SuppressWarnings("serial")
public class ColorChooserDemo extends JPanel
implements ChangeListener {
protected JColorChooser tcc;
protected JLabel banner;
public ColorChooserDemo() {
super(new BorderLayout());
//Set up color chooser for setting text color
tcc = new JColorChooser();
tcc.getSelectionModel().addChangeListener(this);
tcc.setBorder(BorderFactory.createTitledBorder(
"Choose Text Color"));
add(tcc, BorderLayout.PAGE_END);
}
public void stateChanged(ChangeEvent e) {
Color newColor = tcc.getColor();
FirstWindow.ta1.setForeground(newColor);
}
/**
* 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("ColorChooserDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new ColorChooserDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
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();
}
});
}
}
Main Class:
import java.awt.EventQueue;
public class Main{
protected static Object fw;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
try
{
FirstWindow fw = new FirstWindow();
fw.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
}
FirstWindow class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class FirstWindow extends JFrame {
private static final long serialVersionUID = 1L;
protected JColorChooser tcc;
protected static JTextArea ta1;
public FirstWindow() {
super("Note Pad");
Font font = new Font("Verdana", Font.BOLD, 12);
//Setting the size of the note pad
setSize(650, 745);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//Create the MenuBar
JMenuBar mb = new JMenuBar();
setJMenuBar(mb);
//Create the panel to hold everything in
JPanel p = new JPanel();
//Create the Text Area
final JTextArea ta1 = new JTextArea();
ta1.setFont(font);
ta1.setMargin(new Insets(5,5,5,5));
ta1.setLineWrap(true);
ta1.setWrapStyleWord(true);
//Create the Scroll Pane to hold the Text Area
final JScrollPane sp = new JScrollPane(ta1);
sp.setPreferredSize(new Dimension(625,675));
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
//Create the menu's
JMenu format = new JMenu("Format");
//Create menu item for picking font color
JMenuItem clr = new JMenuItem("Font Color");
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo ccd = new ColorChooserDemo();
ccd.setVisible(true);
}
});
//adding the menu items to the file menu tab
//adding menu items to the edit tab
//adding menu items to the format tab
format.add(clr);
//adding the menus to the menu bar
mb.add(format);
//adding the scroll pane to the panel
p.add(sp);
add(p, BorderLayout.CENTER);
}
}
Probably the easiest way to show the ColorChooser is the following:
In the ColorChooserDemo class, you have the method private static void createAndShowGUI(), which you should declare public.
Then, replace the ActionListener for the menu item to the following:
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
ColorChooserDemo.createAndShowGUI();
}
});
Your ColorChooserDemo class extends JPanel, not JFrame. You first need a JFrame, then add the panel, then show the JFrame. This is what happens in the createAndShowGUI() method.
Edit:
I understood that you only wanted to know how to show the ColorChooserDemo when selecting a menu item.
However, to actually set the color, you might want to skip using your own ColorChooserDemo class, and replace the ActionListener code with the following:
clr.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
Color c = JColorChooser.showDialog(ta1, "ColorChooserDemo", null);
ta1.setForeground(c);
}
});
An SSCE is easier not only for us to provide a solution, as Andrew suggested, but it may also help you figure out and understand what to do. Anyway, here's a quick example of opening a colour chooser after pressing a JMenuItem:
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JColorChooser jColorChooser = new JColorChooser();
JDialog jDialog = new JDialog();
jDialog.setContentPane(jColorChooser);
jDialog.pack();
jDialog.setVisible(true);
}
});
LE: (sorry, new to colour choosers myself) or just use JColorChooser.showDialog()
I don't know how I can add mouseListener (mouseClicked, mouseEntered, etc...) to my actionPerformed. I learned only how to add action from JButton but mouseListener is in JLabel.
Here it's this code:
test = new JLabel (ikona);
test.setBounds(200, 200, 100, 100);
add(test);
test.addMouseListener(new MouseListener()
{
public void mouseClicked(MouseEvent e) {
System.out.println(ikona2);
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
and:
public void actionPerformed(ActionEvent arg0)
{
Object Zrodlo = arg0.getSource();
if (Źródło==przycisk)
{
wyswietlacz.setText(new Date().toString());
//System.out.println(new Date());
}
else if (Zrodlo==przycisk2)
{
dispose();
}
else if (Zrodlo==przycisk3)
{
wyswietlacz.setText(new Date().toString());
}
else if (Zrodlo==test)
{
wyswietlacz.setText("");
}
"przycsik, przycisk2, przycisk3" are JButton, I try doing something with JLAbel ("test") but I don't have idea how solve this.
P.S. sorry for my english...
EDIT: For JButton I use this to see action in mine JFrame:
public void actionPerformed(ActionEvent arg0)
{
Object Zrodlo = arg0.getSource();
if (Źródło==przycisk)
{
wyswietlacz.setText(new Date().toString());
//System.out.println(new Date());
}
else if (Źródło==przycisk2)
{
dispose();
}
I want to do same with my JLabel and mouseListener. I want see interaction which mouse/cursor which MouseListener. I want to add icon(gif) to JLabel and use MouseListener to change icon1 to icon2 example mouseClicked or mousePressed. If I use:
test.addMouseListener(new MouseListener()
{
public void mouseClicked(MouseEvent e) {
System.out.println(ikona2);
}
I only see source to my "ikona2" in my Eclipse Console. I want to see action in my JFrame.
A listener is a type of callback that follows the observer pattern, something happens, you get notified.
There are many types of listeners for many different types of events. Buttons have an ActionListener which is triggered by, at least, the user clicking or pressing enter or space while the button has focus.
A label does not have an ActionListener, a label is a static component for all intended purposes, however, a label does have a MouseListener...
MouseListener listener = ...;
JLabel label = new JLabel("This is a clickable lable");
label.addMouseListener(listener);
This will allow you to monitor when a mouse click occurs on the label.
Take a look at:
How to write a mouse listener
Writing Event Listeners
Creating a GUI with Swing
For more details
Not sure I understand the question but you can paint a JButton like a JLabel but still have the ActionListener work like a button:
JButton button3 = new JButton("Label Button");
button3.setBorderPainted(false);
button3..setFocusPainted(false);
button3.setContentAreaFilled(false);
button3.addActionListener( ... );
You can't combine those two action listeners (MouseListener & ActionListener). You can add the MouseListener on a JLabel as well on a JButton. Adding an ActionListener to the JLabel isn't allowed anyway. What you can do is to create one MouseListener which handles the events for the JLabel as well for the JButton. Here is an example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JLabel;
public class MouseListenerTest extends javax.swing.JFrame {
private static final long serialVersionUID = 3109442737770802801L;
public static void main(String[] args) {
MouseListenerTest t = new MouseListenerTest();
t.setLayout(new BorderLayout());
MyMouseListener mouseListener = new MyMouseListener();
JLabel l = new JLabel("JLabel");
l.setPreferredSize(new Dimension(200, 100));
JButton b = new JButton("JButton");
b.setPreferredSize(new Dimension(200, 100));
l.addMouseListener(mouseListener);
b.addMouseListener(mouseListener);
t.add(l, BorderLayout.CENTER);
t.add(b, BorderLayout.SOUTH);
t.pack();
t.setVisible(true);
}
}
class MyMouseListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
Object o = e.getSource();
if (o instanceof JButton) {
System.out.println("JButton");
} else if (o instanceof JLabel) {
System.out.println("JLabel");
}
}
#Override
public void mousePressed(MouseEvent e) {/* TODO */
}
#Override
public void mouseReleased(MouseEvent e) {/* TODO */
}
#Override
public void mouseEntered(MouseEvent e) {/* TODO */
}
#Override
public void mouseExited(MouseEvent e) {/* TODO */
}
}