I've created java Swing app where it consist of a jDesktoppane, inside it I'm loading/calling some jinternal frames from toggle buttons in the main frame (JFrame). And I've used jButton group to all the toggle buttons so only one frame will when a button is pressed.
Since I've used toggle button, even though I dispose a JInternalFrame the relevant toggle button will be in pressed mode (Selected). I've tried many ways and couldn't change the toggle-button's state from selected to UnSelected.
first i've created a method inside my Main JFrame.
public void buttongroup_off(){
buttonGroup 1.setSelected(null,false);
}
Then I created an object inside the exit button of the JInternalFrame and through that I called the buttongroup_off() method.
private void jButton 7 ActionPerformed(java.awt.event.ActionEvent evt) {
Main m1= new Main();
m1.buttongroup_off();
this.dispose();
}
but it does not work!!, Can someone help me on this?
im kind a new to programming.
private void jButton7ActionPerformed(java.awt.event.ActionEvent evt) {
Main m1= new Main();
m1.buttongroup_off();
this.dispose();
}
In this code you are creating a new JFrame Main (which is invisible after creation) and disable its buttongroup. That is not what you want. You have to call buttongroup_off method using a reference to an existing Main instance. You may pass the reference via custom constructor for custom class that extends JInternalFrame, or you may add a static method to the Main class that will return reference to the Main instance. Like this:
private void jButton7ActionPerformed(java.awt.event.ActionEvent evt) {
Main m1 = Main.getInstance();
m1.buttongroup_off();
this.dispose();
}
You may also look at this question answers: managing parent frame from child frame on java swing
You can get the JFrame by using code like:
Component source = (Component)event.getSource();
Main frame = (Main)SwingUtilities.windowForComponent( source );
Now that you have a reference to the frame you can invoke any method from your custom frame class.
Related
How would I go about closing a JFrame based on an ActionEvent from a button click within a JPanel?
I have a total of three classes:
Application: contains the main method and runs the program by creating a FrameStartUp object.
FrameStartUp: extends the JFrame class and displays the contents within StartUpPanel.
StartUpPanel: extends the JPanel class and has all the components and ActionEvents.
Within the StartUpPanel class, I have a button with an ActionEventListener waiting for the button to be clicked.
When the button is clicked I want the application to shut down completely. I know of a method called .dispose() for the JFrame class, but I can't use it because creating an object of FrameStartUp would just run another GUI (run by the constructor).
As I am new to programming and swing, I do not know any other way to fix this, other than getting rid of the StartUpPanel and just creating a JPanel within the FrameStartUp class.
Are there any methods provided by Swing that can access the current JFrame that the panel is on, so the program can close when the ActionEvent is triggered?
I know of a method called .dispose() for the JFrame class
This will work if you explicitly set setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Are there any methods provided by Swing that can access the current JFrame that the panel is on
Yes... SwingUtilities provides one called getWindowAncestor().
button.addActionListener(e -> {
SwingUtilities.getWindowAncestor((Component)e.getSource()).dispose();
});
... or more commonly, you can chose to reference a final variable to achieve the same effect...
final JFrame swingStuff = this; // or expose via a getter/setter
button.addActionListener(e -> {
swingStuff.dispose();
});
... however the final variable placement and setter/getter would need a small reproducible code example.
And finally, as others have mentioned, System.exit(0) works quite fantastically well too, so as long as it doesn't break the lifecycle of any of your other components.
My test class:
import javax.swing.*;
import java.awt.*;
public class SwingStuff extends JFrame {
// Our main JFrame
public SwingStuff() {
super();
// The button
JButton button = new JButton("Close");
button.addActionListener(e -> {
SwingUtilities.getWindowAncestor((Component)e.getSource()).dispose();
});
// The JPanel and nested components
JPanel startupPanel = new JPanel();
startupPanel.add(button);
add(startupPanel);
pack();
// Make sure the app exits when closed
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// Just our entry point
public static void main(String ... args) {
SwingUtilities.invokeLater(() -> {
new SwingStuff().setVisible(true);
});
}
}
What I have:
Two Classes that instantiate two JFrames.
What I am trying to achieve:
One with a button and the other that will become invisible when a action is fired on the button.
Problems:
I do not know how to pursue this. How should I go about coding this?
Class 1
public class test1{
public static void main(String[] args){
JFrame frame = new JFrame("Blinkly Frame");
frame.setSize(100, 100);
frame.setVisible(true);
}
}
Class 2
public class test2{
public static void main(String[] args){
JButton button = new JButton();
//when i will click this button i want to make invisible frame
}
}
Solution:
Create an instance of the class that has a Jframe or extends a JFrame.
First we need the JFrame that will be disappearing.
public class BClass extends JFrame{
// Disappearing frame
public BClass()
{
this.setSize(300,300);//sets frame properties
this.setLocationRelativeTo(null);
}
}
Next we need the Frame that will be holding the buttons. (Documentation added)
public class ACLass {
public static void main(String[] args) {
JFrame frame = new JFrame("Magician"); // instantiates
BClass b = new BClass(); // instantiates class that extends JFrame
b.setVisible(true);//
frame.setSize(300,300);//
frame.setVisible(true);//
frame.setLocationRelativeTo(null);//
JButton disappearButton = new JButton("Disappear"); //Adds button
disappearButton.addActionListener(new ActionListener() { // Adds action -When button is "clicked"
public void actionPerformed(ActionEvent e) { // method called when action fired
b.setVisible(false); //visibility changed
}
});
disappearButton.setBounds(0,0,300,150);
JButton appearButton = new JButton("appear"); //Adds button
appearButton.addActionListener(new ActionListener() { // Adds action -When button is "clicked"
public void actionPerformed(ActionEvent e) { // method called when action fired
b.setVisible(true); //visibility changed
}
});
disappearButton.setBounds(0,100,300,150);
frame.add(disappearButton, BorderLayout.PAGE_START); //adds button to frame
frame.add(appearButton, BorderLayout.PAGE_END); //adds button to frame
//I used border layout however use the a layout manager that works with your components/frame
}
}
Exotic Explanation
I'm going to explain this in terms of a magic show as it provides better understanding.
So first, we have one magician(JFrame) and his wand(JButton) and then we have the helper(the second JFrame) that will disappear and a stage that has been set(all properties defined etc.)
First the magician adds some magic power to his wand(actionListener that handles the button being pushed) that will react when the magician waves it(action fired a.k.a button being pushed).
Next we show the audience the helper(instantiating JFrame to disappear).
As we have shown the audience the helper, we can now show him/her disappearing (Now we can call setVisible through the instance variable of the class).
Finally, the magician waves his wand(firing an action), and the helper gets the signal(actionPerformed method) to disappear. The helper then can call the
b.setVisible(false); //making the frame invisible
General Explanation
https://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html
Basically, by instantiating an object in another class you can also call the objects methods in that class i.e. setVisible(boolean b).
Other less preferable solutions:
If your disappearing class has does not extend a JFrame but instantiates one..
You would need to create an instance variable
private JFrame j;
Then use getters/setters to access the object which will then allow you to call its methods.
secondClass.getFrame().setVisible(true);//getFrame returns the JFrame
Then add that to the actionPerformed method.
You can also use a static instance variable and statically reference it in the actionPerformed method... (not recommended)
secondClass.frame.setVisible(true);
I am new to swing programming. I have created a Jtabbedpane and added 4 jpanel to it.
all the button and labels in the 4 jpanel are in the same java class and is starting to look cluttered. I am using Intellij. It would be nice if I can put all the items and events related to one panel in its own class so 4 classes for 4 panels and just a reference to those classes in the main frame. Not sure how to do this as most of the code is generated by the IDE.
If there is a way to do this or a tutorial that does this please let me know.
Yes you can break this up rather easily. Anywhere the code generates a new panel, probably as a "build" method, you can pull that out and make in a structure in another class. An example would look something like this:
// New class file named testPanel.java
public class testPanel extends JPanel{
// Constructor
public textPanel(){
// Add an example button
JButton btn_exit = new JButton("Exit");
btn_exit.addActionListener(new ExitButtonListener());
buttons.add(btn_exit);
}
// Private inner class which does event handling for our example button
private class ExitButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
System.exit(0);
}
}
// Add whatever other code you like here or above or anywhere else :)
}
Then to use that panel in your main JFrame, you can aggregate it like this:
private testPanel pnl_test = new textPanel();
// You can place this in the constructor
// for your JFrame without the "MyJFrame."
// But for demonstration purposes I will include it
MyJFrame.add(pnl_test);
// Or if you were placing a panel inside of another panel,
// you can use the same method associated with a JPanel object
MyJPanel.add(pnl_test);
I am busy doing a school project and hoped some awesome people out there could help me.
I currently have a Main, a Log in GUI and a Search frame (designed with Netbeans Gui dev).
I have an actionPerformed(ActionEvent e) method, where I am struggling is to access the Log in button that is on my Log in GUI. Currently I am doing this.
In my constructor: Declare the Frame. LogInFrame x = new LogInFrame();
In
public actionPerformed(ActionEvent eve)
{
if(eve.getSource()==x.LogInBtn())
{
x.setVisible(false);
}
}
At the moment the button isn't responding, so I was wondering if I was doing anything wrong.
The current Frame is just a standard frame. Really simple
public static void main (String[] args)
{
JFrame LogInFrame = new JFrame ("Log in");
LogInFrame.setSize (300, 300);
JButton close = new JButton ("Hid frame");
LogInFrame.getContentPane ().add (close);
}
}
Thats about everything that is needed. The problem does not lie with the GUI itself as I can run the GUI in netbeans fine. I can use the auto generated actionPerformed method of the button by double clicking on it. But i want to be able to access my GUI's compenents in my main.(tell the button what to do from my main). I have made sure that the button is public and can be accessed. I dont get any physical "coding" errors, the code just doesnt seem to be working (the button isnt responding if I add events from my main)
I am creating a java application which consists of two frames(JFrame1 and JFrame2)
JFrame1 has a grid 6x6 button; and JFrame2 has 6 radio buttons representing colours. How can I link the two frames so that when a button in JFrame1 is clicked, JFrame2 pops up and when a colour is chosen from that the JFrame2 closes and the clicked button gets the respective colour?
It is better to have one JFrame for every application. Use one for the 6x6 JButtons and create a modal JDialog for your color JRadioButtons.
The color selection JDialog should have a public getSelectedColor() method in order to return the selected color to the caller class.
Instantiate the ColorDialog in main and do not set it visible.
The ActionListener of each JButton should make the modal JDialog visible.
The RadioButton ActionPerformed should set the selected color and make the JDialog invisible.
Call getSelectedColor() and apply the returned color to your JButton.
In your frame1's button action listner, you can do something like this
public void actionPerformed(ActionEvent e) {
Frame2 frame = new Frame2(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
where "this" refers to the frame1 object. This is you can access its jTEXTFIELD and jBUTTONs from the second frame. So naturally you have store it in Frame1 object declared in your second class.
Suppose you have a clickable color field in frame2 object, once you click on it, you should trigger a function that get the input field from frame1 (using your locale object reference) and store it in it. something like this:
public void actionPerformed(ActionEvent e) {
frame1.getMyTextField().setText(WHAT_THE_CLICKED_ON);
this.close();
}
Sorry if I made any syntax errors, it's been a long time I didnt work with java :)
Just create another class, let us say FrameMananger, then use the singleton pattern to manage them.
Then in any class, you can use FrameManager.getFrame1() to get the frame1, same as the frame2. You can add logic judgement inside, like dynamically dispose some frame or only create them when needed.
This issue is fairly common concept when you create a game and try to navigate between your every view(like the show score panel from everywhere).
public class FrameManager
{
Frame1 frame1;
Frame1 frame2;
public static Frame1 getFrame1()
{
if(frame1 == null)
frame1 = new Frame1();
return frame1;
}
public static Frame1 getFrame2()
{
if(frame2 == null)
frame2 = new Frame1();
return frame2;
}
public class Frame1 extends JFrame
{
}
public class Frame2 extends JFrame
{
}
}