When I add a MouseListener/FocusListener to a JPanel which has a BorderLayout and JComponents in it, I can't catch mouse or focus events. Is there any way to catch a JPanel's mouse and focus events which has a BorderLayout?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Application extends JFrame{
public Application(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jPanel = new JPanel(new BorderLayout());
jPanel.add(new JButton("Button"));
jPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited");
}
});
// if border is set then listener works if not does not
// jPanel.setBorder(new LineBorder(Color.black, 1));
setLayout(new FlowLayout());
add(jPanel);
setSize(400, 400);
setVisible(true);
}
public static void main(String[]args){
new Application().setVisible(true);
}
}
As said, just a simple mistake. Because JFrame is given a FlowLayout, the JPanel occupies the area required for JButton only. You can test that by adding a Border to the JPanel.
Now it works,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Application extends JFrame {
private static final long serialVersionUID = 1L;
public Application() {
JPanel jPanel = new JPanel();
jPanel.setLayout(new FlowLayout());
jPanel.add(new JButton("Button"));
jPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited");
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(jPanel);
setSize(400, 400);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Application().setVisible(true);
}
});
}
}
The following Code prints the corresponding Events to StdOut.
JFrame frame = new JFrame();
JPanel panel = new JPanel(new BorderLayout());
JPanel innerPanel = new JPanel();
innerPanel.setSize(200,200);
panel.add(innerPanel);
panel.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {
System.out.println("MouseReleased");
}
public void mousePressed(MouseEvent e) {
System.out.println("MousePressed");
}
public void mouseExited(MouseEvent e) {
System.out.println("MouseExited");
}
public void mouseEntered(MouseEvent e) {
System.out.println("MouseEntered");
}
public void mouseClicked(MouseEvent e) {
System.out.println("MouseClicked");
}
});
frame.setContentPane(panel);
frame.setVisible(true);`
Related
I'm trying to move around jframe on the window through an event triggered from an external jpanel class, my code is below, but the doesn't achieve this. Instead the panel is the one that's moving around.
What am I doing wrong here? I am new programming in general.
package casuls_app;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Titlebar extends JPanel {
public Titlebar() {
btnClose =new JButton("X");
btnClose.setFocusable(false);
btnClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
closeButtonPressed(e);
}
}
);
controlBox =new JPanel(new GridLayout(1,1));
controlBox.setPreferredSize(new Dimension(150,40));
controlBox.add(btnClose);
controlBox.setBackground(new Color(255,255,255));
setLayout(new BorderLayout());
add(controlBox,BorderLayout.EAST);
setPreferredSize(new Dimension(0,40));
setBackground(new Color(60, 173, 205));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
mousePressedOnTitlebar(e);
}
}
);
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
mouseDraggedOnTitlebar(e);
}
}
);
}
private void mousePressedOnTitlebar(MouseEvent e) {
posX= e.getX();
posY=e.getY();
}
private void mouseDraggedOnTitlebar(MouseEvent e) {
setLocation(e.getXOnScreen() -posX, e.getYOnScreen() -posY);
}
private void closeButtonPressed(ActionEvent e){
System.exit(0);
}
//Variables declaration
private int posX,posY;
private JButton btnClose;
private JPanel controlBox;
}
setLocation() sets the location of your JPanel (because your class extends JPanel).
If you have a reference to the JFrame, you can call the setLocation method on that object.
frame.setLocation(x, y);
If you don't have the reference, then you can follow this post which accesses the frame via SwingUtilities:
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
I'm trying to close a JPanel that's on top of my JFrame.
Now I want to close this panel by clicking a button that's on top of this panel and open another panel on the same frame.
All my panels and my frame is in a separated class.
Here is my idea:
JFrame Class
public MainFrame() throws IOException {
InitializeStartScreen();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setLocationRelativeTo(null);
this.setIconImage(FrameTopIcon.getImage());
this.setTitle("test");
this.setVisible(true);
}
private void InitializeStartScreen() {
StartPanel startPNL = new StartPanel();
this.add(startPNL);
// pack();
}
public static void main(String args[]) throws IOException {
try {
new MainFrame();
}
catch (IOException e) {
throw e;
}
}
JPanel Class
import javax.swing.*;
import java.awt.*;
public class StartPanel extends JPanel {
private LabelButtonCategory Button1 = new LabelButtonCategory("test");
public StartPanel() {
this.setLayout(new GridBagLayout());
InitializeLabelButtons();
this.setBackground(backgroundColor);
this.add(gridPanel);
this.setVisible(true);
}
private void InitializeLabelButtons() {
button1Panel.setBackground(backgroundColor);
ImageIcon iconBtn1 = new ImageIcon("./src/images/CreateBill.png");
Button1.setIcon(iconBtn1);
Button1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
Button1MouseClicked(evt);
}
public void mouseEntered(java.awt.event.MouseEvent evt) {
Button1MouseEntered(evt);
}
public void mouseExited(java.awt.event.MouseEvent evt) {
Button1MouseExited(evt);
}
});
button1Panel.add(Button1);
gridPanel.add(button1Panel);
private void Button1MouseClicked(java.awt.event.MouseEvent evt) {
// CLOSE THIS PANEL AND OPEN ANOTHER PANEL ON FRAME
}
How do I put a button on the border that surrounds the frame like this cog:
_"Is the a short example anywhere? "
Yea, here... This very basic. You need to do alot more to it. You'll notice I have to add a MouseMotionListener to the JPanel that acts as the top frame border, because when you remove the decoration from the frame, you're also taking away that functionality. So the MouseMotionListener makes the frame draggable again.
You would also have to implement resizing if you wished. I already implemented the Systemexit()` when you press the image. Test it out. You need to provide your own image.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class UndecoratedExample {
static JFrame frame = new JFrame();
static class MainPanel extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
static class BorderPanel extends JPanel {
JLabel stackLabel;
int pX, pY;
public BorderPanel() {
ImageIcon icon = new ImageIcon(getClass().getResource(
"/resources/stackoverflow1.png"));
stackLabel = new JLabel();
stackLabel.setIcon(icon);
setBackground(Color.black);
setLayout(new FlowLayout(FlowLayout.RIGHT));
add(stackLabel);
stackLabel.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
System.exit(0);
}
});
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
// Get x,y and store them
pX = me.getX();
pY = me.getY();
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent me) {
frame.setLocation(frame.getLocation().x + me.getX() - pX,
frame.getLocation().y + me.getY() - pY);
}
});
}
}
static class OutsidePanel extends JPanel {
public OutsidePanel() {
setLayout(new BorderLayout());
add(new MainPanel(), BorderLayout.CENTER);
add(new BorderPanel(), BorderLayout.PAGE_START);
setBorder(new LineBorder(Color.BLACK, 5));
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setUndecorated(true);
frame.add(new OutsidePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I need to be able to change the size of an JPanel in a event function and then get the size again. It seems that the JPanel is not updated untill the function call has been finished. How can I get the real size? This is an SSCCE:
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener{
JPanel p;
Test(){
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000,1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
p = new JPanel();
p.setPreferredSize(new Dimension(200,200));
p.setBackground(Color.red);
add(p);
addMouseWheelListener(this);
pack();
}
public static void main(String args[]){
new Test();
}
public void mouseWheelMoved(MouseWheelEvent e) {
System.out.println(p.getSize());
p.setPreferredSize(new Dimension(100,100));
p.revalidate();
System.out.println(p.getSize());
}
}
The code works fine, but it prints the following in the console if I scroll the mouse one step:
java.awt.Dimension[width=200,height=200]
java.awt.Dimension[width=200,height=200]
I want it to print:
java.awt.Dimension[width=200,height=200]
java.awt.Dimension[width=100,height=100]
your code works for me, but working only on mouse wheel event, you have to scroll with mouse wheel
modified example
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener {
private static final long serialVersionUID = 1L;
private JPanel p;
public Test() {
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000, 1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel();
p.setPreferredSize(new Dimension(200, 200));
p.setBackground(Color.red);
add(p);
addMouseWheelListener(this);
pack();
setVisible(true);
}
public void mouseWheelMoved(MouseWheelEvent e) {
Dimension dim100 = new Dimension(100, 100);
Dimension dim200 = new Dimension(200, 200);
System.out.println(p.getSize());
if (p.getPreferredSize().equals(dim100)) {
p.setPreferredSize(dim200);
p.revalidate();
System.out.println(p.getSize());
} else if (p.getPreferredSize().equals(dim200)) {
p.setPreferredSize(dim100);
p.revalidate();
System.out.println(p.getSize());
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}
EDIT:
have to delay System.out.println(p.getSize());, invokeLater() is best of all in this case, becase container returned changed Dimension after all events are done in the EDT
example
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame implements MouseWheelListener {
private static final long serialVersionUID = 1L;
private JPanel p;
public Test() {
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000, 1000));
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel();
p.setPreferredSize(new Dimension(900, 900));
p.setBackground(Color.red);
add(p);
addMouseWheelListener(this);
pack();
setVisible(true);
}
public void mouseWheelMoved(MouseWheelEvent e) {
Dimension dim100 = p.getSize();
System.out.println("before "+ p.getSize());
p.setPreferredSize(new Dimension(dim100.height - 5, dim100.width - 5));
p.revalidate();
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
System.out.println("after "+ p.getSize());
}
});
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}
generated
before java.awt.Dimension[width=900,height=900]
after java.awt.Dimension[width=895,height=895]
before java.awt.Dimension[width=895,height=895]
after java.awt.Dimension[width=890,height=890]
before java.awt.Dimension[width=890,height=890]
after java.awt.Dimension[width=885,height=885]
before java.awt.Dimension[width=885,height=885]
after java.awt.Dimension[width=880,height=880]
before java.awt.Dimension[width=880,height=880]
after java.awt.Dimension[width=875,height=875]
before java.awt.Dimension[width=875,height=875]
after java.awt.Dimension[width=870,height=870]
before java.awt.Dimension[width=870,height=870]
after java.awt.Dimension[width=865,height=865]
before java.awt.Dimension[width=865,height=865]
after java.awt.Dimension[width=860,height=860]
Don't you need to call paint() too, to the size change?
I am trying to view a JApplet within a JFrame.
Class: Paint
public void paint(Graphics g) {
g.drawString("hi", 50, 50);
}
public static void main(String args[]) {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(methodThatReturnsJMenuBar());
JPanel panel = new JPanel(new BorderLayout());
frame.add(panel);
JApplet applet = new Paint();
panel.add(applet, BorderLayout.CENTER);
applet.init();
frame.pack();
frame.setVisible(true);
}
The applet shows up in the Window, but there is no background (it's transparent), and when I click on the Menu, the list is covered. How do I make it so that the Menu list isn't covered, and there is a background?
Edit: When I draw a white rectangle, it fixes the background problem, but the Menu list is still covered.
I would gear my GUI creation towards making a JPanel and then use the JPanel as I desire, either in an JApplet or a JFrame. For e.g.,
import java.awt.*;
import javax.swing.*;
public class MyPanel extends JPanel {
private static final Dimension PREF_SIZE = new Dimension(400, 300);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("hi", 50, 50);
}
#Override
public Dimension getPreferredSize() {
return PREF_SIZE;
}
public JMenuBar methodThatReturnsJMenuBar() {
JMenu menu = new JMenu("Menu");
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
return menuBar;
}
}
Then to use in an applet:
import javax.swing.JApplet;
public class MyApplet extends JApplet {
public void init() {
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}
}
private void createGUI() {
getContentPane().add(new MyPanel());
}
}
Or in a JFrame:
import javax.swing.JFrame;
public class MyStandAlone {
private static void createAndShowUI() {
MyPanel myPanel = new MyPanel();
JFrame frame = new JFrame("MyPanel");
frame.getContentPane().add(myPanel);
frame.setJMenuBar(myPanel.methodThatReturnsJMenuBar());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}