How to take out white borders in JMenu and JMenuItems - java

I'm doing this Graphic Interface with Swing. The problem that i'm having is that i can't take the white borders that are arround the JMenuItems, and paint it all of black. Here is an image:
I would like to paint it like this (I have edited the image with paint :D):
Could someone help me? I'll appreciate any help. Thank you!

I just did this quick test, using
UIManager.put("PopupMenu.border", new LineBorder(Color.RED));
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
UIManager.put("PopupMenu.border", new LineBorder(Color.RED));
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Stuff");
menu.add(new JMenuItem("A"));
menu.add(new JMenuItem("BB"));
menu.add(new JMenuItem("CCC"));
menuBar.add(menu);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.setJMenuBar(menuBar);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Now, this may not be desirable, as this will effect ALL popup menus in your program
Updated
I had a look at JMenu and through it's UI delegates and it appears that the popup menu is created within a private method of JMenu called ensurePopupMenuCreated, which would have been an excellent place to inject your custom code.
The method is actually called in a number of different places, but possibly the getPopupMenu is the most accessible
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Stuff") {
private Border border = new LineBorder(Color.RED);
#Override
public JPopupMenu getPopupMenu() {
JPopupMenu menu = super.getPopupMenu();
menu.setBorder(border);
return menu;
}
};
JMenuItem mi = new JMenuItem("Help", 'H');
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, KeyEvent.META_MASK));
menu.add(new JMenuItem("A"));
menu.add(new JMenuItem("BB"));
menu.add(new JMenuItem("CCC"));
menu.add(mi);
menuBar.add(menu);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.setJMenuBar(menuBar);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

I am adding a second approach. You could use setBorder method:
menuBar.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
This solution has the advantage that you can set the level of thickness. In the example above level of thickness is set to 2.
Also you can use setBorder in many components to paint various borders as in the example below:
First the basic code:
Main class:
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
CustomGUI sw = new CustomGUI();
sw.setVisible(true);
});
}
}
CustomGui.class:
import java.awt.*;
import javax.swing.*;
public class CustomGUI extends JFrame {
public CustomGUI() {
super("Simple example");
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
setSize(500,500);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(Color.DARK_GRAY);
JMenuBar menuBar = new JMenuBar();
JMenu menu1 = new JMenu("menu B");
menuBar.add(menu1);
JMenuItem item = new JMenuItem("A text-only menu item");
menu1.add(item);
JMenu menu2 = new JMenu("menu B");
menuBar.add(menu2);
JMenuItem item2 = new JMenuItem("A text-only menu item");
menu2.add(item2);
add(menuBar);
}
}
Now by adding line:
menuBar.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
in CustomGUI() we get:
Now if we want to add border to jmenu's (which is what the OP asked) as well add:
menu1.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.BLUE, 4));
menu2.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.BLUE, 4));
(as you can see in the image i didn't set border for menubar but this could be done as described above using:
menuBar.setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
And also I added another item just for the menu to be bigger and easier to see the border...)

Related

JPopupMenu appears but seems to not react

