JButtons not appearing - java

I am attempting to write a simple program for now but the actual JButton is not appearing for some reason, here is my code below.
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame {
public static void main(String[] args) {
JFrame window = new JFrame("Shoes");
window.setDefaultCloseOperation(EXIT_ON_CLOSE);
window.setResizable(true);
window.setSize(400,500);
window.setVisible(true);
window.setLocationRelativeTo(null);
JButton welcome = new JButton("Click here");
welcome.setLocation(100,100);
welcome.setVisible(true);
// doesn't work, but is there another way to make it so?
//add(welcome);
}
}

You created the button, but did not add it.
You have to add it to the window. Simply using add(welcome) will add it to your frame, which you extend, but not to the window in which you want it to show.
Instead of:
add(welcome);
Just do:
window.add(welcome);

I would also like to mention that the reason the code on your commented out section didnt work, is because you're extending JFrame.
When you extend JFrame, you inherit all of the methods JFrame has. That includes add(). However, when you use this.add() you are adding the compononent to you Test Object (which is also a JFrame), not your window JFrame.
To add to the window you would use window.add(welcome);
To stop these weird confusions in the future I would also change
public class Test extends JFrame
to
public class Test

you extended JFrame yet in your code you use another JFrame that you created JFrame window = new JFrame("Shoes");, this is why add(welcome); is not working for you... since its trying to add the JButton to this instance of your Test class(which is not visible) and not the window you have created.
You have 2 ways of solving this:
The first one as mentioned by #Hackerdarshi is to add the button to the window you created. like : window.add(welcome);
The second way is to make use of your extension of the JFrame class(otherwhise why extend at all) and call all the methods on the window using this instance of your Test class:
public Test() {
super("Shoes");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(true);
setSize(400,500);
setVisible(true);
setLocationRelativeTo(null);
JButton welcome = new JButton("Click here");
welcome.setLocation(100,100);
welcome.setVisible(true);
// this will work since `this` instance is set to visible
add(welcome);
}
NOTE that to set the buttons location like: welcome.setLocation(100,100); you should use a null Layout

Related

Refresh java program with Button

