How to use KeyPressed in Java - java

I am working on my Java assignment. I have to create a virtual keyboard and my professor didn't teach us about KeyPressed and I am stuck for couple of days now.
My question is if I want the user to type something in the JTextFiled and want to change the background of the JButton to appear in different color whenever the user type any of the characters that are available on the keyboard, how can I do that?
For example, if the user hit the spacebar, I want the color of the spacebar on the frame to appear black and when the user releases the button, the color changes to it's original background color.
I know how to create JFrame, JButton, JLabel, and JPanel.
This is a simple code that I have created.
import javax.swing.*;
import java.awt.*;
public class Assignment extends JFrame {
private JButton jbtnSpace = new JButton(" ");
private JPanel jpnl1 = new JPanel();
private JTextArea txta = new JTextArea(10,62);
public Assignment(){
jpnl1.add(txta);
jpnl1.add(jbtnSpace);
this.add(jpnl1);
}
public static void main(String[] args) {
Assignment jfrm = new Assignment();
jfrm.setTitle("Assignment");
jfrm.setSize(710,440);
jfrm.setVisible(true);
jfrm.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
Please help. Thank you

Try this:
private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {
int i=evt.getKeyChar();
if(i==KeyEvent.VK_SPACE) //or any Key Constant
{
//your code of changing the color
}
}
I hope this helps. You must understand the working though, as described in one of the comments.

Related

How to change icon in JLabel with JButton

I'm making a simple conversion tool to convert dollars to euro's and vice versa.
The whole purpose is just to experiment and learn this cool tool, java.
I have a JLabel at the top with an icon of a euro to indicate the starting currency. I have a button bellow this that I want to use to change that icon to a dollar one.
I am currently plying around with an ActionListener and trying different variations of setIcon/setIconImage (every itteration I can think of seeing that nothing has worked thus far).
public class MoneyConverter extends JFrame implements ActionListener{
//add label and icon showing base conversion currency
JLabel startcur = new JLabel("<--- Starting Curency", new ImageIcon("C:\\Users\\Russel\\Desktop\\1euro.gif"), SwingConstants.CENTER);
JButton euro = new JButton("Swap to Euro");
JButton dollar = new JButton("Swap to Dollar");
I then set up a
public MoneyConverter(){}
method and add all my components to a grid layout and add ActionLister's to my convert buttons.
e.g.
dollar.addActionListener(this);
euro.addActionListener(this);
After the usual code (setVisible and the likes that I will omit for your sake as I don't see it interfering with this, please let me know if I should include it all)
public void ActionPerformed (ActionEvent e){
Object source = e.getSource();
if (source.equals(euro)){
startcur.setIcon(new ImageIcon("C:\\Users\\Russel\\Desktop\\1.gif"));
}
}
This part has been changed many times and is the main reason for this post, how do I change this icon in the JLabel? - I will also be setting the conversion rate in here depending if they choose to start with dollars or euros. (Rate won't be actual rate.)
First, create and store a new ImageIcon
ImageIcon image = new ImageIcon(getClass().getResource("/nameOfImage.jpg"));
Then put this in your Action Listener
label.setIcon(image);
label.setText("");
You have to make sure you have a resource folder set up for your project. You can read how to do that in IntelliJ or Eclipse
You are also declaring the actionPerformed() wrong. I suggest reading up on this You should be doing it like this.
#Override
public void actionPerformed(ActionEvent e)
{
}
Conventionally, in java, method names start with a lower case letter and Classes start with an upper case.
The whole purpose is just to experiment and learn this cool tool, java.
Then I'll show you how to improve this program in a number of ways.
//Don't make your Swing class implement Actionlistener and add it as a
//listener to itself in the constructor before it's fully initialized
public class MoneyConverter extends JFrame {
//These don't have to be loaded at runtime, so make them into constants
//Java variables and methods follow thisNamingConvention
private static final Icon euroIcon = new ImageIcon("C:\\Users\\Russel\\Desktop\\1euro.gif");
private static final Icon dollarIcon = new ImageIcon("C:\\Users\\Russel\\Desktop\\1dollar.gif");
//These you probably want to use later so save them as private class variables
//Make them final so you can access them in the ActionListeners below
private final JLabel currencyLabel;
private final JButton euroButton;
private final JButton dollarButton;
public MoneyConverter() {
//These are declared final and are are therefore usually set first in constructor
this.currencyLabel = new JLabel("<--- Starting Curency", euroIcon, SwingConstants.CENTER);
this.euroButton = new JButton("Swap to Euro");
this.dollarButton = new JButton("Swap to Dollar");
//Write your own separate ActionListener for each button
euroButton.addActionListener(new ActionListener() {
#Override
public void run() {
currencyLabel.setIcon(euroIcon);
//These two are required for you to see the effect
//This should also be the solution to your initial problem
currencyLabel.revalidate();
currencyLabel.repaint();
}
});
dollarButton.addActionListener(new ActionListener() {
#Override
public void run() {
currencyLabel.setIcon(dollarIcon);
currencyLabel.revalidate();
currencyLabel.repaint();
}
});
//Add your components here using whatever layout manager you want.
}
public static void main(String []args){
//Start new Swing applications like this to prevent it from
//clogging the rest of the program
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MoneyConverter();
}
});
}
}

Handle RadioButton events after button clicked

help,
my questions are:
why isn't itemStateChanges triggered, I tried to put it in the inner class ButtonHandler and also in RadioButtonHandler Im having trouble with it, what is the right way to do it?
I want to trigger and check the marked JRadioButtons after the user click the "check" button.
What is the right way to check which button was clicked, I feel like comparing the strings is bad programming practise. Maybe using an ID ?
How should I make a "reset" button(start over), I want to uncheck all radio buttons and run the constructor once again.
Thank you for your help !
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class ExamFrame extends JFrame {
static ArrayList<Question> qArrList;
JRadioButton a1,a2,a3,a4;
public ExamFrame() {
super("Quiz");
setLayout(new GridLayout(0, 1));
GridBagConstraints gbc = new GridBagConstraints();
Exam exam = new Exam();
qArrList = exam.getExam();
int count=0;
for(Question q : qArrList){
count++;
JLabel questionLabel = new JLabel(count+". "+q.getQustion()); //swing constant ?
ArrayList<String> ansRand = q.getAllRandomAns();
a1 = new JRadioButton(ansRand.get(0));
a2 = new JRadioButton(ansRand.get(1));
a3 = new JRadioButton(ansRand.get(2));
a4 = new JRadioButton(ansRand.get(3));
add(questionLabel);
add(a1);add(a2,gbc);add(a3);add(a4);
ButtonGroup radioGroup = new ButtonGroup(); //logical relationship
radioGroup.add(a1);radioGroup.add(a2);radioGroup.add(a3);radioGroup.add(a4);
}
//buttons:
JButton checkMe = new JButton("Check Exam");
JButton refresh = new JButton("Start Over");
ButtonHandler handler = new ButtonHandler();
checkMe.addActionListener(handler);
refresh.addActionListener(handler);
add(checkMe);
add(refresh);
}
/** Listens to the radio buttons. */
public class ButtonHandler implements ActionListener
{
public void actionPerformed (ActionEvent e) {
if(e.getActionCommand().equals("Start Over")){ //id?
//how to do this?
}
else{
RadioButtonHandler handler = new RadioButtonHandler();
a1.addItemListener(handler);
System.out.println("success?");
}
JOptionPane.showMessageDialog(ExamFrame.this, String.format("You pressed: %s", e.getActionCommand()));
}
public void itemStateChanged(ItemEvent e) //can i add it here?
{
JOptionPane.showMessageDialog(ExamFrame.this, String.format("yes?"));
System.out.println("success!");
}
}
public class RadioButtonHandler implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
JOptionPane.showMessageDialog(ExamFrame.this, String.format("radio state changed"));
}
}
}
why "itemStateChanges" isn't triggered, i tried to put it in the inner
class "ButtonHandler" and also in "RadioButtonHandler" Im having
troubles with it, what is the right way to do it? I want to trigger
and check the marked JRadioButtons after the user click the "check"
button.
ButtonHandler is implemented with ActionListener only:
public class ButtonHandler implements ActionListener{}
The itemStateChanged(ItemEvent) function belongs to ItemListener. This function is triggered if state of a source component to which this listener is registered gets changed. So implement the ItemListener. However, one more thing to note, that JButton doesn't respond to ItemListener but JRadioButton will. Because this Item events are fired by components that implement the ItemSelectable interface. Some example of such components are: check boxes, check menu items, toggle buttons and combo boxes including Radio Buttons as mentioned above.
What is the right way to check which button was clicked, i feel like
comparing the strings is wrong programming. Maybe using an ID
Well using the event source function: e.getSource(), check whither the type of the source is your expected type and cast it to appropriate type. And then you can use getName(String) function and check the name you were expecting. Of-course you should assign the name using setName(String) after initialization of component. Or using the component reference directly if it is declared in the Class context and you have direct access to the component.
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getSource() instanceof JCheckBox)
{
JCheckBox checkBox = (JCheckBox)e.getSource();
if(checkBox.getName().equals("expectedName"))
; // do my thing
}
}
How should i make a "reset" button(start over), i want to uncheck all
radio buttons and run the constructor once again.
Well you are working with ButtonGroup. And ButtonGroup has a nice function: clearSelection() to help with whatever(I could not understand the part: run the constructor part) you want.
Edit: As you wanted me to see an ItemListener implemented class, Yes i can see that But:
i can not see that you have actually registered an instance of that class(a1.addItemListener(handler);) to any component before performing any action on the component to which ButtonHandler is registered to: checkMe, refresh
In addition to that, in this action performed function, you are checking with
action command, which you haven't even set with JButton.setActionCommand(String) function. You should not assign a (Item)listener depending on event-occurrence of another (Action)listener.
Tutorial:
How to Write an ItemListener
How to Write an ActionListener
How to Use the ButtonGroup Component

