I am currently trying to make a GUI with a menu that has 2 options you can select from. One being "Default Settings" and one being "Custom Settings." When you click on either one, it will take you to the new jPanel that will display the proper windows, text boxes, etc for that panel. However, I cannot seem to get the mouseClicked action to actually switch between the panels. As a test, I have a simple jLabel on each panel that says "Default" for the default panel and "custom" for the custom panel, and each menu item, when clicked respectively, should switch between them. Here is my current code:
frmLegitServerAdder = new JFrame();
frmLegitServerAdder.setTitle("Legit Server Adder 5 Million");
frmLegitServerAdder.setBounds(100, 100, 546, 468);
frmLegitServerAdder.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
frmLegitServerAdder.setJMenuBar(menuBar);
JMenu mnNewMenu = new JMenu("Settings");
menuBar.add(mnNewMenu);
JMenuItem menuItemDefaultSettings = new JMenuItem("Default Settings");
mnNewMenu.add(menuItemDefaultSettings);
JMenuItem menuItemCustomSettings = new JMenuItem("Custom Logon Settings");
mnNewMenu.add(menuItemCustomSettings);
frmLegitServerAdder.getContentPane().setLayout(new CardLayout(0, 0));
final JPanel defaultSettingsPanel = new JPanel();
frmLegitServerAdder.getContentPane().add(defaultSettingsPanel, "name_416522810155567");
defaultSettingsPanel.setLayout(null);
JLabel lblDefaultArea = new JLabel("Default Area");
lblDefaultArea.setBounds(217, 11, 90, 14);
defaultSettingsPanel.add(lblDefaultArea);
final JPanel customSettingsPanel = new JPanel();
frmLegitServerAdder.getContentPane().add(customSettingsPanel, "name_416549691176064");
customSettingsPanel.setLayout(null);
JLabel lblCustomArea = new JLabel("Custom Area");
lblCustomArea.setBounds(235, 21, 46, 14);
customSettingsPanel.add(lblCustomArea);
menuItemDefaultSettings.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
defaultSettingsPanel.setVisible(true);
customSettingsPanel.setVisible(false);
}
});
menuItemCustomSettings.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
defaultSettingsPanel.setVisible(false);
customSettingsPanel.setVisible(true);
}
});
The code runs and the GUI displays just fine, but nothing actually happens when I click on either menu items, as it should. Any ideas?
You should NOT be using a MouseListener. Instead you should be adding an ActionListener to the menu item. Read the section from the Swing tutorial on How to Use Menus for more information.
You should be using a CardLayout when you want to swap components. See How to Use Card Layout from the same tutorial.
You need ActionListener
menuItemDefaultSettings.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
defaultSettingsPanel.setVisible(true);
customSettingsPanel.setVisible(false);
}
});
Hope this helps.
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 want to have a Button Group in which either only one option is selected or none of them are. At the moment, I can get it to have no options ticked by default, and then if one of them is ticked only one of them can be ticked, but I also want to be able to untick the button that was selected. Is this possible?
EDIT: Ideally without having a clear all button, as it would ruin the symmetry of my GUI. Also, here is my code thus far:
ButtonGroup option = new ButtonGroup();
for(int i = 0; i < n; i++) {
JCheckBox check = new JCheckBox("", false);
option.add(check);
row3b.add(check);
}
Just use the clearSelection() method of ButtonGroup :
ButtonGroup.clearSelection()
Clears the selection such that none of the buttons in the ButtonGroup
are selected.
This snippet demonstrates how you can clear selections using ButtonGroup.clearSelection():
//The buttons
JFrame frame = new JFrame("Button test");
JPanel panel = new JPanel();
JRadioButton btn1 = new JRadioButton("Button1");
JRadioButton btn2 = new JRadioButton("Button2");
JButton clearbutton = new JButton("Clear");
panel.add(btn1);
panel.add(btn2);
panel.add(clearbutton);
frame.add(panel);
frame.setVisible(true);
frame.pack();
//The Group, make sure only one button is selected at a time in the group
ButtonGroup btngroup = new ButtonGroup();
btngroup.add(btn1);
btngroup.add(btn2);
btn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Do whatever you want here
}
});
btn2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Do whatever you want here
}
});
clearbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Clear all selections
btngroup.clearSelection();
}
});
As you can see, this creates two JRadioButtons and adds them to group then makes a button that clears selections. Really simple. Or you could create your own radio button class that allows for the unchecking of the button, which is also doable relatively easily.
Hi I am trying to create Scroll Bar for my JFrame. I created JPanel object and set components into JPanel. Then created a JScrollPane object for the panel. Then add the ScrollPane object to JFrame. I am not seeing any scrollbar. Also I am wondering if there is a option in JPanel that would resize the object inside Jpanel automatically according to the zoom level of the JPanel. Any help would be highly appreciated.
public class xmlottgui {
private JPanel Container;
private JFrame frmCreateXml;
private JTextField titlename;
private JLabel lbltitlename;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
xmlottgui window = new xmlottgui();
window.frmCreateXml.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public xmlottgui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
Container = new JPanel();
Container.setLayout(null);
//JScrollPane pane=new JScrollPane(Container,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
frmCreateXml = new JFrame();
frmCreateXml.setTitle("Create XML");
frmCreateXml.setBounds(100, 100, 1000, 1200);
frmCreateXml.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmCreateXml.getContentPane().setLayout(null);
//Create MenuBar
JMenuBar menuBar = new JMenuBar();
Container.add(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenuItem mntmImportFromCsv = new JMenuItem("Import From Excel File");
//Add menu item Exit
JMenuItem mntmexit = new JMenuItem("Exit");
mntmexit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
mnFile.add(mntmexit);
showform();
JScrollPane pane=new JScrollPane(Container,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane.setLayout(null);
frmCreateXml.setContentPane(pane);
frmCreateXml.getContentPane().add(pane);
}
private void showform(){
titlename = new JTextField();
titlename.setBounds(164, 27, 749, 26);
Container.add(titlename);
titlename.setColumns(10);
lbltitlename = new JLabel("Title Name");
lbltitlename.setBackground(Color.GRAY);
lbltitlename.setBounds(22, 1000, 90, 16);
Container.add(lbltitlename);
}
This:
pane.setLayout(null);
Will completely disable your JScrollPane and prevent it from working as it will prevent the JScrollPane from displaying and manipulating its view port properly. JScrollPanes have there own very special layout manager, one you never want to muck with unless you are very clever and know what you're doing. As a general rule you should almost never use null layouts.
Also this is not correct:
frmCreateXml.setContentPane(pane);
frmCreateXml.getContentPane().add(pane);
You make pane the contentPane and then add pane to itself.
AND THIS is messing you up:
frmCreateXml.getContentPane().setLayout(null);
You will want to learn about and use the layout managers as it will make your life much easier.
If a popup menu is still open when another component is clicked, then the component does not get the event, because it's probably consumed by the popup. This happens for all JPopupmenus in general.
This happens only in Java 7 with windows LAF (Windows7). Is there a workaround? Is it a known bug?
import javax.swing.*;
import java.awt.event.*;
public class Test
{
public static void main(String[] s)
throws Exception
{
String lookAnfFeelClassName = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(lookAnfFeelClassName);
JMenu menu = new JMenu("TEST Menu");
JMenuItem menuItem = new JMenuItem("Menu Item 1");
JMenuBar menuBar = new JMenuBar();
menu.add(menuItem);
menuBar.add(menu);
final JButton b = new JButton("Test");
b.setBounds(5, 50, 60, 20);
b.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//If the Menu is open when I press the button, the putton is not pressed
//so I have to press it again.
JOptionPane.showMessageDialog(b, "Button Pressed");
}
}
);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(150, 150);
frame.setJMenuBar(menuBar);
frame.getContentPane().setLayout(null);
frame.getContentPane().add(b);
frame.setVisible(true);
}
}
Here is the magic line that fixes the problem:
UIManager.put("PopupMenu.consumeEventOnClose", Boolean.FALSE);
I found this after looking into the source code for the BasicPopupMenuUI class. Apparently this behaviour is a deliberate design choice according to the following comments in the code, but it sure feels like a bug to me.
// Ask UIManager about should we consume event that closes
// popup. This made to match native apps behaviour.
By the way, it happens in Java 5 and 6 too.
I have a menu-bar and a tabbed pane in a frame, and i want that if i select a menuitem, then the requested tab will open. Please help me with this, thanks!!!
In the ActionListener of the JMenuItem, you can call JTabbedPane#setSelectedIndex.
like SoboLAN said:
final JTabbedPane tabs = new JTabbedPane();
JPanel panel = new JPanel();
tabs.add("title", panel);
//add more tabs...
// here the important part starts
JMenuItem item = new JMenuItem("open tab 1");
item.addActionListener(new ActionListener() {
//this function get called when you click the item.
#Override
public void actionPerformed(ActionEvent e) {
//insert the index you want to select
tabs.setSelectedIndex(0);
}
});