I've problems to get a JPopupMenu working correctly.
What I expect
The menu should pop up once I do a right click with my mouse. Then I can select an item from the menu and do whatever I want..
What I actually get
The menu appears once I do a right click but after that I can not select a menu item or at least I am missing the well known mouse hover highlight effect (I would expect that the item I am currently hovering is highlighted, like it is the case in the normal menu).
The see problem here (no highlight on hover):
Here is my example code:
package com.mycompany.mavenproject2;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class PopupMenuTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel pane = new JPanel();
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("A"));
popup.add(new JMenuItem("B"));
pane.setSize(300,300);
pane.add(popup);
pane.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e)) {
popup.setLocation(e.getXOnScreen(), e.getYOnScreen());
popup.setVisible(true);
}
}
});
frame.setTitle("Test");
frame.add(pane);
frame.setPreferredSize(new Dimension(300,300));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Edit
Compare to a "normal" menu with working hovering:
Edit #2
Please see the current (unexpected) behaviour:
You need to use the JPopupMenu show method, rather than the setVisible method.
Here's the code I tested with. I'm running Windows 10 and using the Java JDK 13.0.2 with Java 8 compliance. I get the highlight on the mouse over.
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class JPopupMenuTest implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JPopupMenuTest());
}
#Override
public void run() {
JFrame frame = new JFrame();
JPanel pane = new JPanel();
pane.setPreferredSize(new Dimension(300, 300));
pane.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("A"));
popup.add(new JMenuItem("B"));
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
});
frame.setTitle("JPopupMenu Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

open another class with an action listener

Hi im currently working on a program but I need to be able to change the class (so that the frame changes) with just the click of a menu tab.
I would like someone to modify this to get my to class2.java
JMenu area = new JMenu ("Area");
menu.add(area);
JMenuItem convertA= new JMenuItem ("Convertions");
area.add(convertA);
class aaction implements ActionListener{
public void actionPerformed (ActionEvent e) {
}
}
class 1.java
/*import needed packages*/
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JTextPane;
import javax.swing.JTextField;
import javax.swing.JFormattedTextField;
import javax.swing.AbstractAction;
import javax.swing.SwingConstants;
import javax.swing.Action;
import javax.swing.InputVerifier;
import javax.swing.*;
import javax.xml.soap.Text;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.*;
import java.awt.Font;
import java.awt.Frame;
import java.math.*;
import java.lang.*;
import java.text.*;
import java.awt.EventQueue;
import java.awt.SystemColor;
import java.awt.Window;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
#SuppressWarnings("unused")
public class circle_ac {
private JFrame frame;
private JTextField txtRadius;
private JTextField txtTheAreaOf;
private JTextField txtTheCircumfrenceOf;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
circle_ac window = new circle_ac();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public circle_ac() {
initialize();
}
/**
* Initialize the contents of the frame.
* #param arg0
* #param arg0
* #param arg0
*/
private void initialize() {
/*setup the JFrame*/
frame = new JFrame();
frame.setResizable(true);
frame.setBounds(1000, 1000, 2250, 1000);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(BorderLayout.CENTER,new JLabel("MHMB 1.3.5"));
/*setup JMenu*/
Font f = new Font("sans-serif", Font.PLAIN, 25);
UIManager.put("Menu.font", f);
UIManager.put("MenuItem.font", f);
JMenuBar menu = new JMenuBar ();
frame.setJMenuBar(menu);
JMenu circles = new JMenu ("Circles");
menu.add(circles);
JMenuItem ac= new JMenuItem("Area And Circumference");
circles.add(ac);
JMenu measurements = new JMenu ("Measurements");
menu.add(measurements);
JMenuItem convert= new JMenuItem ("Convertions");
measurements.add(convert);
JMenu area = new JMenu ("Area");
menu.add(area);
JMenuItem convertA= new JMenuItem ("Convertions");
area.add(convertA);
class aaction implements ActionListener{
public void actionPerformed (ActionEvent e) {
contentPane.removeAll();
contentPane.setLayout(new BorderLayout());
contentPane.add(BorderLayout.CENTER,frame1);
this.revalidate();
this.repaint();
}
}
JMenu close = new JMenu ("Close");
menu.add(close);
JMenuItem exit = new JMenuItem ("Exit");
close.add(exit);
class eaction implements ActionListener{
public void actionPerformed (ActionEvent e) {
System.exit(0);
}
}
exit.addActionListener(new eaction());
/*setup calculate button*/
JButton btnCalculate = new JButton("calculate");
btnCalculate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
/*setup calculations*/
double rad;
double ans1;
double ans2;
double pi=3.1415926535897932384626433832795;
try {
rad=Double.parseDouble(txtRadius.getText()) ;
ans1= pi*(rad*rad);
ans2= 2*pi*rad;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(25);
txtTheAreaOf.setText("The Area Is "+df.format(ans1));
txtTheCircumfrenceOf.setText("The Circumference Is "+df.format(ans2) );
/*setup error message*/
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Please Enter Valid Radius");
}
}
});
/*initialize calculate button*/
btnCalculate.setFont(new Font("Tahoma", Font.PLAIN, 60));
btnCalculate.setBackground(new Color(227, 227, 227));
btnCalculate.setForeground(Color.BLACK);
frame.getContentPane().add(btnCalculate, BorderLayout.SOUTH);
/*setup Radius text box*/
txtRadius = new JTextField();
txtRadius.setFont(new Font("Tahoma", Font.PLAIN, 55));
txtRadius.setCursor(null);
txtRadius.setInputVerifier(null);
txtRadius.setText(" Enter The Radius");
txtRadius.setBackground(SystemColor.controlHighlight);
frame.getContentPane().add(txtRadius, BorderLayout.CENTER);
txtRadius.setColumns(10);
/*setup Area text box*/
txtTheAreaOf = new JTextField();
txtTheAreaOf.setEditable(false);
txtTheAreaOf.setText("The Area Of The Circle Is ");
txtTheAreaOf.setBackground(SystemColor.control);
txtTheAreaOf.setFont(new Font("Tahoma", Font.PLAIN, 30));
frame.getContentPane().add(txtTheAreaOf, BorderLayout.WEST);
/*setup Circumference text box*/
txtTheCircumfrenceOf =new JTextField();
txtTheAreaOf.setEditable(false);
txtTheCircumfrenceOf.setFont(new Font("Tahoma", Font.PLAIN, 30));
txtTheCircumfrenceOf.setText("The Circumfrence Of The Circle Is ");
txtTheCircumfrenceOf.setBackground(SystemColor.control);
frame.getContentPane().add((Component) txtTheCircumfrenceOf, BorderLayout.EAST);
}
}
class2.java
/*import needed packages*/
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JTextPane;
import javax.swing.JTextField;
import javax.swing.JFormattedTextField;
import javax.swing.AbstractAction;
import javax.swing.SwingConstants;
import javax.swing.Action;
import javax.swing.InputVerifier;
import javax.swing.*;
import javax.xml.soap.Text;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.*;
import java.awt.Font;
import java.awt.Frame;
import java.math.*;
import java.lang.*;
import java.text.*;
import java.awt.EventQueue;
import java.awt.SystemColor;
import java.awt.Window;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
#SuppressWarnings("unused")
public class area_c {
private JFrame frame1;
private JTextField txtRadius;
private JTextField txtTheAreaOf;
private JTextField txtTheCircumfrenceOf;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
area_c window = new area_c();
window.frame1.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public area_c() {
initialize();
}
/**
* Initialize the contents of the frame.
* #param arg0
* #param arg0
* #param arg0
*/
private void initialize() {
/*setup the JFrame*/
frame1 = new JFrame();
frame1.setResizable(true);
frame1.setBounds(1000, 1000, 2250, 1000);
frame1.pack();
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setLayout(new BorderLayout());
frame1.add(BorderLayout.CENTER,new JLabel("MHMB 1.3.5"));
/*setup JMenu*/
Font f = new Font("sans-serif", Font.PLAIN, 25);
UIManager.put("Menu.font", f);
UIManager.put("MenuItem.font", f);
JMenuBar menu = new JMenuBar ();
frame1.setJMenuBar(menu);
JMenu circles = new JMenu ("Circles");
menu.add(circles);
JMenuItem ac= new JMenuItem("Area And Circumference");
circles.add(ac);
JMenu measurements = new JMenu ("Measurements");
menu.add(measurements);
JMenuItem convert= new JMenuItem ("Convertions");
measurements.add(convert);
JMenu area = new JMenu ("Area");
menu.add(area);
JMenuItem convertA= new JMenuItem ("Convertions");
area.add(convertA);
class aaction implements ActionListener{
public void actionPerformed (ActionEvent e) {
}
}
JMenu close = new JMenu ("Close");
menu.add(close);
JMenuItem exit = new JMenuItem ("Exit");
close.add(exit);
class eaction implements ActionListener{
public void actionPerformed (ActionEvent e) {
System.exit(0);
}
}
exit.addActionListener(new eaction());
System.out.println("Hello World!");
I need the menu tab to change it from class1.java to class2.java with an action listener.
is this possible, if so how do I do it.
I recommend to implement your two classes as JPanels. Then you can add these JPanels to your JFrame. Have a look at this small example, that shows the principle in a short and quick way. Hope it helps:
package test;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class TestFrame extends JFrame {
private Container contentPane;
private JPanel panel1,panel2;
public TestFrame() {
super("Test");
this.setJMenuBar(menubar());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = this.getContentPane();
createPanels();
contentPane.setLayout(new BorderLayout());
this.add(BorderLayout.CENTER,panel1);
this.pack();
this.setVisible(true);
}
private JMenuBar menubar() {
JMenuBar menubar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem m1 =new JMenuItem("Selection 1");
JMenuItem m2 =new JMenuItem("Selection 2");
m1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
contentPane.removeAll();
contentPane.setLayout(new BorderLayout());
contentPane.add(BorderLayout.CENTER,panel1);
refresh();
}
});
m2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
contentPane.removeAll();
contentPane.setLayout(new BorderLayout());
contentPane.add(BorderLayout.CENTER,panel2);
refresh();
}
});
fileMenu.add(m1);
fileMenu.add(m2);
menubar.add(fileMenu);
return menubar;
}
private void refresh() {
this.revalidate();
this.repaint();
}
private void createPanels() {
panel1 = new JPanel();
panel1.setLayout(new BorderLayout());
panel1.add(BorderLayout.CENTER,new JLabel("Hello World"));
panel2 = new JPanel();
panel2.setLayout(new BorderLayout());
panel2.add(BorderLayout.CENTER,new JLabel("Goodbye World"));
}
public static void main(String[] args) {
TestFrame t = new TestFrame();
}
}
In most of the IDE's, when you right-click on the Button in the Design(GUI) pane, you can travel through:
Events -> Actions -> actionPerformed().
When you are in one frame, you can set it's visibility off to hide it, like this:
this.setVisible(false);
And you can create the object of another class (of the other frame where you want to redirect) and set it's visibility on to display it, like this:
area_c of = new area_c();
of.setVisible(true);
So, you will be transitioning from one class to another of different frames.
You can achieve the same using the object of JMenuItem object:
class1 = new JPanel();
class1.setLayout(new BorderLayout());
class1.add(BorderLayout.CENTER,new JLabel("Label_Name"));
class2 = new JPanel();
class2.setLayout(new BorderLayout());
class2.add(BorderLayout.CENTER,new JLabel("Label_Name"));
JMenuItem JMenuItemObject1 =new JMenuItem("Class 1");
JMenuItem JMenuItemObject2 =new JMenuItem("Class 2");
JMenuItemObject1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
contentPane.removeAll();
contentPane.setLayout(new BorderLayout());
contentPane.add(BorderLayout.CENTER,panel1);
this.revalidate();
this.repaint();
}
});
JMenuItemObject2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
contentPane.removeAll();
contentPane.setLayout(new BorderLayout());
contentPane.add(BorderLayout.CENTER,panel2);
this.revalidate();
this.repaint();
}
});
area.add(JMenuItemObject1);
area.add(JMenuItemObject2);
menubar.add(area);