JTextField hangs on GUI update via X11 forwarding

I have a Swing GUI that allows a user to add JTextFields to the GUI as needed. When I run this locally on the console (on ubuntu), everything works fine.. When I run the GUI from Cygwin on a Windows box using X11 forwarding, everything starts out fine, but when I click the "add" button to put a new JTextField on the GUI, the text field shows up as expected, but I can't click in it or modify it, etc., for a long time. In fact, I can't click in the original text fields either.. After a little more than 30 seconds, the text fields come back to life and work normally until I click "add" again.
I've included a SSCCE below that demonstrates the problem. Again, this only seems to happen when running with X11-forwarding, and if I run on the Ubuntu console directly, it works as expected, so I'm not sure if this will be reproduce-able for everyone else.
One last piece of information - in my real program, clicking the add button causes a JComboBox and two JTextFields to be added. The combo box is responsive right away, but all text fields on the GUI (new ones and old ones too) are not.
HmmFrame.java:
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class HmmFrame extends JFrame
{
ArrayList< JTextField > fields;
JPanel mainPan;
JButton addButton;
HmmFrame()
{
super("Hmmm");
JTextField curField;
fields = new ArrayList< JTextField >();
setLayout(new FlowLayout());
mainPan = new JPanel(new FlowLayout());
this.add(mainPan);
addButton = new JButton("Add");
addButton.addActionListener(new HmmListener());
this.add(addButton);
curField = new JTextField("Try");
fields.add(curField);
updateGUI();
setVisible(true);
}
public void updateGUI()
{
mainPan.removeAll();
for (JTextField curField : fields)
{
mainPan.add(curField);
}
pack();
}
public class HmmListener implements ActionListener
{
public void actionPerformed(ActionEvent actEv)
{
JTextField curField;
curField = new JTextField("New One" + fields.size());
fields.add(curField);
updateGUI();
}
}
}
Hmm.java (driver)
public class Hmm
{
public static void main(String [] args)
{
HmmFrame hmmFrame;
hmmFrame = new HmmFrame();
}
}

