I am just starting to make a simple mp3 player, I am creating the play, forward, back, etc... Button but for some reason only the first button appears and to make the second button appear I have to go and scroll over it. If you could help me fix that, that would be great. And I am using a two images one named play.jpg and another named next.png.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Graphic extends JPanel{
JFrame f = new JFrame();
JPanel p = new JPanel(new GridBagLayout());
public Graphic(){
gui();
}
public void gui(){
f.setVisible(true);
f.setSize(1600,900);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p);
ppr(75,26,25,25,"pics/play.jpg");
//above is the play button
ppr(40,26,25,25,"pics/next.png");
// above is the button that wont appear until it is scrolled over (it is just to the left of the button above
}
public void ppr(int x, int y, int width, int height, String file){
p.setLayout(null);
Toolkit tool = Toolkit.getDefaultToolkit();
Image player = tool.getImage(file);
ImageIcon playbutton = new ImageIcon(player);
JButton play = new JButton(playbutton);
play.setBounds(x, y, width, height);
p.add(play);
// ********************** above is the the method that makes a button
}
public static void main(String args[]) {
new Graphic();
}
}
Don't use setBounds. Use GridBagLayout
you specified while initialising the panel and specify GridBagConstraints
The setVisible(true) method should be invoked AFTER all the components have been added to the GUI.
I also agree with the other suggestions for better GUI design.
Run the GUI in a different thread, not the main thread.
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
All UI code should be run in the event dispatch thread for Swing.
Related
I don't understand this, I'm currently making a main menu for a game i'm making but for some reason when I hover over a JButton, it flashes up on the top left side of the JFrame. I don't have any mouseAction methods or anything, is it the gif i'm using? I'm not sure...
Here is a screengrab of the error
Here is my code :
import javax.swing.*;
import java.awt.*;
public class MainMenu {
JFrame frame = new JFrame("Frasergatchi");
public void display(){
frame.setSize(400,400);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true);
}
public void addComponents(){
JButton play = new JButton("Play");
JButton instructions = new JButton("Instructions");
JButton exit = new JButton("Exit");
JPanel panel = new JPanel();
paintMenu paintMenu = new paintMenu();
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
frame.add(panel);
play.setAlignmentX(Component.CENTER_ALIGNMENT);
instructions.setAlignmentX(Component.CENTER_ALIGNMENT);
exit.setAlignmentX(Component.CENTER_ALIGNMENT);
panel.add(paintMenu);
panel.add(play);
panel.add(instructions);
panel.add(exit);
}
public class paintMenu extends JPanel{
public void paintComponent(Graphics graphics){
Image dog = new ImageIcon(getClass().getResource("DogMenuImage.gif")).getImage();
graphics.drawImage(dog,170,240,this);
}
}
}
The first statement in the paintComponent() method should always be:
super.paintComponent(g);
to make sure the background gets cleared.
Also:
Don't do I/O in a painting method. Painting methods are for painting only. Read the image in the constructor of your class and same the image in an instance variable.
Class names SHOULD start with an upper case character. Think of all the classes in the JDK and follow the standards.
There is no need to create a custom class to paint the image. Just use a JLabel with an Icon.
So I have 2 classes. One that creates a JPanel and a JFrame, and one that creates Buttons. Now I want to add those Buttons to my JPanel.
Where my JPanel and JFrame are created:
public class Surface extends JPanel implements KeyListener, ActionListener
{
private static final long serialVersionUID = 1L;
static JFrame jframe = new JFrame("TitleComingSoon");
Snake mySnake = new Snake(true);
int width;
int height;
#SuppressWarnings("deprecation")
public Surface(int width, int height)
{
this.width = width;
this.height = height;
// Create the JPanel
setLayout(null);
setBounds(0, 0, 400, 400);
setBackground(Color.DARK_GRAY);
// Create the JFrame
jframe.setSize(width, height);
jframe.setResizable(false);
jframe.setLayout(null);
jframe.add(this); // Add the JPanel to the JFrame
jframe.setVisible(true);
// Add the KeyListener
addKeyListener(this);
setFocusTraversalKeysEnabled(true);
setFocusable(true);
requestFocusInWindow();
show();
}
#Override
public void paintComponent(Graphics diamond)
{
super.paintComponent(diamond);
diamond.drawRect(60, 60, 100, 50);
diamond.setColor(Color.RED);
repaint();
}
}
And in my other class I'm doing this:
Surface.jframe.add(myButton);
My problem is, that the buttons is under the JPanel. So if I remove the JPanel, I can see the button.
Several things jump out...
Use of null layouts. While it might seem like you gain control, you increase your work load and lose flexibility between platforms.
Creating a frame from with another component, but more importantly, from within its constructor. The panel shouldn't be concerned with how it will be displayed and should be focused on doing the job it was designed for.
Use of KeyListener. KeyListener is fussy and troublesome, better to use the Key Bindings API
Use of static for cross object communication. Static is not how you provide access to fields across classes, there are plenty of other techniques which provide better support. The main problem is, if you create another instance of your pane, you'll create a new frame and change the reference to the static field...now which frame are you actually addressing?
So, what's the solution?
From your "main" entry class, create an instance of a JFrame, your Surface panel and button. Set the Surface panel as the content panel of the frame, then add the button to the frame.
Make use of appropriate layout managers
Use the key bindings API instead of KeyListener
You could create an instance of your ButtonHolderClass in Surface and retrieve the button by way of a public getter method:
public Surface(int width, int height)
{
...
ButtonHolderClass buttonHolder = new ButtonHolderClass();
JButton myButton = buttonHolder.getMyButton();
add(myButton); // Add myButton
jframe.add(this); // Add the JPanel to the JFrame
}
Surface.jframe.add(myButton);
You are adding the button to the JFrame. You said you wanted to add it to the JPanel.
Simply make it
Surface.add(myButton);
Surface.jframe.add(Surface);
That will add the JButton to the JPanel, then it will add the JPanel to the JFrame.
There is a slight problem in ordering things here. You are adding your Surface instance to the frame before the Surface constructor is done constructing it.
package test;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Surface extends JPanel {
static JFrame jframe;
static Surface surfaceInstance = new Surface();
public static Surface getInstance() {
return surfaceInstance;
}
public static void main(String argv[]) {
/* You need this to be a good friend of the Swing */
Runnable initiator = new Runnable() {
public void run() {
jframe = new JFrame("Whatever title you want");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // this will kill the application when you close the frame
jframe.setContentPane(Surface.getInstance());
jframe.pack();
jframe.setVisible(true);
}
};
/** You let the Swing run your initiator when Swing wishes to do so */
SwingUtilities.invokeLater(initiator);
Surface.getInstance().setPreferredSize(new Dimension(400,400));
/** then you can add other stuff to it **/
for (String buttonTitle: new String[] {"button1", "button2", "button3"}) {
Surface.getInstance().add(new JButton(buttonTitle));
}
}
}
I am facing a bit problem as I am a newbe in Java. I made two frame, the first one's name is test and the second one is Login. In the test Jframe, there are three buttons. The third one which name is "Admin" is for taking me to the second frame. How can I make the third buttonwork to take me to the second frame without closing the first frame?
Thanks in advance.
import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.*;
public class test extends JFrame {
private static final int width = 600, height = 480;
private static final int buttonWidth = 200, buttonHeight = 100;
static JFrame frame;
static JButton button;
static JButton button2;
static JButton button3;
public static void main(String[] args) {
createWindow();
createButtons();
addEverything();
frame.setVisible(true);
}
private static void createWindow() {
frame = new JFrame("Welcome to Easy Hire");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);
}
private static void createButtons() {
button = new JButton("Hire A Taxi");
button.setLocation(0, 0);
button2 = new JButton("User Login");
button2.setLocation(200, 0);
button3 = new JButton("Admin");
button3.setLocation(400, 0);
}
private static void addEverything() {
addButtons();
}
private static void addButtons() {
frame.getContentPane().setLayout(null);
frame.getContentPane().add(button);
frame.getContentPane().add(button2);
frame.getContentPane().add(button3);
button.setSize(200,50);
button2.setSize(200,50);
button3.setSize(200,50);
}
}
Suggestions:
To give JButtons behaviors, add ActionListeners to them via the addActionListener(...) method. I don't see that you've tried this.
You should avoid having more than one JFrame in an application as the JFrame is usually the application's "mother ship".
If you need to show a dialog window, such as a log-in window, use a dialog, a modal JDialog to be exact.
If you need help showing this, show your attempt at doing this.
Avoid null layouts and absolute positioning of components. This way leads to madness.
Useful Java Tutorials:
The Really Big Index: the main tutorial where you should start.
Using Swing Components: how to create Swing GUI's
How to Use Buttons, Check Boxes, and Radio Buttons
How to Write an Action Listener
My JFrame is not displaying the button or background color that is set in the constructor. I am only getting a blank box when I start the program. Not sure what is wrong with the code.
//imports
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;;
public class StartingTheCode{
JButton CalculateButton;
JTextField Ans;
JPanel p;
JFrame f;
public static void main (String[] args){
new StartingTheCode();
}
//constructor
StartingTheCode(){
f = new JFrame("test");
f.setVisible(true);
f.setSize(600,600);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new JPanel();
p.setBackground(Color.BLUE); // not displaying blue background
CalculateButton = new JButton("+"); // should display button
CalculateButton.setSize(30,30);
CalculateButton.setLocation(5,5);
}
}
You're not adding your button or your JPanel to anything, and so no JFrame is magically going to display them.
You should add your JButton to your JPanel via its add(...) method, and then add the JPanel to the JFrame via its add(...) method, and do so before setting the JFrame visible.
Most importantly, you should read the Swing tutorials, since I speak from experience when saying you'll get no-where just guessing at this stuff. This is all well explained there.
As an aside, avoid setting the sizes of any components and instead read the tutorial section on use of the layout managers as it will allow you to simplify and empower your code greatly.
You need to add your calculateButton to the JPanel with p.add(calculateButton) and add the panel to the frame with f.add(p)
I Have applet with a image of a java cup that can be repositioned by the clicking of 5 buttons to move it in the main area of the applet window.
the issue im having is the buttons are not being displayed in im applet the only thing that is showing is my cup.gif on the blue background, can any one see the problem with the code ,i want the buttons to show and work
And yes guys I know AWT is old but i have to learn it for my course...any help would be great thanks guys!
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class moveIt extends Applet implements ActionListener
{
private Image cup;
private Panel Keypad = new Panel();
public int top = 15;
public int left = 15;
private Button Keyarray[] = new Button[5];
public void init ()
{
cup=getImage(getDocumentBase(), "cup.gif");
Canvas myCanvas= new Canvas();
Keyarray[0] = new Button ("Up");
Keyarray[1] = new Button ("Left");
Keyarray[2] = new Button ("Down");
Keyarray[3] = new Button ("Right");
Keyarray[4] = new Button ("Center");
setBackground(Color.BLUE);
Panel frame = new Panel();
frame.setLayout(new BorderLayout());
frame.add(myCanvas, BorderLayout.NORTH);
frame.add(Keypad, BorderLayout.SOUTH);
Keypad.setLayout(new BorderLayout());
Keypad.add(Keyarray[0], BorderLayout.NORTH);
Keypad.add(Keyarray[1], BorderLayout.WEST);
Keypad.add(Keyarray[2], BorderLayout.SOUTH);
Keypad.add(Keyarray[3], BorderLayout.EAST);
Keypad.add(Keyarray[4], BorderLayout.CENTER);
Keyarray[0].addActionListener(this);
Keyarray[1].addActionListener(this);
Keyarray[2].addActionListener(this);
Keyarray[3].addActionListener(this);
Keyarray[4].addActionListener(this);
}//end of method init
public void paint(Graphics g)
{
g.drawImage(cup, left, top, this);
}
public void actionPerformed(ActionEvent e)
{
String arg= e.getActionCommand();
if (arg.equals("Up"))
top -= 15;
if (arg.equals("down"))
top += 15;
if (arg.equals("Left"))
left -= 15;
if (arg.equals("Right"))
left += 15;
if (arg.equals("Center"))
{
top=60;
} left=125;
repaint();
}//end paint method
}//end of class
You never add the frame to the applet this.add(frame)
Once you do, you will have to setOpaque(false) to the frame so you can see the background
Important Side Notes:
Instead of painting on the Applet directly, you should be painting rather on a JPanel and override it's paintComponent method.
You Need to call super.paint(g) or super.paintComponent(g)(for JPanel) in the paint method, as to not break the paint chain and see all kinds of wierd paint artifacts
I just noticed the AWT components. AWT is pretty much obsolete. You should move it up to using Swing. See the Swing Tutorials
Use Java naming convention. Variables begin with lower case letters, using camelCasing e.g. Keyarray → keyArray. Class names begin with capital letters using CamelCasing e.g. moveIt → MoveIt