In my program, I have this MAIN window and a HELP window. The HELP window (when opened) is to always stay on top whether it's in focus or not. The issue however is, when I try to requestFocusInWindow() for a component in the MAIN window through an action listener that gets fired from the HELP window, it just won't let me do it.
What is the proper way of accomplishing this?
TY :)
Edit:
As requested, here's a short example of what I'm trying to accomplish. Essentially I need the button inside the HELP window to trigger focus to the TextField inside the Main window.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main {
public static void initGUI() {
mainFrame = new JFrame("Main");
helpFrame = new JFrame("Help");
mainFrame.setPreferredSize(new Dimension(500, 200));
helpFrame.setPreferredSize(new Dimension(500, 200));
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
helpFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setLayout(new FlowLayout());
helpFrame.setLayout(new FlowLayout());
mainTextView = new JTextField("", 20);
mainButton = new JButton("Open Help");
helpButton = new JButton("Request Focus");
mainButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(mainButton)) {
helpFrame.pack();
helpFrame.setVisible(true);
}
}
});
helpButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(helpButton))
System.out.println("Focus requested:" + mainTextView.requestFocusInWindow());
}
});
helpFrame.add(helpButton);
mainFrame.add(mainTextView);
mainFrame.add(mainButton);
mainFrame.pack();
mainFrame.setVisible(true);
}
public static void main(String[] args) {
initGUI();
}
static JFrame mainFrame, helpFrame;
static JTextField mainTextView;
static JButton mainButton, helpButton;
}
So turns out the fix was rather trivial. If requestFocus() is used instead of requestFocusInWindow(), it seems to work just fine.
Kinda feel stupid for how much time I spent on this :P
helpButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(helpButton))
mainTextView.requestFocus();
}
});
Related
That's My Code Down Here. I want the answer for java.awt.Button and java.awt.Frame.
Can any one help me with it?
import java.awt.*;
import java.awt.event.*;
public class TestGUI extends Frame implements ActionListener, WindowListener{
private Label lbl;
private Label lbl1
private Label lbl2;
private Label lbl3;
private TextField tf;
private TextField tf1;
private TextField tf2;
private Button btn;
private Button btn1;
private Frame frame;
public TestGUI() {
setLayout(new FlowLayout());
lbl = new Label("Hi Guys! That's My First GUI Program and is made by me too");
add(lbl);
lbl1 = new Label("Enter Your Name Please ~");
add(lbl1);
tf1 = new TextField(30);
tf1.setEditable(true);
add(tf1);
lbl2 = new Label("Enter Your Age Please ~");
add(lbl2);
tf2 = new TextField(30);
tf2.setEditable(true);
add(tf2);
lbl3 = new Label("Enter Your School/College Name Please ~");
add(lbl3);
tf = new TextField(28);
tf.setEditable(true);
add(tf);
btn = new Button("Cancel");
add(btn);
btn.addActionListener(this);
addWindowListener(this);
setTitle("My own GUI");
setSize(500, 300);
setVisible(true);
}
public static void main(String[] args){
TestGUI app = new TestGUI();
}
#Override
public void actionPerformed(ActionEvent evt){
}
#Override
public void windowClosing(WindowEvent evt){
System.exit(0);
}
#Override public void windowDeactivated(WindowEvent evt){}
#Override public void windowActivated(WindowEvent evt){}
#Override public void windowOpened(WindowEvent evt){}
#Override public void windowClosed(WindowEvent evt){}
#Override public void windowIconified(WindowEvent evt){}
#Override public void windowDeiconified(WindowEvent evt){}
}
Thanks in Advance.
You're just complicating the things. Instead of extending the frame & implementing those interfaces, just extend JFrame.
public class TestGUI extends JFrame{...}
In your TestGUI frame create another JFrame say otherFrame and create two bottons say Open & Close and then bind ActionListener to them.
openBtn.addActionListener(new ActionListener(){
otherFrame.setVisible(true);
});
closeBtn.addActionListener(new ActionListener(){
otherFrame.setVisible(false);
});
The setVisible() method accepts boolean & this is what you actually need.
Much simpler & cleaner code.
It might make more sense for you to use a JFrame instead of a Frame (I recomend you read Kumar Vivek Mitra's answer here to get a better idea of why).
If you use a JFrame, you'll need to call yourJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) to stop your program when you close the window.
To respond to your button clicks, simply pass Anonymous Classes to your buttons addOnClickListener() method, like this:
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//Do stuff here
}
});
Then you should be able to remove your existing actionPerformed() method.
For opening a new frame and closing your existing one, you should be creating two JFrame objects instead of extending Frame (or JFrame). Then, when you want to open your second frame, just call secondFrame.setVisable(true), and close your first one with firstFrame.dispose. However, I'd have a look at JDialogs and JOptionPanes first to see if they might work better for you.
After all this you should be able to remove all your WindowListener stuff, as that's for something slightly different. (Have a look here if you're interested)
Finally, don't forget to add a semicolon after your lbl1 label. ;)
Good luck!
You may use ActionListener interface.
However for a little addition to above guys commented. You may add animation to your frame by adding for loop and setSize method within the loop and the height width of the corresponding loop's variable.
For school I have to make a small game which is based on Breakout.
I got my JFrame which does this:
game.setFocusable(true);
setContentpane(game);
in my game I am adding a inputhandler which extends Keylistener and implements JPanel.
setFocusable(true);
Inputhandler input = new Inputhandler();
addKeylistener(input);
It just doesn't seem to work, I've been writing a lot of tests but I can't see to get the input handle capture any keyPressed.
When I change my JFrame to:
add(game);
it works like it is meant to work but the problem I encounter when doing this way is painting my panels the correct way. I'm kinda stuck on this issue so please someone help me out.
Point I've reached now:
public Game(){
setFocusable(true);
requestFocus();
requestFocusInWindow();
getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
getActionMap().put("pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Space is pressed");
}
});
this.inputHandler = new InputHandler();
addKeyListener(this.inputHandler);
setPreferredSize(new Dimension(500,500));
}
If I had a dollar for every time this question were asked, I'd retire rich. As per previous similar questions...
Yes you would need to make the JPanel focusable for its KeyListener to work
And you'd also have to give it the focus, since being focusable is not enough. Usually this is achieved by calling requestFocusInWindow() on the listened to JPanel.
And nothing else can have the focus or steal the focus if the KeyListener is to continue functioning.
Which is one of several reasons why most of us recommend against use of KeyListeners for Swing applications
And usually in favor of using Key Bindings.
Edit
I've used your code and it works, both the key bindings and the KeyListener:
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;
public class Game extends JPanel {
private InputHandler inputHandler;
public Game() {
setFocusable(true);
requestFocus();
requestFocusInWindow();
getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
getActionMap().put("pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Space is pressed");
}
});
this.inputHandler = new InputHandler();
addKeyListener(this.inputHandler);
setPreferredSize(new Dimension(500, 500));
}
class InputHandler extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
System.out.println("key pressed");
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("key released");
}
}
private static void createAndShowGui() {
Game mainPanel = new Game();
JFrame frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I want to close my JDialog by hitting the "enter" key on my keyboard. how can I do that? thank you!
NOTE:
I want to do this, without any button involved.
THank you!
One way:
You could give it a close JButton
whose ActionListener has code that closes the dialog,
And make that button the default button for the dialog's rootpane.
e.g.,
myDialog.getRootPane().setDefaultButton(exitButton);
Option two:
Use Key Bindings to bind the enter key to exit code in an AbstractAction.
e.g.,
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class DemoDialog {
public static void main(String[] args) {
JFrame frame = new JFrame("Frame");
frame.add(Box.createRigidArea(new Dimension(400, 300)));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
final JDialog dialog = new JDialog(frame, "Dialog", true);
// set binding
int condition = JPanel.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = ((JPanel) dialog.getContentPane()).getInputMap(condition);
ActionMap actionMap = ((JPanel) dialog.getContentPane()).getActionMap();
String enter = "enter";
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), enter);
actionMap.put(enter, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.add(Box.createRigidArea(new Dimension(200, 200)));
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
}
I would like to say first that 'Hovercraft Full Of Eels' solution is more elegant than this one and more closely in the spirit of the JDialog and Swing API. However, to offer an alternative here is a basic example of using a KeyListener on your JDialog that will do as you need without adding a button;
public class Test {
public static void main(String[] args) {
JDialog jd = new JDialog();
// Add and define the KeyListener here!
jd.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
// Nothing
}
#Override
public void keyPressed(KeyEvent e) {
// Nothing
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
JDialog d = (JDialog)e.getSource();
d.dispose();
}
}
});
// End key listener code
jd.setVisible(true);
}
}
The important/relevant code is between the two main comments. This is a compilable example, so you can copy paste this into a new file and run it to view the effects.
I am a novice as already stated and looking to create a button to close the program out. I am not talking about making sure the typical window close (Red X) terminates the program. I wish to make an additional button within my frame that when clicked will terminate the program as well.
You can add an ActionListener to your button which, upon action being performed, exits from the JVM.
yourButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
If you have set up the main application frame's (JFrame) defaultCloseOperation to JFrame.EXIT_ON_CLOSE then simply calling the frame's dispose method will terminate the program.
JButton closeButton = JButton("Close");
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
yourReferenceToTheMainFrame.dispose();
}
});
If not, then you will need to add to the actionPerformed method a call to System.exit(0);
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class GoodbyeWorld {
GoodbyeWorld() {
final JFrame f = new JFrame("Close Me!");
// If there are no non-daemon threads running,
// disposing of this frame will end the JRE.
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// If there ARE non-daemon threads running,
// they should be shut down gracefully. :)
JButton b = new JButton("Close!");
JPanel p = new JPanel(new GridLayout());
p.setBorder(new EmptyBorder(10,40,10,40));
p.add(b);
f.setContentPane(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
ActionListener closeListener = new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
f.setVisible(false);
f.dispose();
}
};
b.addActionListener(closeListener);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new GoodbyeWorld();
}
};
SwingUtilities.invokeLater(r);
}
}
If you are extending the org.jdesktop.application.Application class (Netbeans would do that) you could invoke exit() in your app class, so:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
yourApp.exit();
}
});
I want to know how to show an internal frame in swing. That means,when a JFrame is needed, normally what I do is,
new MyJFrame().setVisible(true);
Let's say the previous form should be displayed as well. And when this new frame is displayed,another new icon is displayed on the task bar.(it sounds like two separate applications run in one application) I want to avoid showing that icon and display both frames as they are in one application. Thank you
..want to avoid showing that icon and display both frames as they are in one application.
Another solution is to put the 2nd and subsequent free floating elements in a JDialog.
E.G. of using both a frame and dialog to hold extra content.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class FrameTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initGui();
}
});
}
public static void initGui() {
final JFrame f = new JFrame("Frame Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel gui = new JPanel(new GridLayout(0,1,5,5));
final Content c = new Content();
JButton frame = new JButton("Frame");
frame.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JFrame f2 = new JFrame("Content");
f2.add(c.getContent());
f2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f2.pack();
f2.setLocationByPlatform(true);
f2.setVisible(true);
}
});
gui.add(frame);
JButton dialog = new JButton("Dialog");
dialog.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JDialog d = new JDialog(f);
d.add(new Content().getContent());
d.pack();
d.setLocationByPlatform(true);
d.setVisible(true);
}
});
gui.add(dialog);
f.add(gui);
f.pack();
f.setVisible(true);
}
}
class Content {
public Component getContent() {
JPanel p = new JPanel();
p.add(new JLabel("Hello World!"));
return p;
}
}
You have one JFrame for an application.
You can display multiple JPanels within a JFrame.
Or, as trashgod pointed out, you can have multiple JInternalFrames within a JDesktopFrame.