ActionListener from JTextArea Java

I'm new to Java, and trying to figure out one last thing for my program.
This is the program that I have coded and with the layout it is perfectly fine no problem at all.
Now my program suppose highlight the buttons whenever to press it on the keyboard (NOT BY PRESSING THE BUTTON ON THE SCREEN)
I'm not sure what I have to use since the action that it needs to take is when they type it in the JTextArea. I'm trying to use KeyEvent with KeyPressed but not sure if that is the right thing to do since it doesn't really work.
I can't post my code at the moment here since this is an assignment and I don't want some of my classmate to google and use it if they found it here. (LOL)
As required here is my codes :)
import javax.swing.*; // import all javax.swing
import java.awt.*; // import all java.awt
import java.awt.event.*;
public class Sample extends JFrame implements KeyListener { // start of the
// class
private JTextArea field = new JTextArea(10,15); // create an instance of
// JTextField
private JPanel mainPanel = new JPanel(); // create an instance of JPanel
private JPanel TopFieldPan = new JPanel();
private JPanel MainBtnsPan = new JPanel();
private JPanel FifthRowPan = new JPanel();
JPanel fifthBtn = new JPanel();
private static JButton Space = new JButton("");
public Sample() { // start of the weather constructor
Space.setPreferredSize(new Dimension(280, 45));
fifthBtn.add(Space);
TopFieldPan.add(field);
FifthRowPan.setLayout(new BoxLayout(FifthRowPan, BoxLayout.X_AXIS));
FifthRowPan.add(fifthBtn);
MainBtnsPan.setLayout(new GridLayout(5, 5, 0, 0));
MainBtnsPan.add(FifthRowPan);
mainPanel.add(TopFieldPan);
mainPanel.add(MainBtnsPan);
this.add(mainPanel);
Space.setSelected(true);
field.addKeyListener(this); // important !!!
setTitle("Typing Tutor"); // set the title to the frame
setSize(300, 300); // set the fixed size
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true); // make it visible
} // ends of the constructor
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
Space.setBackground(Color.green);
}
}
public void keyReleased(KeyEvent evt) {
Space.setBackground(null);
}
public void keyTyped(KeyEvent evt) {
// TODO Auto-generated method stub
if(evt.getKeyChar() == 'a' || evt.getKeyChar() == 'A')
{
Space.setBackground(Color.green);
}
else if(evt.getKeyChar() == 'b' || evt.getKeyChar() == 'B')
{
Space.setBackground(Color.red);
}
}
public static void main(String[] args) { // start of the main method
new Sample();
} // ends of main method
} // ends of class
I tried to simplified the code as much as I could and here is the final one.
So I'm trying to make it when I press a or A it should highlight that space JButton.
Create a map of your buttons and the keys they map to, like this:
Map<String, JButton> buttonMap = new HashMap<String, Button>();
Then, when you are adding the buttons, add them to the map, like this:
buttonMap.put(FirstRow[i].toLowerCase(), btn);
Then, add something like this into your KeyTyped:
public void keyTyped(KeyEvent evt) {
String keyPressed = new String(""+evt.getKeyChar()).toLowerCase();
JButton tmp = buttonMap.get(keyPressed);
if(null != tmp){
tmp.doClick();
}
}
I did this quickly to your code for row 1 and 2. You'll have to play around with it to get it to work for the special keys, but it should get you where you're trying to go.
I pasted it here, to keep the answer small.
http://pastebin.com/t1v8d6Hi
You're code looks okay for a first pass, you seem to have a basic mechanism in place that works with the KeyListener. You probably need to think about how to stop mouse clicks on the buttons, JButton.setEnabled(false) works but changes how the button is drawn so you may need to override the paint method. You probably only need to hook the keylistener up to one component, the window will get all events, the text area when it has focus. The main task you have is to work out how to map the key pressed events to the buttons, maybe use a hashmap or something to store the JButtons with the key being the character code?

