setVisible() for cardPanel is not working - java

I want to make it so the cardPanels are not visible until an action that is not on the cardPanel is completed. For instance, a window opens up when you select a certain Jradiobutton on that window. I want to use setVisible(boolean) to to do this. However, setVisible is not working for some reason. Is there something i'm missing?
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
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.JPanel;
import javax.swing.JRadioButton;
public class MainFrame extends JFrame {
private JFrame frame = new JFrame("Swing Refresh Bug?");
private Container contentPane = frame.getContentPane();
private JPanel cardPanel = new JPanel();
private CardLayout cardLayout = new CardLayout();
private Component currentComponent;
private JButton next;
MainFrame() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// properties of the cardPanel
cardPanel.setLayout(cardLayout);
cardPanel.add(new JLabel("One"), "One");
cardPanel.add(new JLabel("Two"), "Two");
cardPanel.add(new JLabel("Three"), "Three");
cardPanel.setVisible(false);
// Create a radio button
JRadioButton addNext = new JRadioButton("Add next");
// Add the radio buttons listener
addNext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardLayout.show(cardPanel, "One");
}
});
// Set the layout of the content pane.
contentPane.setLayout(new BorderLayout());
contentPane.add(cardPanel, BorderLayout.CENTER);
contentPane.add(addNext, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public MainFrame(String title) {
MainFrame mf = new MainFrame();
}
}

Your class need not extend JFrame, you have already created JFrame in the class, if you want to move accross the cards then change ActionListener as follows
addNext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cardLayout.next(cardPanel);
}
});

You set your cardPanel not visible by setVisible(false) but you never set it to true after, so your cardPanel (containing your cardLayout) is never shown !
If you want your cardLayout to appear when pressing the radiobutton, you just have to add the setVisible(true) in the listener.
You can also use the isSelected() method from JRadioButton to check if it is clicked or not. For example :
addNext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(addNext.isSelected()){
cardPanel.setVisible(true);
cardLayout.show(cardPanel, "One");
}
else{
cardPanel.setVisible(false);
//or : cardLayout.show(cardPanel, "Two");
}
}
});
If you want a JFrame to be opened this way, just creat it before, setting it not visible. Then, you set it visible in the listener.
I hope it helped :)

Initialize it in the ActionListener not in the constructor. You must also say setVisible(true) after that. I think you can make CardPannel class which extends JPannel. There is more point of doing it like that. Instead of adding JLabels in the MainFrame constructor do it in the CardPannel constructor. I am on my phone so I can't show you code right now. I hope I helped.

Related

JButton and JTextField

What's wrong? ImageIcon and the frame's size are working properly.
But the JTextField and the JButton aren't.
I need the solution.
import javax.swing.*;
import javax.swing.ImageIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Frame {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("Alkalmazás");
frame.setVisible(true);
frame.setSize(500,500);
frame.setResizable(false);
JTextField field = new JTextField();
field.setBounds(40,250, 300,35);
JButton button = new JButton(new ImageIcon("table.png"));
button.setBounds(40,400, 250,25);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tf.setText(""something);
}
});
frame.add(field);
frame.add(button);
}
}
You didn't mention what's "not working properly", but there are a few errors with your code:
Don't call your class Frame, it may confuse you or others about java.awt.Frame, something that may work would be MyFrame
Right now all your class is inside the main method and it's not placed inside the Event Dispatch Thread (EDT), to fix this, create an instance of your class and call a method createAndShowGUI (or whatever you want to name it) inside SwingUtilities.invokeLater()
For Example:
public static void main(String args[]) {
SwingUtilities.invokeLater(new MyFrame()::createAndShowGUI)
}
Or if using Java 7 or lower, use the code inside this answer in point #2.
setVisible(true) should be the last line in your code, otherwise you may find some visual glitches that may be resolved until you move your mouse above your window or something that triggers the call to repaint() of your components.
Instead of calling setSize(...) directly, you should override getPreferredSize(...) of your JPanel and then call pack() on your JFrame, see this question and the answers in it: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
You're adding 2 components to the CENTER of BorderLayout, which is a JFrame's default layout manager, there are other layout managers and you can combine them to make complex GUI's.
setBounds(...) might mean that you're using null-layout, which might seem like the easiest way to create complex layouts, however you will find yourself in situations like this one if you take that approach, it's better to let Swing do the calculations for you while you use layout managers. For more, read: Why is it frowned upon to use a null layout in Swing?
With all the above tips now in mind, you may have a code similar to this one:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class MyFrame {
private JFrame frame;
private JPanel pane;
private JTextField field;
private JButton button;
public static void main(String[] args) {
SwingUtilities.invokeLater(new MyFrame()::createAndShowGUI);
}
private void createAndShowGUI() {
frame = new JFrame("Alkalmazás");
pane = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
field = new JTextField(10);
button = new JButton("Click me");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
field.setText("something");
}
});
pane.add(field);
pane.add(button);
frame.add(pane);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Now you have an output similar to this one:
What about you want the JTextField to have a more "normal" size? Like this one:
You'll have to embed field inside another JPanel (with FlowLayout (the default layout manager of JPanel)), and then add that second JPanel to pane, I'm not writing the code for that as I'm leaving that as an exercise to you so you learn how to use multiple layout managers