I am trying to make a refresh button that will essentially restart the program when ever I click the button. I don't know how I should go about doing this.
I've place the Graphical User Interface i decided to use do complete this action. Any and all help would be greatly appreciated.
package pdfView;
import javax.swing.*;
import java.awt.*;
public class View extends JFrame {
public View() {
super("PDF Viewer");
setLookAndFeel();
setSize(500, 125);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flo = new FlowLayout();
setLayout(flo);
JTextField Search = new JTextField ("Search", 29);
JButton Search1 = new JButton("Search");
//this is where i have the button
JButton ReFresh = new JButton("ReFresh");
add(Search);
add(Search1);
add(ReFresh);
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.squing.plaf.nimbus.NimbusLookAndFeel"
);
} catch (Exception exc){
}
}
public static void main(String[] args) {
View pdf = new View();
}
}
What do you mean by refresh or restart?
Do you mean:
Let the application be as it is, just update what it's showing?
Really restart the application?
Updating what the application is showing
You first need to decide what actually should cause your application to refresh. You already talked about a Button. The mechanism for activating something like a button is called Action. You can do that stuff manually, using an ActionListener, or you could extend AbstractAction, which is what I recommend. Extending AbstractAction allows you to use the same logical action something in more than one location on the UI. Look at typical applications, they offer Cut/Copy/Paste through menu, toolbar, popupmenu and keyboard shortcuts. The simplest way to achieve this in Java is using Action by extending AbstractAction.
The methods you need to call to update your application are invalidate(), validate() or repaint().
Restarting an application
So you want to run through main() again? That should actually not be required, unless you have an application that supports updating itself. Even then it can sometimes be avoided by smart usage of a ClassLoader.
Some more notes on your code
Usage by extension anti-pattern
I wouldn't extend JFrame just to display a window on the screen. Usage by extension is an anti-pattern. You don't need to extend JFrame to get a JFrame displayed on the screen and do what you want.
Referring static members
I would refer to constants via their original declaration. I.e. I'd refer to EXIT_ON_CLOSE via WindowConstants.EXIT_ON_CLOSE, not JFrame.EXIT_ON_CLOSE.
Typo
You have a typo in your UIManager.setLookAndFeel() code. Search for swing and you will see the typo.
Exception information
You might actually want to print the exception to stderr using exc.printStackTrace() instead of ignoring it completely, because when you have a typo in the LaF class name, as you do, and you don't print the exception, you might actually not come to know what's going wrong.
Sequence of widget construction and UIManager.setLookAndFeel()
The sequence of UIManager.setLookAndFeel() and the effective new JFrame() via super(...) does not guarantee you that the whole UI will be in Nimbus, parts of it might still be in Metal. I recommend to set the LaF before even constructing the first widget, to be on the safe side. As far as I remember, it's not guaranteed that changing the LaF after component construction has an effect, unless you tell the UIManager to update the LaF. See also this quote from the documentation of UIManager:
Once the look and feel has been changed it is imperative to invoke updateUI on all JComponents. The method SwingUtilities.updateComponentTreeUI(java.awt.Component) makes it easy to apply updateUI to a containment hierarchy. Refer to it for details. The exact behavior of not invoking updateUI after changing the look and feel is unspecified. It is very possible to receive unexpected exceptions, painting problems, or worse.
http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html
setSize() vs. pack() with a little help of Insets and Border
Instead of setting the size manually, you might want to play with Insets or Border and JFrame.pack() in order to get a decent layout of your window. Setting the size manually assumes that you know a lot about the screen resolution and the font size of the user.
The pack() method performs automatic size calculation based on the contents. Insets and Border allow you to create some space and borders, even with some designs or labels, around components so they wouldn't be cramped tightly in a window but be nicely spaced.
First you have to assign an actionListener to the ReFresh Jbutton.
You can either implement the interface ActionListener to the class, and override the actionPerformed() method like this
public class View extends JFrame implements ActionListener{
private JButton ReFresh;
public View() {
super("PDF Viewer");
setLookAndFeel();
setSize(500, 125);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flo = new FlowLayout();
setLayout(flo);
JTextField Search = new JTextField ("Search", 29);
JButton Search1 = new JButton("Search");
//this is where i have the button
ReFresh = new JButton("ReFresh");
ReFresh.addActionListener(this);
add(Search);
add(Search1);
add(ReFresh);
setVisible(true);
}
private void setLookAndFeel() { //right way for nimbus: http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/nimbus.html
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e)
{
if(e.equals(ReFresh))
{
super.repaint();
}
}}
public static void main(String[] args) {
View pdf = new View();
}
Or you can do inline assignment to addActionListener, like this
ReFresh.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
super.repaint();
}
});
You can try these methods to refresh/reload the JFrame,
invalidate();
validate();
repaint();
you can also use dispose(); and then new View(); to create the new JFrame, but in this sequence it will close the window and create new one.
or you can even try setVisible(false); then setVisible(true);
I recommend the first 3.

How to switch JPanels from different classes

