I'm working on a small personal project.
I have two JFrame windows, Viewer and Console.
Viewer only contains a subclass of JPanel, and it should respond to mouse input (clicking, mostly).
Console contains a button, a JTextField (the input), and a JTextArea (the output).
I need to make sure than when I press keys on my keyboard, the corresponding text appears in the Console JTextField, not only when the focus is held by the JTextField, but also when it's held any other component in my app.
In other words, I want the JTextField to accept input even right after I clicked on the Viewer frame.
Is this feasible?
In case that matters, I'm running win 8 x64 and I don't really care about portability (I'm the only one that will ever look at or use this code).
EDIT: here is an example of my code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class main {
public static Viewer v;
public static Console c;
public static void main(String[] args) {
v=new Viewer();
c=new Console();
}
static class Viewer extends JFrame {
public Viewer(){
setSize(600,600);
getContentPane().add(new myPanel());
addMouseListener(new mouse());
setVisible(true);
}
}
static class myPanel extends JPanel{
public void paintComponent(Graphics g){
g.setColor(new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255)));
g.fillRect(0, 0, 600, 600);
}
}
static class Console extends JFrame {
public Console(){
setSize(600,200);
JTextField text=new JTextField();
getContentPane().add(text);
setVisible(true);
}
}
static class mouse implements MouseListener{
#Override
public void mouseClicked(MouseEvent arg0) {
v.repaint();
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
}
In this example, after I click on the big window to change its color, if I want to write stuff in the other window I have to click on it first.
Can I suggest the KeyboardFocusManager? I've found this to be the easiest way to achieve what I believe you are trying to achieve
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
new KeyEventDispatcher() {
public void dispatchKeyEvent(KeyEvent ke) {
//TODO: fill this in
}
});
One inelegant solution is to create a KeyListener, which feeds typed characters to your console, although how exactly this happens depends on how you create your components. For the sake of this example I'll pretend to do it through a static method in your Console class (preferably you'd have access to an instance of Console):
public class ApplicationKeyListener implements KeyListener {
public ApplicationKeyListener() {
}
// Other necessary methods...
public void keyPressed(KeyEvent e) {
char pressed = e.getKeyChar();
Console.feedChar(pressed);
}
}
And then in Console, make sure your JTextField object is global and static, then set up the feedChar() method.
public class Console extends JFrame {
private static JTextField consoleTextField;
public Console() {
consoleTextField = new JTextField();
// ...
}
public static feedChar(char c) {
consoleTextField.setText(consoleTextField.getText() + c.toString());
}
}
Then finally you'd have to add this listener to all JFrames and their children.
public class Viewer extends JFrame {
public Viewer() {
ApplicationKeyListener kl = new ApplicationKeyListener();
addKeyListener(kl);
for (Component child : this.getComponents()) {
child.addKeyListener(kl);
}
}
}
Related
I know there was milions of questions about that, but I can't understand most of them. I've seen that people make something like that:
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode()== KeyEvent.VK_Q)
//do something
}
but keyPressed must override methos of some class to work or be runned in other thread. I really don't know how to do that. Can someone give me code of the easiest keylistener for java.
It should work even when program is not focused (it's just console program).
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.*;
import javax.swing.JFrame;
public class SquatCounter {
class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode()== KeyEvent.VK_Q)
System.out.println("Key Q pressed!");
}
}
JFrame jf = new JFrame("title");
public SquatCounter() {
jf.addKeyListener(new MyKeyListener());
}
public static void main(String[] args) {
Key1 key = new Key1 ();
SquatCounter test = new SquatCounter();
}
}
When you setup the JFrame, add a KeyListener like this:
JFrame jf = new JFrame("title");
jf.addKeyListener(new MyKeyListener());
jf.setVisible(false);
(The jf.setVisible(false); stops the program window from appearing (only command line)
Then create a new class called MyKeyListener that extends KeyAdapter.
class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode()== KeyEvent.VK_Q)
System.out.println("Key Q pressed!");
}
}
Now let me explain things a bit.
First, when you create a JFrame, it has no default KeyListener attached. Therefore, we have to create a class MyKeyListener to do that.
Secondly, we extended KeyAdapter instead of implementing KeyListener because there are a lot more methods than what you need in there. You only need to override the keypressed() method when you extends KeyAdapter but you have to implement all (I think it's 3) the other methods that you don't need for your purposes.
Lastly, if you want to do other methods like keyreleased(), just add it in to the MyKeylistener class and it will work.
Hope this helps!
EDIT: Per OP's request, it should be like this:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while (line.equalsIgnoreCase("q") == false) {
line = in.read();
System.out.println("Q is pressed!");
}
in.close();
Just add a KeyListener.
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.*;
import javax.swing.JFrame;
public class SquatCounter {
JFrame jf = new JFrame("title") {{
setVisible(true);
setDefaultCloseOperation(3); // EXIT_ON_CLOSE
}};
public SquatCounter() {
jf.addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent event) {
if (e.getKeyCode()== KeyEvent.VK_Q)
//do something
}
#Override
public void keyReleased(KeyEvent event) {
// different stuff
}
#Override
public void keyTyped(KeyEvent event) {
// more stuff
}
});
}
public static void main(String[] args) {
SquatCounter test = new SquatCounter();
}
}
Doing something out of focus has an answer here: Stackoverflow: Listening for input without focus in Java
I am very new to the Graphics portion of Java. I have created a frame and on it I have added a panel whose color has been set to Green. Now on clicking that panel I want to draw a circle using a test class's object called Mypanel. But it does not happen. Please guide !
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
class Mypanel extends JPanel
{
#Override
public void paintComponent(Graphics g)
{
g.drawOval(15, 15, 5, 5);
}
}
public class algo extends javax.swing.JFrame {
public algo() {
initComponents();
jPanel1.setBackground(Color.GREEN);
}
Mypanel p = new Mypanel() ;
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
p.repaint();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new algo().setVisible(true);
}
});
}
}
If I were to guess I would say that I am not supposed to use the repaint method, but I was told that this was to be used.
That code as supplied would not compile. For better help sooner, post a Minimal, Complete, and Verifiable example or Short, Self Contained, Correct Example.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Mypanel extends JPanel {
boolean clicked = false;
Mypanel() {
setBackground(Color.GREEN);
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
clicked = true;
repaint();
}
};
this.addMouseListener(mouseListener);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 100);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (clicked) {
g.drawOval(15, 15, 50, 50);
}
}
}
public class algo extends JFrame {
public algo() {
initComponents();
pack();
//jPanel1.setBackground(Color.GREEN); ?!?
}
protected final void initComponents() {
add(new Mypanel());
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new algo().setVisible(true);
}
});
}
}
There are a few things to correct in your example...
When you create the frame (i.e. in the constructor) you'll want to call super(). This is the first thing the constructor has to do. Then, you'll probably want to set an initial width/height, and set the background color of the frame green.
You need to add a mouse listener so that the mouseClicked method is actually called. Then have it add the 'MyPanel' object to the frame, and call repaint.
I think that's roughly what you're going for.
i am in trouble with checking if the mouse has clicked with a JFrame. When i use public void mousePressed(MouseEvent e) to print something and i click with the mouse it doesn't print anything. It doesn't gives a error, it just prints nothing out. Here is my code :
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class tuna extends JFrame
{
private JTextArea textArea;
public static void main(String[] args)
{
//Run the program
tuna run = new tuna();
run.setDefaultCloseOperation(3);
run.setSize(1200, 1000);
run.setVisible(true);
}
public tuna()
{
super("Simple JFrame");
//add a simple JScrollPane
textArea = new JTextArea(10,10);
JScrollPane scrollPane = new JScrollPane(textArea);
textArea.setEditable(true);
add(scrollPane);
}
//This doesn't print anything when i am clicking in the JFrame
public void mousePressed(MouseEvent e)
{
if(e.getButton() == MouseEvent.BUTTON1)
{
System.out.println("left");
}
else if(e.getButton() == MouseEvent.BUTTON3)
{
System.out.println("right");
}
}
}
Thank you in advance.
You can make you own Mouse Listener and add it to textArea or another component.
For example like this:
public class tuna extends JFrame
{
private JTextArea textArea;
public static void main(String[] args)
{
//Run the program
tuna run = new tuna();
run.setDefaultCloseOperation(3);
run.setSize(1200, 1000);
run.setVisible(true);
}
public tuna()
{
super("Simple JFrame");
//add a simple JScrollPane
textArea = new JTextArea(10,10);
JScrollPane scrollPane = new JScrollPane(textArea);
textArea.setEditable(true);
textArea.addMouseListener(new CustomListener());
add(scrollPane);
}
//This doesn't print anything when i am clicking in the JFrame
public class CustomListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent mouseEvent) {
if(mouseEvent.getButton() == MouseEvent.BUTTON1)
{
System.out.println("left");
}
else if(mouseEvent.getButton() == MouseEvent.BUTTON3)
{
System.out.println("right");
}
}
#Override
public void mousePressed(MouseEvent mouseEvent) {
}
#Override
public void mouseReleased(MouseEvent mouseEvent) {
}
#Override
public void mouseEntered(MouseEvent mouseEvent) {
}
#Override
public void mouseExited(MouseEvent mouseEvent) {
}
}
}
Well there are few issues, in your concept and source code
First you need a MouseListener, so in your case either you can
create a separate MouseListener or use the current JFrame class
itself, like this
public class Tuna extends JFrame implements MouseListener
Also I would recommend to follow proper naming convention and use Tuna instead of tuna.
Then the element you want to respond on the MouseEvents should be
register with the MouseListener created in first step, in your constructor.
textArea.addMouseListener(this);
Also make sure on what element you want to register your
MouseListener, currently your entire Frame is covered by TextArea,
so registering listener on JFrame won't help, instead add it on
JTextArea
Try using #Override annotation where ever possible, editor shows
appropriate compiler errors then, in your case you just wrote,
public void mousePressed(MouseEvent e)
instead of
#Override
public void mousePressed(MouseEvent e)
As this methods works only if you implement an MouseListener
Refer this link for more understanding,
https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
I have some problem with creating back button. Now in form there is list, I need create button which be on this form in the lower right corner, and when scrolling list, button remains in its place(the lower right corner).
I was trying create container in for lower of the screen and do his invisible. But its not helped because list does not appear under container.
You can try this...
import com.sun.lwuit.Command;
import com.sun.lwuit.Form;
import com.sun.lwuit.Display;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
public class FirstApp extends MIDlet implements ActionListener{
Form f;
Command exitCommand;
public FirstApp()
{
//display form
Display.init(this);
f = new Form("myForm");
f.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
public void commandAction(Command c, Displayable dis)
{
}
protected void startApp() throws MIDletStateChangeException
{
//add exit button
Command exitCommand;
exitCommand = new Command("EXIT")
{
public void actionPerformed(ActionEvent e) {
notifyDestroyed();
}
};
f.addCommand(exitCommand);
f.setBackCommand(exitCommand);
}
You need to use in Object Command.
Command cmd = new Command(searchText) {
public void actionPerformed(ActionEvent evt) {
//TODO - implement back
}
};
and than adding him to Form
f.addCommand(command);
I had posted this in a wrong place (GameDev) and got no response there. So I'm posting it again here.
I'm making an applet game and it is rendering, the game loop is running, the animations are updating, but the keyboard input is not working. Here's an SSCCE.
public class Game extends JApplet implements Runnable {
public void init(){
// Initialize the game when called by browser
setFocusable(true);
requestFocus();
requestFocusInWindow(); // Always returning false
GInput.install(this); // Install the input manager for this class
new Thread(this).start();
}
public void run(){
startGameLoop();
}
}
And Here's the GInput class.
public class GInput implements KeyListener {
public static void install(Component c){
new GInput(c);
}
public GInput(Component c){
c.addKeyListener(this);
}
public void keyPressed(KeyEvent e){
System.out.println("A key has been pressed");
}
......
}
This is my GInput class. When run as an applet, it doesn't work and when I add the Game class to a frame, it works properly.
Thanks
Solved now. See my solution
One possible solution is to use the JApplet's contentPane, to set the focus on it rather than on the JApplet itself. But my preference is to use Key Bindings instead. You may need to use a Swing Timer for this to work:
My SSCCE:
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
#SuppressWarnings("serial")
public class AppletKeyListen extends JApplet {
#Override
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
setFocusable(true);
int timerDelay = 100;
Timer myTimer = new Timer(timerDelay , new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
boolean focusObtained = requestFocusInWindow();
System.out.println("focusObtained for JApplet: " + focusObtained);
Container contentPane = getContentPane();
contentPane.setFocusable(true);
focusObtained = contentPane.requestFocusInWindow();
System.out.println("focusObtained for contentPane: " + focusObtained);
}
});
myTimer.setRepeats(false);
myTimer.start();
// boolean focusObtained = requestFocusInWindow();
// System.out.println("focusObtained: " + focusObtained);
//
// Container contentPane = getContentPane();
// contentPane.setFocusable(true);
//
// focusObtained = contentPane.requestFocusInWindow();
// System.out.println("focusObtained: " + focusObtained);
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
If you're running in a browser, you probably need to click on the applet to give it focus. For security reasons most browsers won't let an applet just grab the keyboard focus without the user clicking it.
So, I would add a mouse listener instead of doing the focus grabbing directly in init():
addMouseListener(new MouseAdapter() {
public void onMousePress(MouseEvent e) {
requestFocus();
}
});
Now that I have two options,
Use JWS
Don't make an applet mode
Now I had tried to make a new class called GApplet. It loads a game into a new JFrame which worked from the applet. Now I can access the fullscreen mode from web too. Here's a link to the class.
The GApplet class
And now it's working like the webstart and is actually an applet.