Here's description of my problem (in one picture!):
I would like to know:
1.) Why this is happening (I have even tried to setMaximumSize(), setPreferredSize(), setMinimumSize()!)?
2.) How I should resolve this? (I used GridLayout. It may or may not be super effective)
This is the setup code:
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.CardLayout;
import java.awt.Dimension;
public class IntroScreen extends JFrame implements ActionListener
{
private boolean sandboxed = true;
private final String SELECTION = "selection", CLEAN = "clean";
private JPanel container;
private DirectorySelectionPanel selectionPanel;
private DirectoryCleanerPanel cleanerPanel;
public IntroScreen()
{
super("Directory Cleaner");
add((container = setupContent()));
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
JOptionPane.showMessageDialog(this, this.getSize());
}
private JPanel setupContent()
{
JPanel content = new JPanel(new CardLayout());
this.selectionPanel = new DirectorySelectionPanel(this.sandboxed);
this.selectionPanel.getButton().addActionListener(this);
content.add(this.selectionPanel, this.SELECTION);
this.cleanerPanel = new DirectoryCleanerPanel(false);
content.add(this.cleanerPanel, this.CLEAN);
return content;
}
#Override
public void actionPerformed(ActionEvent event)
{
// get the source of the event
Object source = event.getSource();
// if it was the selectionPanel's button
if (source.equals(this.selectionPanel.getButton()))
{
if (this.selectionPanel.validateSelections())
{
System.out.println("Test line");
((CardLayout)this.container.getLayout()).show(this.container, this.CLEAN);
// must figure out the correct size for this
// TODO: Find a way to force the size of this to be around 450-by-90 pixels
this.setSize(450,90);
}
}
// otherwise
else
{
// show the selectionPanel
this.setSize(312,253); // revert back to the original size
}
}
public static void main(String[] args)
{
new IntroScreen();
}
}
Related
I'm trying to make a window that switches between pics when the button "change" is pressed. When I'm trying to run the program, the Java logo pops up like the program is about to start, but then it just disappear. I'm kind of stuck now and I'm hoping that someone can give me a hint about what might be wrong.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.imageio.*;
import javax.swing.*;
public class ImageViewer extends JFrame{
private JPanel panel;
private JLabel imageLabel;
private JButton button;
private Icon[] icons = {};
private static final long serialVersionUID = 1L;
public ImageViewer() {
try {
panel = new JPanel();
URL url1 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Teatern.jpg");
URL url2 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Vetenskapens-hus.jpg");
Icon image = new ImageIcon(ImageIO.read(url1));
Icon image2 = new ImageIcon(ImageIO.read(url2));
icons[0] = image;
icons[1] = image2;
imageLabel = new JLabel();
panel.add(button);
panel.add(imageLabel);
button = new JButton("Change");
button.addActionListener(new ActionListener() {
private boolean value = false;
{
}
public void actionPerformed(ActionEvent arg0) {
value = value == true ? false : true;
if (value == false) {
imageLabel.setIcon(icons[0]);
}else {
imageLabel.setIcon(icons[1]);
}
}
});
this.setContentPane(panel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}catch (Exception e) {
}
}
public static void main(String args[]) {
new ImageViewer();
}
}
First, here's what I created to give you some hints.
And here's the code. The hints will follow after the code.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ImageViewer implements Runnable {
private boolean isImage1;
private BufferedImage image;
private ImageData imageData;
private JLabel label;
public static void main(String args[]) {
SwingUtilities.invokeLater(new ImageViewer());
}
public ImageViewer() {
this.imageData = new ImageData();
this.image = imageData.getImage1();
this.isImage1 = true;
}
#Override
public void run() {
JFrame frame = new JFrame("Image Viewer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
label = new JLabel(new ImageIcon(image));
panel.add(label);
JButton button = new JButton("Change");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (isImage1) {
image = imageData.getImage2();
} else {
image = imageData.getImage1();
}
label.setIcon(new ImageIcon(image));
isImage1 = !isImage1;
}
});
panel.add(button);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public class ImageData {
private BufferedImage image1;
private BufferedImage image2;
public ImageData() {
URL url1;
URL url2;
try {
url1 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Teatern.jpg");
url2 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Vetenskapens-hus.jpg");
this.image1 = readImage(url1);
this.image2 = readImage(url2);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private BufferedImage readImage(URL url) {
try {
return ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public BufferedImage getImage1() {
return image1;
}
public BufferedImage getImage2() {
return image2;
}
}
}
So here are the hints.
Do not extend JFrame, or any Swing component, unless you intend to override one or more of the class methods.
Always start your Swing project on the Event Dispatch Thread (EDT). I implemented Runnable in the main ImageViewer class for convenience. Your main method should always contain a call to SwingUtilities invokeLater.
I moved the reading of the images to its own data class. Always separate the data from the view. I usually use the model / view / controller architecture to create a Swing project.
I checked for errors in the URLs or the actual image reading. If an error had occurred, it would have printed a stack trace which would have helped me find the error. Never enclose whole methods in a try-catch block.
The only Swing component that needed to be a class variable was the JLabel component. Only make the class variables that you need for the whole class. My habit is to make all the class variables private, as well as the class methods. Only expose the methods that need to be exposed.
Once I did all these things, writing the action listener was trivial.
I have discovered class javax.swing.Popup. I wrote code to test its behavior. Code is shown below. When I run the code, after the JFrame is displayed, I click the SHOW button and the Popup is displayed. After that I click the HIDE button and the Popup disappears. But then if I click the SHOW button again, nothing happens. The Popup only appears after clicking the SHOW button for the first time. Also, if I click the HIDE button first, before clicking the SHOW button, then when I click the SHOW button, the Popup does not appear.
Am I missing something?
Am I doing something wrong?
I admit I haven't investigated this behavior. I haven't searched the Internet and I haven't looked at the code for class Popup nor PopupFactory, simply due to laziness and in the hope that someone can explain it to me.
Here is my MCVE.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
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.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
public class PopupTest implements ActionListener, Runnable {
private static final String HIDE = "HIDE";
private static final String SHOW = "SHOW";
private Popup popup;
public void actionPerformed(ActionEvent actionEvent) {
String actionCommand = actionEvent.getActionCommand();
switch (actionCommand) {
case HIDE:
popup.hide();
break;
case SHOW:
popup.show();
break;
}
}
public void run() {
showGui();
}
private void showGui() {
JFrame frame = new JFrame("Popup");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JLabel centerLabel = new JLabel("CENTER LABEL", SwingConstants.CENTER);
frame.add(centerLabel, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
JButton showButton = new JButton(SHOW);
showButton.addActionListener(this);
buttonsPanel.add(showButton);
JButton hideButton = new JButton(HIDE);
hideButton.addActionListener(this);
buttonsPanel.add(hideButton);
frame.add(buttonsPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
JLabel popupLabel = new JLabel("Popup_Label");
PopupFactory factory = PopupFactory.getSharedInstance();
Point pt = centerLabel.getLocationOnScreen();
int x = pt.x + 10;
int y = pt.y - 10;
popup = factory.getPopup(centerLabel, popupLabel, x, y);
}
public static void main(String[] args) {
PopupTest instance = new PopupTest();
EventQueue.invokeLater(instance);
}
}
https://docs.oracle.com/javase/7/docs/api/javax/swing/Popup.html#hide()
The documentation that you have chosen not to read is very clear that hide() disposes of the Popup and any further method calls on that Popup will result in indeterminate behaviour.
You must create a new Popup instance each time.
From the docs for hide():
"Hides and disposes of the Popup. Once a Popup has been disposed you
should no longer invoke methods on it. A disposed Popup may be
reclaimed and later used based on the PopupFactory."
As such, here is a quick and dirty modified version that works.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
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.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
public class PopupTest implements ActionListener, Runnable {
private static final String HIDE = "HIDE";
private static final String SHOW = "SHOW";
private Popup popup;
private JLabel centerLabel;
private JLabel popupLabel = new JLabel("Popup_Label");
private PopupFactory factory = PopupFactory.getSharedInstance();
public void actionPerformed(ActionEvent actionEvent) {
String actionCommand = actionEvent.getActionCommand();
switch (actionCommand) {
case HIDE:
if (popup == null) {
return;
}
popup.hide();
popup = null; // necessary to avoid using the disposed popup
break;
case SHOW:
if (popup != null) { // it's already showing
return;
}
Point pt = centerLabel.getLocationOnScreen();
int x = pt.x + 10;
int y = pt.y - 10;
popup = factory.getPopup(centerLabel, popupLabel, x, y);
popup.show();
break;
}
}
public void run() {
showGui();
}
private void showGui() {
JFrame frame = new JFrame("Popup");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
centerLabel = new JLabel("CENTER LABEL", SwingConstants.CENTER);
frame.add(centerLabel, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
JButton showButton = new JButton(SHOW);
showButton.addActionListener(this);
buttonsPanel.add(showButton);
JButton hideButton = new JButton(HIDE);
hideButton.addActionListener(this);
buttonsPanel.add(hideButton);
frame.add(buttonsPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
PopupTest instance = new PopupTest();
EventQueue.invokeLater(instance);
}
}
I didn't really know how else to phrase that but essentially:
-I have a few separate "pieces" that I am trying to add onto a master frame; to keep the code from getting unwieldy I have each "piece" be its own class.
-I'm getting stuck on adding the panells onto the master frame, because the classes themselves aren't panels, rather the method of the class creates the panel, which creates issues that I don't know how to solve.
PIECE (works on its own when I have it make a dialog instead of be a panel):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PieceThing3 extends JPanel //<switched from JDialog
{
//set up variables here
private ActionListener pieceAction = new ActionListener()
{
public void actionPerformed (ActionEvent ae)
{
// Action Listener (this also works)
}
};
private void createPiece()
{
//setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//setLocationByPlatform(true);
// the above are commented out when I switch from dialog to panel
JPanel contentPane = new JPanel();
//something that uses pieceAction is here
//two buttons, b and s, with action listeners are here
contentPane.add(b);
contentPane.add(s);
add(contentPane);
//pack();
//again, commented out to switch from dialog
setVisible(true);
System.out.println("hi I'm done");
//just to check and make sure it's done
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PieceThing3().createPiece();
}
});
}
}
Sorry that is very vague, but the intricacies are not as important as the general idea - it works perfectly when I have it create its own dialog box, but now I am trying to get it to make a panel within a master code, below:
MASTER:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CollectGUI extends JFrame{
private void createDialog(){
this.setSize(2000,1000);
this.setLocation(0,0);
this.setTitle("TITLE");
PieceThing3 pt = new PieceThing3();
//HERE, if I do pt.main(null); while it is in "dialog mode" (rather than panel) it pops up a dialog box and everything is hunky dory. But I don't know how to get it to add the method as a panel.
this.add(pt.main(null));
//this gives an error
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new CollectGUI().createDialog();
}
}
As I said in the comments, if I just do pt.main(null) when pt is set to make a dialog, it does it, but if I try to add pt.main(null) as a panel it throws an error. Can anybody give me some insight on how to add a method of a class rather than a class? I'm pretty stumped.
THANK YOU!!
You are definitely on the right track working to maintain separation of concerns and implement your gui in a number of distinct components. Try something like this:
Panel1
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
public Panel1() {
this.add(new JLabel("This is panel 1"));
}
}
Panel2
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Panel2 extends JPanel {
public Panel2() {
this.add(new JLabel("This is panel 2"));
}
}
JFrame
import java.awt.BorderLayout;
import javax.swing.JFrame;
import org.yaorma.example.jframe.panel.panel1.Panel1;
import org.yaorma.example.jframe.panel.panel2.Panel2;
public class ExampleJFrame extends JFrame {
public ExampleJFrame() {
super("Example JFrame Application");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400,400);
this.setLayout(new BorderLayout());
Panel1 pan1 = new Panel1();
Panel2 pan2 = new Panel2();
this.add(pan1, BorderLayout.NORTH);
this.add(pan2, BorderLayout.SOUTH);
this.setVisible(true);
}
}
main:
public class ExampleApplication {
public static void main(String[] args) throws Exception {
new ExampleJFrame();
}
}
EDIT:
Here's a Panel1 with a little more content.
import java.awt.BorderLayout;
import java.awt.Container;
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 org.yaorma.example.action.sayhello.SayHelloAction;
public class Panel1 extends JPanel {
//
// instance variables
//
private JButton pressMeButton;
//
// constructor
//
public Panel1() {
this.setLayout(new BorderLayout());
this.add(new JLabel("This is panel 1"), BorderLayout.NORTH);
this.initPressMeButton();
}
//
// button
//
private void initPressMeButton() {
this.pressMeButton = new JButton("Press Me");
this.pressMeButton.addActionListener(new PressMeButtonActionListener());
this.add(pressMeButton, BorderLayout.SOUTH);
}
//
// method to get the parent jframe
//
private JFrame getParentJFrame() {
Container con = this;
while(con != null) {
con = con.getParent();
if(con instanceof JFrame) {
return (JFrame)con;
}
}
return null;
}
//
// action listener for Press Me button
//
private class PressMeButtonActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JFrame jFrame = getParentJFrame();
SayHelloAction action = new SayHelloAction(jFrame);
action.execute();
}
}
}
Action called by button:
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class SayHelloAction {
private JFrame owner;
public SayHelloAction(JFrame owner) {
this.owner = owner;
}
public void execute() {
JOptionPane.showMessageDialog(owner, "Hello World");
}
}
a basic problem that i can't figure out, tried a lot of things and can't get it to work, i need to be able to get the value/text of the variable
String input;
so that i can use it again in a different class in order to do an if statement based upon the result
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class pInterface extends JFrame {
String input;
private JTextField item1;
public pInterface() {
super("PAnnalyser");
setLayout(new FlowLayout());
item1 = new JTextField("enter text here", 10);
add(item1);
myhandler handler = new myhandler();
item1.addActionListener(handler);
System.out.println();
}
public class myhandler implements ActionListener {
// class that is going to handle the events
public void actionPerformed(ActionEvent event) {
// set the variable equal to empty
if (event.getSource() == item1)// find value in box number 1
input = String.format("%s", event.getActionCommand());
}
public String userValue(String input) {
return input;
}
}
}
You could display the window as a modal JDialog, not a JFrame and place the obtained String into a private field that can be accessed via a getter method. Then the calling code can easily obtain the String and use it. Note that there's no need for a separate String field, which you've called "input", since we can easily and simply extract a String directly from the JTextField (in our "getter" method).
For example:
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.*;
import javax.swing.text.JTextComponent;
public class TestPInterface {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final JFrame frame = new JFrame("TestPInterface");
// JDialog to hold our JPanel
final JDialog pInterestDialog = new JDialog(frame, "PInterest",
ModalityType.APPLICATION_MODAL);
final MyPInterface myPInterface = new MyPInterface();
// add JPanel to dialog
pInterestDialog.add(myPInterface);
pInterestDialog.pack();
pInterestDialog.setLocationByPlatform(true);
final JTextField textField = new JTextField(10);
textField.setEditable(false);
textField.setFocusable(false);
JPanel mainPanel = new JPanel();
mainPanel.add(textField);
mainPanel.add(new JButton(new AbstractAction("Get Input") {
#Override
public void actionPerformed(ActionEvent e) {
// show dialog
pInterestDialog.setVisible(true);
// dialog has returned, and so now extract Text
textField.setText(myPInterface.getText());
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// by making the class a JPanel, you can put it anywhere you want
// in a JFrame, a JDialog, a JOptionPane, another JPanel
#SuppressWarnings("serial")
class MyPInterface extends JPanel {
// no need for a String field since we can
// get our Strings directly from the JTextField
private JTextField textField = new JTextField(10);
public MyPInterface() {
textField.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
JTextComponent textComp = (JTextComponent) e.getSource();
textComp.selectAll();
}
});
add(new JLabel("Enter Text Here:"));
add(textField);
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = (Window) SwingUtilities.getWindowAncestor(MyPInterface.this);
win.dispose();
}
});
}
public String getText() {
return textField.getText();
}
}
A Good way of doing this is use Callback mechanism.
I have already posted an answer in the same context.
Please find it here JFrame in separate class, what about the ActionListener?.
Your method is a bit confusing:
public String userValue(String input) {
return input;
}
I guess you want to do something like this:
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
Also your JFrame is not visible yet. Set the visibility like this setVisible(true)
Description of the problem: I have a JFrame, inside this JFrame there is a JPanel with a button, when I press the button an action listener change the current JPanel with a new JPanel, which contains other two JPanels, those two have an inputMap that when the user press the key "up" make something on both of them. The problem is: when I change the JPanel with the new one the "up" key won't do anything.
Here is the code: is a SSCCE, so you just have to copy and paste to see what it does.
This modified code comes from another question that I "solved" sometimes ago. How to make two JPanels listen to the same event?
(the code is in the answer that I selected).
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class TwoPanelsTest extends JFrame {
private static MyPanel one = new MyPanel("One");
private static MyPanel two = new MyPanel("Two");
private static List<MyPanel> list = Arrays.asList(one, two);
private PanelsController panelsController;
public TwoPanelsTest() {
super("TwoPanelsTest");
panelsController= new PanelsController(this);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(400,400);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private static class MyPanel extends JPanel {
private String string = " will be updated though its action.";
private Action action = new UpdateAction(this);
private String name;
private JLabel label;
public MyPanel(String name) {
this.name = name;
this.label = new JLabel(name + string, JLabel.CENTER);
this.setLayout(new GridLayout());
this.setFocusable(true);
this.add(label);
}
public Action getAction() {
return action;
}
private void update() {
label.setText(name + ": " + System.nanoTime());
}
private static class UpdateAction extends AbstractAction {
private MyPanel panel;
public UpdateAction(MyPanel panel) {
this.panel = panel;
}
#Override
public void actionPerformed(ActionEvent ae) {
panel.update();
}
}
}//MyPanel
private static class ButtonPanel extends JPanel{
private JButton button ;
private PanelsController panelsController;
public ButtonPanel(PanelsController panelsController){
this.panelsController=panelsController;
button = new JButton("Button");
button.setActionCommand("buttonPressed");
button.addActionListener(this.panelsController);
this.setFocusable(true);
add(button);
}
}//ButtonPanel
private static class PanelsController implements ActionListener {
private TwoPanelsTest twoPanelsTest;
public PanelsController(TwoPanelsTest twoPanelsTest){
this.twoPanelsTest=twoPanelsTest;
this.twoPanelsTest.getContentPane().add(new ButtonPanel(this));
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("buttonPressed")){
twoPanelsTest.getContentPane().removeAll();
twoPanelsTest.getContentPane().invalidate();
JPanel panel = new JPanel(new GridLayout(0, 1, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.add(one);
panel.add(two);
panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
panel.getActionMap().put("up", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
for (MyPanel panel : list) {
panel.getAction().actionPerformed(e);
}
}
});
twoPanelsTest.getContentPane().add(panel);
twoPanelsTest.validate();
twoPanelsTest.repaint();
}
}//ActionPerformed
}//PanelsController
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
TwoPanelsTest t = new TwoPanelsTest();
}
});
}
}
Well, its pretty simple - if you have those two panels without any components inside and want them to listen the hotkey use:
panel.getInputMap ( JComponent.WHEN_IN_FOCUSED_WINDOW )
.put ( KeyStroke.getKeyStroke ( KeyEvent.VK_UP, 0 ), "up" );
JComponent.WHEN_IN_FOCUSED_WINDOW instead of JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT.
Otherwise you need to have somthing focused inside the panel so it could catch the key events.
By the way, there is also another way to listen global hotkeys inside Java application windows:
Toolkit.getDefaultToolkit ().addAWTEventListener ( new AWTEventListener ()
{
public void eventDispatched ( AWTEvent event )
{
// All application key events will be passed here
}
}, AWTEvent.KEY_EVENT_MASK );