I have three classes one JFrame class and two JPanel classes. I have added the intial JPanel to the JFrame like so
public JFrame() {
add(new 1stPanel(this));
setVisible(true);
setLayout(null);
}
Then i want to use an actionlistener on a button in the 1st panel to remove it and add the other panel which is in another class. I tried giving each class a variable and using the simple remove() and add() like this:
private 1stpanel 1p;
private 2ndpanel 2p;
btn.addActionListener((new ActionListener(){
public void actionPerformed(ActionEvent e)
{
remove(1p);
add(2p);
validate();
repaint();
}
}));
that doesn't work i have also tried using JFrame.remove(1p) but that doesn't work either. When i do removeAll() it gets rid of everything in the 1stpanel JPanel but then i can't add the 2ndpanel.
What code can i use to take out the 1st panel or 1stpanel class and add the 2nd panel which is in another class.
Thanks for the help in advance.
Try to use CardLayout and swap cards (panels).
Could be you problem is the creation add(new 1stPanel(this)). You add a local variable but then use fields of class.
your code lines
remove(1p);
add(2p);
validate();
repaint();
which you are calling inside the action listener are being called on the this object which I suspect is the JPanel itself. If it is so define a method in the class that is extending the JFrame, place these codes inside that method, and on action event call that method.

how to call active frame that already exist from another class that extends JDialog then remove all of its component?