JList position resets to default whenever update occurs

list is to accept input from Action1 this works, however, whenever a new element is added to the list, the list's position moves back to the default top-middle position.
This also occurs when the frame is resized, so as a temporary fix I the line frame.setResizable(false) but I do not want that to be permanent.
How would I fix both of these issues?
import static java.lang.String.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
public class lists
{
static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;
public static void createGUI()
{
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(800,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel panel = new JPanel();
frame.add(panel);
JButton addurl = new JButton("Add URL");
panel.add(addurl);
addurl.addActionListener(new Action1());
JButton remurl = new JButton("Remove URL");
panel.add(remurl);
//model.addElement("one");
//model.addElement("two");
//model.addElement("three");
JList list = new JList<String>(model);
list.setCellRenderer(new DefaultListCellRenderer());
list.setVisible(true);
list.setLocation(listXCoord, listYCoord);
list.setBackground(new Color(186, 203, 250));
//list.setLocation(650, 10);
panel.add(list);
list.setSize(130, 540);
}
static class Action1 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
model.addElement(newUrl);
}
}
public static void main(String[] args)
{
createGUI();
}
}
Basically, you're fighting the layout manager (Flowlayout) and losing. When you add a new element to the JList, the container hierarchy is been revalidated which is causing the layout managers to re-layout the contents of their containers
The basic solution would be to use a different layout, but, JFrame uses a BorderLayout, so instead of adding the JList to the JPanel, you could simply add it to the EAST position of the frame instead
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Lists {
static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;
public static void createGUI() {
JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JButton addurl = new JButton("Add URL");
panel.add(addurl);
addurl.addActionListener(new Action1());
JButton remurl = new JButton("Remove URL");
panel.add(remurl);
//model.addElement("one");
//model.addElement("two");
//model.addElement("three");
JList list = new JList<String>(model);
list.setCellRenderer(new DefaultListCellRenderer());
list.setVisible(true);
list.setLocation(listXCoord, listYCoord);
list.setBackground(new Color(186, 203, 250));
//list.setLocation(650, 10);
frame.add(new JScrollPane(list), BorderLayout.EAST);
frame.setVisible(true);
}
static class Action1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
model.addElement(newUrl);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
createGUI();
}
});
}
}
See Laying Out Components Within a Container, How to Use BorderLayout and How to use FlowLayout for more details.
You should also be calling setVisible last, after all the components have been added to the frame, this reduces the possibilities that some of your components won't be displayed when you think they should be.
JList will also benefit from been contained within a JScrollPane. See How to Use Lists and How to Use Scroll Panes for more details

