The following code below shows an internal frame listener for the Gui class. The internal frame listener should either set the save (JMenuItem) as enable or disabled but it does nothing. I don't know where the problem is. I have tried a couple of things but nothing works.
Here is the code:
public class Gui implements InternalFrameListener, ActionListener{
MyInternalFrame frame;
JMenuItem save;
public Gui( JDesktopPane desktop, final JMenuItem save) {
// TODO Auto-generated constructor stub
frame = new MyInternalFrame(title, img);
this.save = save;
frame.setVisible(true);
desktop.add(frame);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
frame.addInternalFrameListener(this);
// options(name, desktop);
}
class MyInternalFrame extends JInternalFrame {
static final int xPosition = 30, yPosition = 30;
public MyInternalFrame(String title, ImagePlus img) {
super(title, true,true, true, true);
setSize(img.getHeight(), img.getWidth());
// Set the window's location.
setLocation(xPosition * openFrameCount, yPosition * openFrameCount);
}
}
public void actionPerformed(ActionEvent e){
frame.addInternalFrameListener(this);
System.out.println("beingg called");
}
#Override
public void internalFrameActivated(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(true);
}
#Override
public void internalFrameClosed(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(false);
}
#Override
public void internalFrameClosing(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(false);
}
#Override
public void internalFrameDeactivated(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(false);
}
#Override
public void internalFrameDeiconified(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(true);
}
#Override
public void internalFrameIconified(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(false);
}
#Override
public void internalFrameOpened(InternalFrameEvent arg0) {
// TODO Auto-generated method stub
save.setEnabled(true);
}
}
A MCVE showing that this is working in general. My guess would be that you are using a wrong instance of the save menu item. In doubt, add debug output
#Override
public void internalFrameIconified(InternalFrameEvent arg0)
{
System.out.println("Disabling "+save);
save.setEnabled(false);
}
to your methods.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
public class InternalFrameListenerTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridLayout(1, 1));
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menubar.add(menu);
JMenuItem menuItem = new JMenuItem("Save");
menu.add(menuItem);
frame.setJMenuBar(menubar);
JDesktopPane d = new JDesktopPane();
Gui gui = new Gui(d, menuItem);
frame.getContentPane().add(d);
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class Gui implements InternalFrameListener, ActionListener
{
MyInternalFrame frame;
JMenuItem save;
public Gui(JDesktopPane desktop, final JMenuItem save)
{
frame = new MyInternalFrame("Title");
this.save = save;
frame.setVisible(true);
desktop.add(frame);
try
{
frame.setSelected(true);
}
catch (java.beans.PropertyVetoException e)
{
}
frame.addInternalFrameListener(this);
}
class MyInternalFrame extends JInternalFrame
{
static final int xPosition = 30, yPosition = 30;
public MyInternalFrame(String title)
{
super(title, true, true, true, true);
setSize(200,100);
setLocation(50,50);
}
}
public void actionPerformed(ActionEvent e)
{
frame.addInternalFrameListener(this);
System.out.println("beingg called");
}
#Override
public void internalFrameActivated(InternalFrameEvent arg0)
{
save.setEnabled(true);
}
#Override
public void internalFrameClosed(InternalFrameEvent arg0)
{
save.setEnabled(false);
}
#Override
public void internalFrameClosing(InternalFrameEvent arg0)
{
save.setEnabled(false);
}
#Override
public void internalFrameDeactivated(InternalFrameEvent arg0)
{
save.setEnabled(false);
}
#Override
public void internalFrameDeiconified(InternalFrameEvent arg0)
{
save.setEnabled(true);
}
#Override
public void internalFrameIconified(InternalFrameEvent arg0)
{
save.setEnabled(false);
}
#Override
public void internalFrameOpened(InternalFrameEvent arg0)
{
save.setEnabled(true);
}
}
Related
This question already has answers here:
Keylistener not working for JPanel
(4 answers)
Closed 8 months ago.
I am trying to add a JPanel to a JFrame. The JPanel is supposed to listen to keyboard input and mouse input. When i open the window it does work for the mouse but the keyboard gets ignored and i just can't see the problem, since i wrote the same stuff for both Listeners.
This is the code for the Panel
public class testjpanel extends JPanel implements MouseListener,KeyListener {
testjpanel (){
this.addMouseListener(this);
this.addKeyListener(this);
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
System.out.println(1);
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println(1);
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
and here is the rest
public class main extends JFrame {
public main() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500,500);
this.setVisible(true);
this.setLayout(null);
testjpanel a= new testjpanel();
a.setVisible(true);
a.setBounds(0,0,500,500);
a.setLayout(null);
this.add(a);
}
}
This is a rather non-standard way to use a keyboard or mouse listener. A better, consistently reliable way is as follows.
Create a class to be your MouseManager:
public class MouseManager implements MouseListener {
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
And the Keyboard Manager:
public class KeyboardManager implements KeyListener {
#Override
public void keyPressed(KeyEvent arg0) {
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
After this, all you have to do is add them to your window like this below example:
public class MyFrame extends JFrame {
public MyFrame() {
this.setTitle("Your title");
this.setSize(new Dimension(500, 500));
this.addMouseListener(new MouseManager())
this.addKeyListener(new KeyboardManager());
}
}
Having the keyboard and mouse managers/listener in their own classes keeps things tidy and makes them easier to work with; for functionality, add them to the JFrame instead of your JPanel.
I am trying to capture the moment a user finished resizing a JFrame through the mouse drag of a frame corner. I have so far found the below options, but they both print BLAH again and again until I am done stretching the window size. I only want it to print BLAH once I released the mouse after the continuous dragging of the JFrame corner resizing it. Any thoughts?
frame.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
System.out.println("BLAH");
}
});
AND
frame.addComponentListener(new ComponentListener() {
#Override
public void componentShown(ComponentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void componentResized(ComponentEvent e) {
// TODO Auto-generated method stub
System.out.println("BLAH");
}
#Override
public void componentMoved(ComponentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void componentHidden(ComponentEvent e) {
// TODO Auto-generated method stub
}
}
);
The core problem is, you're unlikely to be able to detect when a mouse event occurs on the frame decorations, as it tends to be handled at a much lower level.
One trick I've used in the past, is to use a short lived, single run, Swing Timer, which is restarted each time componentResized is called. This means that the Timer will only trigger AFTER a "short delay" after componentResized stops been called, for example
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
private Timer resizeTimer;
public TestPane() {
setLayout(new GridBagLayout());
label = new JLabel(".......");
add(label);
addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
if (resizeTimer == null) {
resizeTimer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.setText(getSize().width + "x" + getSize().getHeight());
resizeTimer.stop();
resizeTimer = null;
}
});
resizeTimer.setRepeats(false);
}
resizeTimer.restart();
}
});
}
}
}
I want to create a class that implement mouseListener interface (this class will override all mouseListener methods) instead of override all the methods in the main class. When I tring to do so I get an error.
This is my code:
import javax.swing.*;
public class Game {
public Game(){
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addMouseListener(new MyMouseListener());
}
public static void main(String[] args) {
Game app = new Game();
}
}
MyMouseListener code:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MyMouseListener implements KeyListener{
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
edit: I understand my problem was that I implement keyListener insteed of mouseListener in the class MyMouseListener so I changed this and MyMouseListener code is now:
public class MyMouseListener extends Game implements MouseListener{
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
The problem you might be having is the frame not showing up, this is because you did not tell it to show the frame, use the following method:
frame.setVisible(true);
In addition as stated by Jorn Vernee, in your class MyMouseListener you have to implement the MouseListener interface instead of the KeyListener.
I tried this code out and it worked just fine:
import javax.swing.JFrame;
public class Game {
public Game(){
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addMouseListener(new MyMouseListener());
frame.setVisible(true);
}
public static void main(String[] args) {
Game app = new Game();
}
}
Code for MyMouseListener:
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MyMouseListener implements MouseListener{
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("clicked");
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
I want to change my blankCardPic to clubsAcePic after I clicked on the blankCardPic and after 2 seconds, it will change back from clubsAcePic to blankCardPic. I know it could be easily done by using JLabels but I want to learn how to use paintComponent to do it.
Right now, when I clicked on the blankCardPic it does not change to clubsAcesPic.
Please help. thank you.
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GameUI extends JPanel implements MouseListener {
/**
*
*/
private static final long serialVersionUID = 8525183729697452509L;
private boolean clicked = false;
private JFrame frame;
private BufferedImage blankCardPic;
private BufferedImage clubsAcePic;
public GameUI() {
loadImages();
frame = new JFrame();
frame.setContentPane(this);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
public static void main(String[] args) {
new GameUI();
}
public void loadImages() {
try {
blankCardPic = ImageIO.read(getClass().getResourceAsStream("resources/images/blank.png"));
clubsAcePic = ImageIO.read(getClass().getResourceAsStream("resources/images/clubsAce.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage blankCard() {
try {
blankCardPic = ImageIO.read(new File("resources/images/blank.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return blankCardPic;
}
public BufferedImage revealClubsAce() {
try {
clubsAcePic = ImageIO.read(new File("resources/images/clubsAce.png"));
} catch (IOException e) {
e.printStackTrace();
}
return clubsAcePic;
}
private void render(Graphics g) {
if (!clicked) {
g.drawImage(blankCardPic, 100,100, null);
} else {
g.drawImage(clubsAcePic, 100,100, null);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
render(g);
Toolkit.getDefaultToolkit().sync();
}
#Override
public void mouseClicked(MouseEvent e) {
setFocusable(true);
requestFocus();
addMouseListener(this);
if(e.getButton() == MouseEvent.BUTTON1) {
clicked = true;
repaint();
}
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
clicked = false;
}
});
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
I have written the following code to handle an event incase a Jinternalframe is minimized or maximized.
jif.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
Boolean isMax = ((JInternalFrame)e.getComponent()).isMaximum();
if(isMax == false)
{
// TODO Auto-generated method stub
}
else if(isMax == true )
{
// TODO Auto-generated method stub
}
}
public void componentMoved(ComponentEvent e) {
// TODO Auto-generated method stub
}
public void componentShown(ComponentEvent e) {
// TODO Auto-generated method stub
}
public void componentHidden(ComponentEvent e) {
// TODO Auto-generated method stub
}
}
);
The problem is that the isMax part gets triggered when the frame loads. I want this event to happen only after the Jinternalframe is completely loaded. Also i have noticed this event triggers when i minimize the container applet.
Is there any workaround for this?
You might be able to use a PropertyChangeListener and InternalFrameListener:
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
public class InternalFrameEventTest {
public JComponent makeUI() {
final JDesktopPane desktop = new JDesktopPane();
JPanel p = new JPanel(new BorderLayout());
p.add(desktop);
p.add(new JButton(new AbstractAction("New") {
#Override public void actionPerformed(ActionEvent e) {
JInternalFrame f = new JInternalFrame("title", true, true, true, true);
InternalFrameHandler handler = new InternalFrameHandler();
f.addInternalFrameListener(handler);
f.addPropertyChangeListener(handler);
f.setSize(240, 120);
f.setVisible(true);
desktop.add(f);
}
}), BorderLayout.NORTH);
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new InternalFrameEventTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class InternalFrameHandler implements PropertyChangeListener, InternalFrameListener {
//PropertyChangeListener
#Override public void propertyChange(PropertyChangeEvent e) {
if (JInternalFrame.IS_MAXIMUM_PROPERTY.equals(e.getPropertyName())) {
System.out.println("isMaximum: " + e.getNewValue());
}
}
//InternalFrameListener
#Override public void internalFrameClosing(InternalFrameEvent e) {
System.out.println("internalFrameClosing");
}
#Override public void internalFrameClosed(InternalFrameEvent e) {
System.out.println("internalFrameClosed");
}
#Override public void internalFrameOpened(InternalFrameEvent e) {
System.out.println("internalFrameOpened");
}
#Override public void internalFrameIconified(InternalFrameEvent e) {
System.out.println("internalFrameIconified");
}
#Override public void internalFrameDeiconified(InternalFrameEvent e) {
System.out.println("internalFrameDeiconified");
if (e.getInternalFrame().isMaximum()) {
System.out.println("isMaximum: " + e.getInternalFrame().isMaximum());
}
}
#Override public void internalFrameActivated(InternalFrameEvent e) {
System.out.println("internalFrameActivated");
}
#Override public void internalFrameDeactivated(InternalFrameEvent e) {
System.out.println("internalFrameDeactivated");
}
}