Hey I have a panel class in which there are two panels, one of the panels have text field. I want to perform an action when it gets focused.
The panel is added on the main frame.
Use FocusListener, here is simple example:
import java.awt.BorderLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class TestFrame extends JFrame{
public TestFrame(){
init();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void init() {
JTextField f1 = new JTextField(5);
f1.addFocusListener(getFocusListener());
add(f1,BorderLayout.SOUTH);
add(new JTextField(5),BorderLayout.NORTH);
}
private FocusListener getFocusListener() {
return new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
super.focusGained(e);
System.out.println("action");
}
};
}
public static void main(String... s){
new TestFrame();
}
}
Also JFrame has getFocusOwner() method.
Use the api
JFrame.getFocusOwner()
This will return a reference to the component with focus
You ca also check....
KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()
To the modification, just add a FocusListener to your respective Component, and implement the interface to your particular acitons.
There are visual clue that helps to know which component has the focus, such as an active cursor in a text field. To work with the FocusListener Interface and in order to listen’s the keyboards gaining or losing focus, the listener object created from class is need to registered with a component using the component’s addFocusListener() method. The two important method focusGained(FocusEvent e) and void focusLost(FocusEvent e) which helps to find which component is focused.
To know more about What is FocusListener Interface and How it Works.
Related
So I have a case like this:
I have a JFrame, let's call it frame1. There's a JButton named Submit in frame1.
Inside the frame1, there is a JPanel, call it panel1. There's a JTextField in that JPanel.
The frame1 and panel1 are two different Java files.
I want to do something like this:
When I user edit, delete or insert the JTextField, there's a DocumentListerner to check if the input match with a regex. If it matches, then the Submit button is enabled, otherwise the Submit button is disabled.
I already know how to implement the DocumentListener on JTextField1 with regex check. The thing I don't know how to do is to make the frame1 listen to the boolean outcome of that regex check, so the Submit button will be enabled/disabled.
Could anyone help please ?
One way to do this could be to have the JButton on the same class as the JTextField, for a simple GUI as the one you have this is doable.
But we know there are times that this isn't possible so another way that you could have this done up to Java 8 is using the Observer pattern, as shown in this example. After Java 9, Observer and Observable are deprecated so you should use PropertyChangeEvent and PropertyChangeListener from java.beans package1.
So, if you're not using Java 9 or higher and don't care about the caveats of Observer and Observable then you could have a sample code like this one:
EnableButtonInOtherClass
import java.awt.BorderLayout;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class EnableButtonInOtherClass implements Observer {
private JFrame frame;
private OtherClass pane;
private JButton button;
private ObservableField observableField;
public static void main(String[] args) {
SwingUtilities.invokeLater(new EnableButtonInOtherClass()::createAndShowGUI);
}
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
observableField = new ObservableField();
observableField.addObserver(this);
pane = new OtherClass(observableField);
button = new JButton("Click me!");
button.setEnabled(false);
frame.add(pane);
frame.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
#Override
public void update(Observable o, Object arg) {
System.out.println("Text is a digit: " + arg);
button.setEnabled((boolean) arg);
}
}
OtherClass
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
#SuppressWarnings("serial")
public class OtherClass extends JPanel implements DocumentListener {
private JTextField field;
private ObservableField observableField;
public OtherClass(ObservableField observableField) {
field = new JTextField(10);
add(field);
this.observableField = observableField;
field.getDocument().addDocumentListener(this);
}
#Override
public void changedUpdate(DocumentEvent e) {
// TODO Auto-generated method stub
}
#Override
public void insertUpdate(DocumentEvent e) {
updateState();
}
#Override
public void removeUpdate(DocumentEvent e) {
updateState();
}
private void updateState() {
String patternString = "[0-9]+";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(field.getText());
observableField.updateState(matcher.matches());
}
}
ObservableField
import java.util.Observable;
public class ObservableField extends Observable {
public void updateState(boolean state) {
setChanged();
notifyObservers(state);
}
}
The above example makes use of the ObservableField class to handle the Observable class, that has an update method that notifies the observers (EnableButtonInOtherClass) that there has been a change every time you type into the JTextField on OtherClass and based on the matcher.matches() value determines if the JButton should be enabled or not.
But again, for a simple UI as the one you have it's easier to move the JButton to the same file and / or on JButton's ActionListener evaluate what's inside the JTextField rather than enable / disable the JButton.
Here are some screenshots of how the program looks like.
1Taken from this answer
So I'm making a simple program that jumps from panel to panel and am using an actionlistener Button to make the jump. What kind of method or operation do I use to jump from panel to panel?
I tried to use setVisible(true); under the action listener, but I get just a blanks screen. Tried using setContentPane(differentPanel); but that doesn't work.
ackage Com.conebind.Characters;
import Com.conebind.Tech.TechA16;
import Com.conebind.Overviews.OverviewA16;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Char_A16 extends JFrame {
private JButton combosButton16;
private JButton techButton16;
private JButton overviewButton16;
private JLabel Image16;
private JPanel panel16;
private JPanel panelOverviewA16;
public Char_A16() {
overviewButton16.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
OverviewA16 overview16 = new OverviewA16();
overview16.setVisible(true);
overview16.pack();
overview16.setContentPane(new Char_A16().panelOverviewA16);
}
});
techButton16.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//Todo
}
});
}
private void createUIComponents(){
Image16 = new JLabel(new ImageIcon("Android 16.png"));
}
public static void main (String[] args){
JFrame frame = new JFrame("Android 16");
frame.setContentPane(new Char_A16().panel16);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);}
}
The setContentPane(OverviewA16) doesn't work because there's not an object that defines the panel.
Please check this demo project showing how to use CardLayout with IntelliJ IDEA GUI Designer.
The main form has a method that switches between 2 forms displayed inside it:
public void showPanel(String id) {
final CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, id);
}
Both forms are added to the card layout during the main form initialization:
FormOne one = new FormOne();
one.setParentForm(this);
cardPanel.add(one.getPanel(), FORM_ONE);
FormTwo two = new FormTwo();
two.setParentForm(this);
cardPanel.add(two.getPanel(), FORM_TWO);
final CardLayout cl = (CardLayout) cardPanel.getLayout();
cl.show(cardPanel, FORM_ONE);
A reference to the main parent form is passed to these 2 forms using setParentForm() method so that FormOne and FormTwo classes can access the showPanel() method of the MainForm.
In a more basic case you may have a button or some other control that switches the forms
located directly on the MainForm, then you may not need passing the main form reference to the subforms, but it can be still useful depending on your app logic.
I have a frame, on this frame I have a Menu with About MenuItem. When we select it the program opens a new JPanel with texts and with OK button and the enabled status of parent panel is set to false.
And now comes a problem. When we click on OK, then I want to close this About panel, and I want to turn to parent panel, and I want to enable it!
Please tell me, how?
Consider using a WindowListener that reacts to the closing event of the about-dialog. You can add this in your frame or in the constructor of your dialog, just set the variables accordingly.
myDialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
parentFrame.setEnabled(true);
}
});
If you really only have a switching JPanel, use a ButtonListener.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
frame.setEnabled(true);
}
});
As mentioned in the comments, using a modal JDialog would be a more elegant way of solving the problem of disabling a parent frame while a dialog is active. Here is a tutorial.
Why don't you use simply a JOptionPane (particularly the showMessageDialog method)? You can specify there an Object (for example a JPanel) which will be presented in a modal dialog. Take a look at this sample code I've written for you (I've used a JButton, but it will be the same for JMenuItem):
import java.awt.BorderLayout;
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.JOptionPane;
import javax.swing.JPanel;
public class AboutDialogDemo extends JFrame {
private final JButton btnAbout = new JButton("About...");
public AboutDialogDemo() {
final JFrame thisFrame = this;
btnAbout.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(thisFrame, new AboutPanel());
}
});
getContentPane().setLayout(new BorderLayout());
getContentPane().add(btnAbout, BorderLayout.PAGE_END);
pack();
}
public static void main(String[] args) {
AboutDialogDemo frame = new AboutDialogDemo();
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class AboutPanel extends JPanel {
private final JLabel lblAbout = new JLabel("Sample about text");
public AboutPanel() {
setLayout(new BorderLayout());
add(lblAbout, BorderLayout.PAGE_START);
}
}
I hope you'll find it useful
Well, this is a very newie cuestion. Im stating to write by myself the code of my GUI applications with the help of window builder, i have decided to stop using netbeans couse ive read some peope in here that said that would be good. You may think i havent investigate, but trust me, i did my homework...
I tryed the way oracle says:
Declare an event handler class and specify that the class either implements an ActionListener interface or extends a class that implements an ActionListener interface. For example:
public class MyClass implements ActionListener {
Register an instance of the event handler class as a listener on one or more components. For example:
someComponent.addActionListener(instanceOfMyClass);
Include code that implements the methods in listener interface. For example:
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
and my own way (wrong, off course, but i dont know whats wrong)
package Todos;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Main extends JFrame {
private JPanel contentPane;
protected JButton btnNewButton;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new BorderLayout());
//setDefaultLookAndFeelDecorated(false);
//setIconImage(Image imagen);
setTitle("");
setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
setPreferredSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
setLocationRelativeTo(null);
this.btnNewButton = new JButton("New button");
this.btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
asd(arg0);
}
});
this.getContentPane().add(this.btnNewButton, BorderLayout.NORTH);
}
public void asd(ActionEvent arg0) {
this.getContentPane().add(new JButton("asd"));
}
}
The cuestion is, why this code doesnt work, the JButton im trying to add to the JFrame with the ActionPerformed event is not visible after i click.
This is an example code, may look silly, but i think it simplifies the cuestion, since my problem is in a few lines of code its not neccesary to show you the hole proyect.
Thank you in advance!
Your problem is here:
public void asd(ActionEvent arg0) {
this.getContentPane().add(new JButton("asd"));
}
Form Container.add() javadoc:
This method changes layout-related information, and therefore,
invalidates the component hierarchy. If the container has already been
displayed, the hierarchy must be validated thereafter in order to
display the added component.
You need to call validate() method to make added button visible:
public void asd(ActionEvent arg0) {
this.getContentPane().add(new JButton("asd"));
this.getContentPane().validate();
}
I want to display a TextField only when user has entered a value in Input field
Here is my code:
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class PlayingAround {
JFrame frame;
JTextField display;
JTextField input;
public static void main(String[] args) {
PlayingAround obj = new PlayingAround();
obj.create();
}
private void create() {
frame = new JFrame();
display = new JTextField();
input = new JTextField();
display.setEditable(false);
display.setVisible(false);
input.addKeyListener(new Listener());
frame.add(BorderLayout.NORTH, display);
frame.add(BorderLayout.SOUTH, input);
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class Listener implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
display.setVisible(true);
display.setText(input.getText());
}
}
}
But my problem is that the Display JTextField doesn't becomes visible until there are some events like Resizing the Window, Minimizing and maximizing the Window.
I tried calling frame.repaint() in the keyReleased Method but even it has not helped.
You should call revalidate() and repaint() on the container that holds the JTextField after placing the text field component in the container. The revalidate() call sends a request to the container's layout managers to re-layout its components. The repaint() then requests that the JVM request of the paint manager to redraw the newly laid out container and its child components. The repaint() is not always needed but is usually a good idea.
Also, don't use a KeyListener for this, but rather a DocumentListener on the first text component's Document. This way, if the user empties the first text component, you can make the second text component disappear if desired. Also, text can be entered without key presses, and you want to allow for that.