I have class main extends jframe, it has a button that calls /shows another class that extends jdialog.
If the button from jdialog is triggered, it will dispose that dialog and will remove all component of jframe, then add it to a new jpanel.
What should I do?
Here's my new broken code:
public class mainz extends JFrame{
mainz(){
setVisible(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JToolBar r = new JToolBar();
r.add(Box.createHorizontalGlue());
add(r, BorderLayout.NORTH);
JButton n = new JButton();
r.add(n, BorderLayout.EAST);
n.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
show();
}
});
}
public void show(){
dialogz d = new dialogz(this);
d.setVisible(true);
}
public void lastHope(){
getContentPane().removeAll();
getContentPane().validate();
getContentPane().repaint();
}
public static void main (String[]args){
new mainz().setExtendedState(MAXIMIZED_BOTH);
}
}
public class dialogz extends JDialog{
public dialogz(final mainz owner) {
setSize(300, 300);
JButton n = new JButton("execute");
add(n);
final JFrame ew = (JFrame)super.getOwner();// <<
n.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
dispose();
//owner.lastHope;
ew.removeAll();// <<
ew.validate();// <<
ew.repaint();// <<
}
});
}
void yes(){
getOwner().removeAll();
getOwner().validate();
getOwner().repaint();
}
}
I know I can prevent my main class from extending jframe, and call it from main instead, but I want to do it like that...
Please help me ... T-T
Sorry for my English, I from a far away country ~,~"
update:
the error is
java.lang.ClassCastException: javax.swing.SwingUtilities$SharedOwnerFrame cannot be cast to javax.swing.JFrame
it will be done with delete the line that contain
// <<
then call lastHope();
but i think there's a another way to get that existing jframe to removeall
(by casting it first or something ~,~" )
You are calling getParent() but you never set the parent (or owner). That should happen in the constructor as already pointed out. Also, be mindful that getParent() returns a Container object and getOwner() returns a Window object. Both of these refer to the JFrame which is the parent and owner. If you want to use it as a JFrame, you'll have to cast the output as (JFrame). But removeAll() is in Container class so if that's all you want, there'll be no need for casting.
Update:
JFrame frame = new JFrame();
JDialog dialog = new JDialog(frame);//frame is owner
JFrame parentOfDialog = (JFrame)(dialog.getParent());
//OR
//JFrame parentOfDialog = (JFrame)(dialog.getOwner());
parentOfDialog.removeAll();
If you are using your custom class, pass JFrame in the constructor and call super.
Please read the javadoc on JDialog before you try to use it. Also, read more about inheritance.
I'm not clear on what your goal is, but if you want to change the components that are displayed in a container, such as a JFrame or JDialog's contentPane, then I recommend that you use a CardLayout to do this since it allows you to easily swap "views".
There could be two ways to do this:
Your JDialog class could use a reference to the JFrame that is passed in via its constructor (and you should then pass it immediately into the dialog's super constructor so that your modality will work correctly). You could then call any public methods in the JFrame's class.
Or since the JDialog is modal, the JFrame's code will halt while the dialog is visible. You could swap "views" immediately after the dialog has been disposed of and is no longer visible. this would keep the JFrame manipulating code in the JFrame class.
Edit: note that if you don't use CardLayout, then you're responsible for calling revalidate() and repaint() on any container who gets its components changed.
As an aside: since English is not your first tongue and nor is it the native language of many folks on this forum, please avoid using non-standard abbreviations. The clearer your communication with us, the easier it will be for us to understand you and help you.

How can I add a JButton to my full screen java program

I have followed thenewbostons java game tutorials on youtube and managed to create a base class which will be in full screen mode using a screenmanager class. Well all works just fine, I can draw images and strings and so on, but how the heck can I add JButtons etc etc.
I have uploaded my code on pastie.org so you can see it :)
Main.java
Screen
BaseFrame [the abstract frame]
Menu Frame [Inheritted from BaseFrame]
consider following code :
import javax.swing.JButton;
import javax.swing.JFrame;
public class NewClass5 extends JFrame
{
JButton b=new JButton("button");
NewClass5(){
this.add(b);
this.setSize(200, 200);
this.setVisible(true);
}
public static void main(String a[]){
new NewClass5();
}
}
Consider adding the button in ahead of time. Don't make it visible. Then when you want to give that option, setVisible(true). Unless you have many buttons that are dynamic and need to change on the fly or something, I think this should work.

How do I close a frame yet open a new frame? (revisited)

I'm trying to close a frame yet open a new frame.
My application has page A, a JPanel with some controls and a specific button, and when the user clicks the button, I want page A to disappear and page B to appear (page B has controls that depend on the choices that are made by the user on page A).
This has been asked before, but there was no satisfactory answer. Inside the ActionListener implementation, namely public void ActionPerformed(ActionEvent e) from my jpanelForPageA class, I can comfortably write this.setVisible(false), but how can I set page B to a visible state?
You can do the removal of panel a and then the addition of panel b trick. Another is to use a CardLayout.
When you create your panels, you add them to a containing JPanel that you initialize with a CardLayout:
JPanel container = new JPanel(new CardLayout());
containter.add(getPanelA(), "PANEL_A");
containter.add(getPanelB(), "PANEL_B");
Then, in your actionPerformed, when you want to show panelB, you do this:
CardLayout cl = (CardLayout) container.getLayout();
cl.show("PANEL_B");
Take a look at this tutorial for some more ideas.
For some reason, I can never to get setVisible() to work for me to do what you're describing. Instead, I do this:
frame.remove(panelA);
frame.add(panelB);
"frame" is just the JFrame you want to put the panels in. Try this if the setVisible() method doesn't work :)
To your original question, all you have to do is (like aioobe said):
panelB.setVisible(true);
((btw, posting some of your code would help me figure out what you're trying to ask))
And this is just a guess as to what you're trying to do -- I'm guessing your JPanels are in different classes. Then, you'll need to do this:
class pages extends JFrame implements ActionListener
{
public pages()
{
panelA a = new panelA(this)
}
changeToA(panelB b)
{
remove(panelB);
add(new panelA(this));
}
changeToB(panelA a)
{
remove(panelA);
add(new panelB(this));
}
}
class panelA extends JPanel implements ActionListener
{
pages p;
public panelA(pages p)
{
this.p = p
}
// all that actionlistener code stuff
p.changeToB(this);
}
class panelB extends JPanel implements ActionListener
{
pages p;
public panelB(pages p)
{
this.p = p
}
// all that actionlistener code stuff
p.changeToA(this);
}
You pass the pages class to the panels so the panels can tell the pages class to remove themselves.
((I don't know if there is an easier way, but this is what I do all the time))
I hope I helped :)
You have to remove Panel A from the frame, add Panel B to the frame, and call invalidate on the frame (or containing panel). At least in Swing, I'm not sure about AWT, there you might need repaint or revalidate instead of invalidate.
You could also just create a whole new JFrame and dispose the one containing panel A.

Categories