exit button java

I am building a Java GUI on IntelliJ and making an 'exit' button - currently using
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class gui extends JFrame {
private JPanel mainPanel;
private JButton exitButton;
public gui(String title) {
super(title);
exitButton = new JButton("Exit");
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setContentPane(mainPanel);
this.pack();
}
public static void main(String[] args) {
JFrame frame = new gui("Emro GUI");
frame.setVisible(true);
}
}
The code runs, and I followed an exact tutorial on youtube, but the exit button isn't function how it should and I am unsure why. Should I have the exit button in a new class or function?
Adding the following three lines in appropriate locations will make it work.
import javax.swing.*;
mainPanel = new JPanel();
mainPanel.add(exitButton);
However:
Swing should always be used from the AWT Event Dispatch Thread (EDT) (use java.awt.EventQueue.invokeLater.
No need to extend JFrame.
No need for mainPanel and exitButton to be fields instead of locals.
Use a lambda expression for the ActionListener.
Have you tried this inside your action listeners method:
WindowEvent closeWindowEvent = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING); frame.dispatchEvent(closeWindowEvent);

Swing code compilation error "missing ;"

How do I solve this compilation error? Note that I'm new to Swing.
http://prntscr.com/bpz2ve
package gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class GUI extends Frame {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello World - YaBoiAce");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 300);
// Layout //
frame.setLayout(new BorderLayout());
// Swing Component //
final JTextArea textarea = new JTextArea();
JButton jbutton = new JButton("Click me");
// Add Component to content pane
Container c = frame.getContentPane();
c.add(textarea,BorderLayout.CENTER);
c.add(jbutton, BorderLayout.SOUTH);
// Action Listener
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textarea.append("Hello");
} // Eclipse says 'missing ;' on this line.
}
private static void setDefaultCloseOperation(int exitOnClose) {
}
}
Eclipse says "Missing ;" But when I put that in, It highlights the ; saying "Missing ;" again. It keeps on doing that. Any help?
It is on the line marked with:
// Eclipse says 'missing ;' on this line.
There are many problems in your code:
As stated in the
comments
by #HovercraftFullOfEels:
You're not matching closing parenthesis on your addActionListener method too. Again good code formatting will help you see this.
// Action Listener
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textarea.append("Hello");
} // Eclipse says 'missing ;' on this line.
}); //HERE YOU NEED TO ADD: );
You're extending Frame (Maybe you were trying to extend JFrame)
and creating a JFrame object, choose which one you want to use
(Recommended to create the object instead of extending, because if
you extend a JFrame your class is a JFrame and cannot be
included somewhere else and you're not changing it's functionallity
either so, no need to extend).
You're creating a private static method
private static void setDefaultCloseOperation(int exitOnClose) {}
That method should be public and belongs to JFrame class, I guess your IDE wrote that when you extended Frame instead of JFrame.
Frame belongs to java.awt while JFrame belongs to javax.swing so, they are not the same.
You're creating your windows and every component inside your main
method instead of the constructor
You're adding your components to a Container but never add that container to your JFrame, so you need to call
frame.setContentPane(c);
So your code should look like this:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class GUI {
JFrame frame;
public GUI() {
frame = new JFrame("Hello World - YaBoiAce");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 300);
// Layout //
frame.setLayout(new BorderLayout());
// Swing Component //
final JTextArea textarea = new JTextArea();
JButton jbutton = new JButton("Click me");
frame.add(textarea,BorderLayout.CENTER);
frame.add(jbutton, BorderLayout.SOUTH);
// Add Component to content pane
Container c = frame.getContentPane();
c.add(textarea,BorderLayout.CENTER);
c.add(jbutton, BorderLayout.SOUTH);
frame.setContentPane(c);
// Action Listener
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textarea.append("Hello");
} // Eclipse says 'missing ;' on this line.
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new GUI());
}
}

JTextField is blanking out my JPanels