Differences between Jbutton and Jpanel and JFrame ?

i make simple game , and it consist of 2 files , first file is "Alibaba.java" which is extended from JFrame , i used it to display general contents of the game !,
and the second file is "intro.java" which is extended from JPanel , i used it to show intro of the game which include (title & background & person) ,
my problem occured when i tried to add a simple button in the intro ! , i did a function to create the button , but the problem is when i run the game , the button which i added it don't appear !! , but when i tried add it from the first file which extended from JFrame , its appeared ! ,
so what is the problem in my code ? is JPanel don't accept JButtons ! or i must create the buttons from the JFrame file ?!
so i need to know how to add Jbutton inside Jpanel instead of add Jbutton in JFrame Direct !!,
this is my samples of my codes which contain the problem :
1st file (Alibaba.java)
package alibaba;
import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class Alibaba extends JFrame {
public Alibaba(){
super("Alibaba");
Intro intro = new Intro();
this.add(intro);
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getDefaultScreenDevice();
device.setFullScreenWindow(this);
}
public static void main(String[] args) {
Alibaba alibaba = new Alibaba();
}
}
2nd file(Intro.java) :
package alibaba;
import javax.swing.JButton;
public class Intro extends javax.swing.JPanel implements Runnable{
Thread _intro_run;
public Intro() {
_intro_run = new Thread(this);
_intro_run.start();
}
#Override
public void run() {
// Here i tried to add a button to the Intro !!!
this.add(this.createbutton("Exit"));
}
public JButton createbutton(String text){
JButton _button = new JButton(text);
return _button;
}
}
So please tell me what is the problem and how to solve it , sorry but iam new to java , new to programming games world ! ,, thank you :)
You have to add the JButton inside the main thread, cross thread Component manipulation is bad.
For example:
public Intro() {
JButton exitButton = new JButton("Exit");
this.add(exitButton);
}
Alternatively, use SwingUtilities.invokeLater(Runnable). For example, in your run method:
#Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
add(createbutton("Exit"));
}
}
}
Based on discussion it seems that you are overriding the paint or paintComponent methods. You need to call super in them, like:
void paint(Graphics g) {
super.paint(g);
// do other stuff to g
}
In addition, it is a bad sign that you have a JPanel that implements Runnable. In Java, all UI work (here you are using Swing components) is done from the Event Dispatching Thread - having an actual Swing component (your Intro class is a JPanel) Runnable flies in the face of that.
Suggestions:
Anytime you add a new component to a container, you have to tell the layout managers to layout the new and existing components. This is done by calling revalidate() on the JPanel receiving the button. You also should call repaint() on the JPanel after this.
You shouldn't do any of this in a background thread.
Most important read the Swing tutorials as they will tell you all of this and more.

Categories

Resources