java object resize on window resize

I've to resize few elements like JTable on window resize. I've been trying this code, but it doesn't work correctly:
table.setLocation(0, 23);
Dimension siz = contentPane.getMaximumSize();
table.setSize(siz.height, siz.width - 46);
It resizing my table, but it making it endless, what i don't want. Also I would like to connent scrollbar to this table, and if it's possible - set column width in precentage
Your main problem (with resizing) has more to do with your reliance on form editors then anything to do with Swing or Java
Have a look at Laying Out Components Within a Container for more details.
You're also don't seem to be utilising a JScrollPane to house the JTable in. Have a look at How to Use Tables and How to Use Scroll Panes for more details
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class ResizeTest {
public static void main(String[] args) {
new ResizeTest();
}
public ResizeTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTable table;
private JButton historyButton;
private JButton otherButton;
public TestPane() {
table = new JTable(new DefaultTableModel(10, 10));
historyButton = new JButton("History");
otherButton = new JButton("Other");
setLayout(new BorderLayout());
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
buttons.add(historyButton);
buttons.add(otherButton);
add(buttons, BorderLayout.NORTH);
add(new JScrollPane(table));
JPanel footers = new JPanel(new GridLayout(1, 2));
JLabel left = new JLabel("Left");
left.setHorizontalAlignment(JLabel.LEFT);
JLabel right = new JLabel("Right");
right.setHorizontalAlignment(JLabel.LEFT);
footers.add(left);
footers.add(right);
add(footers, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

Swing Mouse Click Event for JMenu and JPopupMenu

I would like to have Eclipse behavior for mouse clicks outside menus and popup menus in Swing. Basically, in Eclipse, when you press the mouse OUTSIDE the menu, the menu disappears and the mouse press event is forwarded to the component on which you clicked with the mouse.
Irritatingly, Swing does not do this, and I can't find a way around it.
Right now, even with Windows LAF, i have to click a second time to get the component to register the mouse click.
For the sake of the response just do it on a table
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem viewProfile = new JMenuItem("View Profile");
viewProfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
popupMenu.add(viewProfile);
table.setComponentPopupMenu(popupMenu);
EDIT: here is a test code. I don't think it is convenient to add a mouse listener to every simple component so they can register mouse clicks after a popup menu. In the following example, the Table does implement it, but not the Button.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TestMouse {
public static void main(String[] args) {
new TestMouse();
}
private JLabel counter;
private int count;
private JPanel northPanel;
private JButton clickMe;
public TestMouse() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DefaultTableModel model = new DefaultTableModel(new Object[] { "A", "B", "B", "B", "B", "B", "B" }, 10);
JTable table = new JTable(model);
northPanel = new JPanel();
clickMe = new JButton("Button");
clickMe.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("clicked");
count++;
}
});
counter = new JLabel("0");
northPanel.add(counter);
northPanel.add(clickMe);
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem viewProfile = new JMenuItem("View Profile");
viewProfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
popupMenu.add(viewProfile);
table.setComponentPopupMenu(popupMenu);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("clicked");
count++;
counter.setText(String.valueOf(count));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(northPanel, BorderLayout.NORTH);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I don't seem to be able to replicate the issue.
When I right click the table, the popup menu appears and when I click the table again (to dismiss the popup), the mouseClicked event is triggered.
Note the counter in the north position...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TestMouse {
public static void main(String[] args) {
new TestMouse();
}
private JLabel counter;
private int count;
public TestMouse() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DefaultTableModel model = new DefaultTableModel(
new Object[]{"A", "B", "B", "B", "B", "B", "B"},
10
);
JTable table = new JTable(model);
counter = new JLabel("0");
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem viewProfile = new JMenuItem("View Profile");
viewProfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
popupMenu.add(viewProfile);
table.setComponentPopupMenu(popupMenu);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("clicked");
count++;
counter.setText(String.valueOf(count));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(counter, BorderLayout.NORTH);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
A actual runnable example that demonstrates your problem would involve less guess work and better responses
I had exactly the same problem when closing JMenuBar popups, and this worked for me:
UIManager.put("PopupMenu.consumeEventOnClose", false);

Categories