I am attempting to learn more about creating more dynamic GUI's. I am hoping to add different panels with different content and as you press buttons on one main panel, it changes the adjacent panels. I have added two panels and some buttons and when I test the program, it displays correctly. The problem is when I add a JTextField (or JTextArea) the panels are blank and there are no buttons. The strange thing is I haven't added the JTextField to either panel. I have only created a global variable. If I comment it out, the program runs correctly. Am I missing something very simple?
Here is the gameWindow class that has the JTextField
package rpgcreator;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
class gameWindow extends JPanel {
JPanel startWindowPanel;
JPanel settingsPanel;
JPanel characterPanel;
JPanel scenarioPanel;
JPanel mapPanel;
JButton CharacterButton = new JButton("Create your character");
JButton StoryButton = new JButton("Choose your Story line");
JButton MapButton = new JButton("Choose your World");
//JTextField nameField = new JTextField(15); //comment or uncomment to see issue
public gameWindow() {
setLayout(new GridLayout(0,2,5,0));
startWindowPanel = new JPanel(new FlowLayout());
settingsPanel = new JPanel(new GridLayout(2,1));
startWindowPanel.setBackground(Color.blue);
settingsPanel.setBackground(Color.black);
startWindowPanel.add(MapButton);
startWindowPanel.add(StoryButton);
startWindowPanel.add(CharacterButton);
add(startWindowPanel);
add(settingsPanel);
}
}
Here is main
package rpgcreator;
import javax.swing.JFrame;
public class RPGCreator extends JFrame{
private static void mainWindow(){
RPGCreator mainwindow = new RPGCreator();
mainwindow.setSize(1200, 800);
mainwindow.setResizable(false);
mainwindow.setLocationRelativeTo(null);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
// TODO code application logic here
mainWindow();
}
}
setVisible should go at the end. You're currently setting visible to true, and then adding a panel.
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
Put setVisible at the end after setDeaultCLoseOperation
I'm not entirely sure why it does it, maybe someone else can explain.
What I do know, is I usually call pack() which seems to make your problem go away.
private static void mainWindow(){
final RPGCreator mainwindow = new RPGCreator();
mainwindow.setMinimumSize(new Dimension(1200, 800));
mainwindow.setResizable(false);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainwindow.pack(); //This usually goes after you've added all of your components
mainwindow.setLocationRelativeTo(null);
}
Some notes:
I had to change to mainwindow.setMinimumSize(new Dimension(1200, 800)); to avoid the frame looking squashed. Although I would usually let the layout manager deal with the sizes of things.
Call setLocationRelativeTo(null) after you call pack() so that it has the desired effect. Again not sure why, but I've learnt that through some hardship.

JCheckBox not showing (text appears, but without check box)

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class SideNotes {
public static JPanel panel = new JPanel();
private List<String> notes = new ArrayList<String>();
private static JButton add = new JButton("Add note");
public SideNotes() {
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(add);
loadNotes();
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addNote();
}
});
}
public void addNote() {
String note = JOptionPane.showInputDialog("Enter note: ", null);
notes.add(note);
JLabel label = new JLabel(note);
panel.add(label);
panel.revalidate();
panel.repaint();
}
private void loadNotes() {
for (int i = 0; i < notes.size(); i++) {
JCheckBox jcb = new JCheckBox(notes.get(i), false);
panel.add(jcb);
panel.revalidate();
panel.repaint();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(200, 400);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(add);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
new SideNotes();
}
}
Why isn't my JCheckBox showing up? The text shows up but not the actual box. What's the deal?
I have edited my post to contain all of my code in case that helps solve the issue.
needmoretextneedmoretextneedmoretextneedmoretextneedmoretextneedmoretextneedmoretext
Possible reasons:
panel has not been added to GUI
panel has been added but for some reason is not visible.
panel is too small to show the child component. This can happen for instance if you set a component's size or preferredSize or if you place it in a FlowLayout-using container without thought.
panel uses null layout.
panel's layout manager is not one that easily accepts a new component -- think GroupLayout for this one.
There are other unspecified layout manager problems going on. Do you call pack() on your GUI? Do you use null layout or absolute positioning anywhere? Do you need to put panel in a JScrollPane?
Consider creating and posting an sscce for better help.
Edit
Your posted code doesn't ever add any JCheckBoxes to the JPanel, just JLabels. To prove this is so, click on the labels and you'll see that they don't respond to clicks.
Your code grossly over-uses static fields. Get rid of all static modifiers on all variables. They should all be instance variables. The only static anything in your code above should be the main method, and that's it. If this causes errors, then fix the errors, but not by making fields static.
Give your SideNotes class a method, getPanel() that returns the panel field.
Create a SideNotes instance in the beginning of your main method. Then call the above method on the instance to get the JPanel for the JFrame. i.e., frame.add(sideNotes.getPanel());.
Don't add JLabels to your GUI (I've no idea why you're doing this). Add JCheckBoxes in the actionPerformed method.
Every time you press the button, a new Note (JLabel) is added to the panel. But you never call loadNotes() after adding a new Note. So the JLabel is added but not its respective JCheckBox as intended.
Besides of this I'd suggest you make this change:
public void addNote() {
String note = JOptionPane.showInputDialog("Enter note: ", null);
if(notes != null) {
notes.add(note);
JLabel label = new JLabel(note);
panel.add(label);
panel.add(new JCheckBox(note, false));
panel.revalidate();
panel.repaint();
}
}
So you don't need to call loadNotes() and update the GUI just once.

Categories