I used the NteBeans' GUI making tool.
It created a frame.
I want to close this frame using a button.
I know that I need to use "my_frame_name.dispose();" to close a frame.
But the problem is I cant find the name of the frame in the "Source" tab.
I think this is because, NetBeans created this frame and its code automatically.
Could anyone tell me how to close this frame using a code or a function, please?
Please don't tell me I have to recode everything, because I have multiple frames like tis one and don't have the luxury of time.
You can try this one also
Here program is using container.getParent() method to find out the top most JFrame.
public static void main(String[] a) {
JFrame frame = new JFrame();
JPanel p = new JPanel();
final JButton btn = new JButton("close");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Container parent = btn;
while ((parent = parent.getParent()) != null) {
System.out.println(parent.getClass().getName());
if (parent instanceof JFrame) {
((JFrame) parent).setVisible(false);
} else {
parent = parent.getParent();
}
}
}
});
p.add(btn);
frame.getContentPane().add(p);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
Related
I'm trying to make a program using java and swing gui. I want a total of 3 windows/JFrames to be used. The first window opens well and I have added 2 buttons in the first window. After clicking on those buttons I want 2 other windows to open.
The program itself is to perform matrix operations and scientific calculations. The first window has two buttons clicking on which the desired operation is to be performed.
I have cleated 3 java files in total, one java file has the Swing gui elements to display the two buttons. And other 2 java files which perform the matrix calculations and scientific calculations
I want to open the two other java classes when a button is clicked. I searched online for articles to follow but none of it worked. So, please help me out. Code of the main java file is given below.
class calculator
{
public static void main(String args[])
{
JFrame f = new JFrame("2 in 1 Calculator");
JButton b=new JButton("Matrix");
b.setBounds(50,100,95,30);
f.add(b);
f.setLayout(null);
f.setVisible(true);
b.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
MatrixPanel m1=new MatrixPanel();
m1.setVisible(true);
}
});
JButton b1=new JButton("Scientific");
b1.setBounds(200,100,95,30);
f.add(b1);
f.setLayout(null);
f.setVisible(true);
b1.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
ScientificPanel p1=new ScientificPanel();
p1.setVisible(true);
}
});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(420,420);
}
}
The name of the other two java files is ScientificCalculator.java and MatrixCalculator.java. I am ready to provide more information pertaining to the code as well. Help is really appreciated
DONT USE MULTIPLE JFRAMES
Use dialogs and proper modality:
public class DialogExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
JButton button = new JButton("Click me for dialog");
button.addActionListener(e -> {
Component customView = new CustomPanel();
Object[] options = { "Yes, please", "No, thanks", "No eggs, no ham!" };
int n = JOptionPane.showOptionDialog(frame, customView, "A Silly Question",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[2]);
if (n == 0) {
JOptionPane.showMessageDialog(frame, "Thanks for selecting yes.");
}
});
frame.setLayout(new FlowLayout());
frame.add(button);
frame.pack();
frame.setVisible(true);
});
}
static class CustomPanel extends JPanel {
public CustomPanel() {
super(new BorderLayout());
add(new JLabel("CustomPanel"));
}
}
}
Also, don't use null layout! Read why null layout and setBounds() is bad practice.
I am trying to write an application that get video frames, process them and then display them in JPanel as images. I use the OpenCV library to get video frames (one by one), then they are processed and after that displayed on the screen (to get the effect of playing video).
I created the GUI using Java Swing. A window application is created with the necessary buttons and a panel to display the video. After clicking "START", a method playVideo is called, which takes video frames from the selected video, modifies them and displays them in the panel. My code looks like this:
public class HelloApp {
private JFrame frame;
private JPanel panel;
final JLabel vidpanel1;
ImageIcon image;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
HelloApp window = new HelloApp();
window.frame.setVisible(true);
}
});
}
public void playVideo() throws InterruptedException{
Mat inFrame = new Mat();
VideoCapture camera = new VideoCapture();
camera.open(Config.filename);
while (true) {
if (!camera.read(inFrame))
break;
Imgproc.resize(inFrame, inFrame, new Size(Config.FRAME_WIDTH, Config.FRAME_HEIGHT), 0., 0., Imgproc.INTER_LINEAR);
... processing frame
ImageIcon image = new ImageIcon(Functions.Mat2bufferedImage(inFrame)); // option 0
vidpanel1.setIcon(image);
vidpanel1.repaint();
}
}
public HelloApp() {
frame = new JFrame("MULTIPLE-TARGET TRACKING");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);//new FlowLayout()
frame.setResizable(false);
frame.setBounds(50, 50, 800, 500);
frame.setLocation(
(3 / 4) * Toolkit.getDefaultToolkit().getScreenSize().width,
(3 / 4) * Toolkit.getDefaultToolkit().getScreenSize().height
);
frame.setVisible(true);
vidpanel1 = new JLabel();
panel = new JPanel();
panel.setBounds(11, 39, 593, 371);
panel.add(vidpanel1);
frame.getContentPane().add(panel);
JButton btnStart = new JButton("START / REPLAY");
btnStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
playVideo();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
});
}
}
I tried to delete the old panel and create a new one every time when button "START" is clicked, but it didn't work. Also I tried before running method playVideo to clean all the panel with methods:
panel.removeAll();
panel.repaint();
playVideo();
And to be honest I don't know what's wrong. The GUI is created, frames are taken and processed, but the panel displays only the last frame. I would be grateful for any advice :)
First of all, a proof it can actually work, somehow, with your code.
Here I read JPG images located in the resources folder, but it actually doesn't really matter.
Your code is a bit messy too. Where are you attaching the btnStart JButton to the outer panel? You need to understand how to layout components too.
You have a main JFrame, and a root JPanel which needs a layout. In this case we can opt for a BorderLayout.
panel = new JPanel(new BorderLayout());
Then we add our components.
panel.add(btnStart, BorderLayout.PAGE_START);
panel.add(vidpanel1, BorderLayout.CENTER);
Now coming to your issue, you say
The gui is created, frames are taken and processed, but panel display only the last frame
I don't know how much the "last frame" part is true, mostly because you're running an infinite - blocking - loop inside the Event Dispatch Thread, which will cause the GUI to freeze and become unresponsive.
In actionPerformed you should actually spawn a new Thread, and inside playVideo you should wrap
ImageIcon image = new ImageIcon(Functions.Mat2bufferedImage(inFrame));
vidpanel1.setIcon(image);
vidpanel1.repaint(); // Remove this
in EventQueue.invokeAndWait, such as
// Process frame
...
// Update GUI
EventQueue.invokeAndWait(() -> {
ImageIcon image = new ImageIcon(Functions.Mat2bufferedImage(inFrame));
vidpanel1.setIcon(image);
});
I set JTextField "rfid" to setEnabled(false) in MainGUI class and created method setRfidEnabled to be able to enable textfield from another class called CardLayout.
When I try to call it from CardLayout by button event listener it does nothing, I mean to textfield, because System.out.print("LOL"); works fine. MainGUI contains JFrame and by button calls another JFrame in CardLayout class.
When I initialize MainGUI class, it has Thread[Thread-2,6,main], but when I call CardLayout it becomes Thread[AWT-EventQueue-0,6,main], same as CardLayout itself. I tried to make "rfid" volatile, no success.
---Edited code---
MainGUI:
public class MainGUI {
JTextField rfid;
JButton button;
final JFrame frame;
final JPanel pane;
LayoutChanger layout = new LayoutChanger();
public MainGUI() {
rfid = new JTextField("", 10);
button = new JButton("CardLayoutSwitch");
frame = new JFrame("Main GUI Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout(5,5));
pane = new JPanel(new GridLayout(5, 5));
frame.add(pane,BorderLayout.CENTER);
pane.add(rfid);
pane.add(button);
rfid.setEnabled(false);
button.setEnabled(true);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent e){
layout.changeLayout(1);
}
});
}
public void setRfidEnabled() {
System.out.println("LOL");
rfid.setEnabled(true);
button.setEnabled(false);
}
}
LayoutChanger class:
public class LayoutChanger {
public static void main(String[] args) {
MainGUI gui = new MainGUI();
}
public void changeLayout(int i){
if (i == 1) {
CardLayout card = new CardLayout();
}
}
}
CardLayout class:
public class CardLayout {
JFrame frame;
JButton manual;
final JPanel pane;
MainGUI gui = new MainGUI();
public CardLayout() {
manual = new JButton("UID MANUAL");
frame = new JFrame("Card Scan Panel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new BorderLayout(5, 5));
pane = new JPanel(new BorderLayout(5, 5));
manual.setPreferredSize(new Dimension(50, 25));
frame.add(pane, BorderLayout.CENTER);
pane.add(manual);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
manual.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent e){
gui.setRfidEnabled();
}
});
}
}
As stated in the comments above by #matt
Every time you click on manual button, you're creating a new MainGUI().
You need to create a single instance, either in your constructor or in the ActionListener and ask if you already have an instance of it (i.e. a Singleton) and use it.
If you decide to use the first one, declare gui as a global variable:
MainGUI gui = new MainGUI();
And on your ActionListener have it changed as:
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(currentThread());
gui.setRfidEnabled();
//frame.dispose();
}
Then you have a single instance of it.
Also as stated by #Sergiy you don't really need all those threads
Here are some examples on how to use ActionListeners:
I'm trying to make a button to count characters in a text field
AppletViewer bugged and trying to involve a timer
Calculator returns 0.0 to all questions asked
Java - My action event doesn't work
Drawing shapes on a JForm java
Animated Sprites with Java Swing This one includes a Timer (Another thread that handles the animation but doesn't block the EDT)
As you can see in all the above examples, none of them required another Thread to handle the actions, the one that uses a thread is only for performing the animation and not to react to user clicks.
Recommended tutorial: How to use Actions
Good afternoon!
I have this code:
private static class ClickListener implements ActionListener {
public ClickListener() {
}
#Override
public void actionPerformed(ActionEvent e) {
JFrame frame = new JFrame();
JLabel label = new JLabel("Opção Indisponivel");
JPanel panel = new JPanel();
frame.add(label, BorderLayout.CENTER);
frame.setSize(300, 400);
JButton button = new JButton("Voltar");
button.addActionListener(new CloseWindowListener());
panel.add(button);
frame.add(panel, BorderLayout.SOUTH);
frame.setVisible(true);
}
}
private static class CloseWindowListener implements ActionListener {
public CloseWindowListener() {
}
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
}
What I want to do is when i click on the button "voltar" (which is in another window, not on the "main" one as you can see) it closes the windows but not the app itselft. The setVisible line gives me an error about that it cannot be referenced by a static context which I understand because I need the reference of the frame. How do I solve this?
EDIT: Changed JFrame to JDialog but still no sucess. Both windows are shutdown.
Thanks in advance,
Diogo Santos
The setVisible line gives me an error about that it cannot be referenced by a static context which I understand because I need the reference of the frame. How do I solve this?
You can access the component that generated the event. Then you can find the window the component belongs to. This will give you generic code to hide any window:
//setVisible(false);
JButton button = (JButton)e.getSource();
Window window = SwingUtilities.windowForComponent(button);
window.setVisible(false);
You can also check out Closing an Application. The ExitAction can be added to your button. Now when you click the button it will be like clicking the "x" (close) button of the window. That is whatever default close operation your specify for the window will be invoked.
I created class NewProject extends JInternalFrame. Then I create New...Action named "NEW", localised in File menu. I put code NewProject p = new NewProject(); p.setVisible(true); to the ActionPerformed method of the action.
But when I run the module and click "NEW" in file menu, nothing appears.
Where can be problem?
EDIT:
I partially solved it by code:
public void actionPerformed(ActionEvent e) {
JInternalFrame f = new JInternalFrame();
f.setSize(500, 500);
f.setVisible(true);
JDesktopPane p = new JDesktopPane();
p.add(f);
//WindowManager.getDefault().getMainWindow().setTitle("fFF");
WindowManager.getDefault().getMainWindow().add(p)
}
but GUI is broken. When I create new internal frame, the black background appears as I move by that frame.
Any idea how to solve it?
The customary Container for JInternalFrame is JDesktopPane. The article How to Use Internal Frames outlines the essentials, and you may like this short example of using Action and JMenu in this context.
Although the NetBean's GUI editor is appealing, you may want to become more comfortable using Swing components first.
Addendum: You can't add one Top-Level Container like JFrame to another like JDesktopPane, but you can add any number of JInternalFrame instances to a JDesktopPane. Try the demo to see how it works.
Addendum: Ah, you mean NetBeans Platform. Sorry, I've not used it.
I think the answer you are looking for is here: https://blogs.oracle.com/geertjan/jdesktoppane,-jinternalframe,-and-topcomponent
There Geertjan Wielenga show an example using a TopComponent with a JDesktopPane inside, where you can attach some JInternalFrame.
...
...
...
private JDesktopPane jdpDesktop;
private int openFrameCount = 0;
public DemoTopComponent() {
initComponents();
setName(NbBundle.getMessage(DemoTopComponent.class, "CTL_DemoTopComponent"));
setToolTipText(NbBundle.getMessage(DemoTopComponent.class, "HINT_DemoTopComponent"));
setLayout(new BorderLayout());
jdpDesktop = new JDesktopPane();
createFrame(); // Create first window
createFrame(); // Create second window
createFrame(); // Create third window
//Add the JDesktop to the TopComponent
add(jdpDesktop);
}
protected void createFrame() {
MyInternalFrame frame = new MyInternalFrame();
frame.setVisible(true);
jdpDesktop.add(frame);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
class MyInternalFrame extends JInternalFrame {
int xPosition = 30, yPosition = 30;
public MyInternalFrame() {
super("IFrame #" + (++openFrameCount), true, // resizable
true, // closable
true, // maximizable
true);// iconifiable
setSize(300, 300);
setLocation(xPosition / openFrameCount, yPosition / openFrameCount);
// Add some content:
add(new JLabel("hello IFrame #" + (openFrameCount)));
}
}
...
...
...