Some time ago I wrote a code in a single main class which worked fine. Later I added JPanel and JFrame in again its single main it again worked fine.
Now I am trying to break the code down and move them into packages.
here is my main
-( src/start/Main.java)-
package start;
import javax.swing.JFrame;
import frames.*;
public class Main {
public static void main(String[] args) {
MainFrame.createFrame();
LogoPanel.createLogoPanel(); //this line is the problem
}
}
here is MainFrame
-(src/frames/MainFrame.java)-
package frames;
import javax.swing.JFrame;
public class MainFrame {
public static JFrame createFrame() {
JFrame frame = new JFrame ("App");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setResizable(false);
frame.setBounds(140,140, 1000, 580);
frame.setVisible(true);
frame.setLayout(null);
return frame;
}
}
here is LogoPanel
-(src/frames/LogoPanel.java)-
package frames;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LogoPanel {
public static JPanel createLogoPanel(JFrame frame) {
JPanel logoPanel = new JPanel ();
logoPanel.setVisible(true);
logoPanel.setBounds(0, 0, 1000, 80);
logoPanel.setBackground(Color.gray);
logoPanel.setLayout(null);
frame.add(logoPanel);
return logoPanel;
}
}
as I said LogoPanel.createLogoPanel(); is the problem . It does not accept createLogoPanel(JFrame frame) from me ? setting it to null doesn't show the panel at all . anyway I can make this work ?
Your createLogoPanel takes a JFrame type argument.
But I don't see you passing an argument when you are actually invoking the method.
Do something along the lines of :
JFrame frame = MainFrame.createFrame();
LogoPanel.createLogoPanel(frame);
This error seem to suggest a lack of understanding about basic Java syntax and concepts. If you are able to accumulate knowledge in this area it will benefit you greatly in the future.
Related
I have a program that consists of four JButtons in a JFrame. I want to add images to the JButtons. The problem is that I can't seem to add them, despite trying multiple methods. When compiled, the output is input == null. The images are stored in the same folder as my .java files, so I can't figure out why they aren't showing up.
Main class:
import java.awt.GridLayout;
import java.awt.Image;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AutoProgram extends JFrame {
private static String[] files = {"workA","programmingA","leisureA","writingA"};
private static JButton[] bIcons = new JButton[4];
private static Image[] bImg = new Image[4];
public AutoProgram() {
super("Automation Project V.1");
JPanel autoIcons = new JPanel();
autoIcons.setLayout(new GridLayout(2,2));
// Initialize the four buttons (w/ images)
for(int i = 0; i < files.length; i++) {
bIcons[i] = new JButton();
try {
bImg[i] = ImageIO.read(getClass().getResource(files[i].toLowerCase() + ".png"));
bIcons[i].setIcon(new ImageIcon(bImg[i]));
} catch (Exception ex) {
System.out.println(ex);
}
autoIcons.add(bIcons[i]);
}
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));;
mainPanel.add(autoIcons);
add(mainPanel);
pack();
}}
Window class:
public class Window {
public static void main(String[] args) {
AutoProgram frame = new AutoProgram();
frame.setSize(315,315);
frame.setLocationRelativeTo(null);
frame.setFocusable(true);
frame.setResizable(true);
frame.setVisible(true);
}
}
Any help would be greatly appreciated. Thanks!
Before going into the answer to your question, please read the following recommendations:
private static JButton[] bIcons = new JButton[4]; Creating static fields could break your program, so be careful when to use them. Not really needed in this case, please read What does the 'static' keyword do in a class?
JFrame is a rigid container which cannot be placed inside others, and you're not changing it's functionallity anywhere in your program, so there's no need to call extends JFrame, it's better to create a JFrame instance then. See: Extends JFrame vs. creating it inside the program for more information about this.
You're correctly calling pack() but later in the code you're calling frame.setSize(315,315); which "destroys" the changes made by pack(), use one or the other, not both, I recommend you to leave pack() call.
You're not placing your program in the Event Dispatch Thread (EDT), you can fix it by changing your main(...) method as follows:
public static void main (String args[]) {
//Java 7 and below
SwingUtilities.invokeLater(new Runnable() {
//Your code here
});
//Java 8 and higher
SwingUtilities.invokeLater(() -> {
//Your code here
});
}
Now, let's go to the solution:
Your code works fine, I think that your errors might come from the following posibilities:
Calling files[i].toLowerCase() (.toLowerCase() method might be breaking your program, Java is case sensitive).
Your images are not PNG but JPG or JPEG (look at the extension carefully)
Your images are damaged
so i was getting a error in Eclipse for my java program to make a new JFrame and i couldnt quiet figure out my it wouldnt load the correct data to set it to be visable and to set the title, location, size, and what it should do when someone closes the JFrame so id like some help if i could please
import javax.swing.*;
import java.awt.*;
public class JFrame
{
public static void main(String[] args)
{
JFrame JF = new JFrame();
JF.setTitle("Test");
JF.setSize(400, 200);
JF.setLocation(200, 300);
JF.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
JF.setVisible(true);
}
}
Thanks for the help in advance
You named your own class JFrame, thus hiding the standard javax.swing.JFrame class.
Choose another name for your class.
First of all, this is a more specific question than it seems to be. To start off: I am currently doing a small application with a rather small GUI, so I decided to make a GUI class, and initialize my whole GUI in this constructor.
This would look like this:
public class GUI extends JFrame{
public GUI{
//Initialize GUI here, including its Frames, Panels, Buttons etc.
}
}
How can I now access the GUIs frame etc. from an external class? If I would create an object of the GUI class, I would simply duplicate my GUI window. I did not come across any other ideas than making the frame, panel and so on static.
I'm somewhat lost right now. Also I'm pretty sure that I am not thinking the right way into this case, but I need someone to point me to the right direction. If someone could help me out, I would be very thankful.
First of all, using static is the worst solution possible, even if your GUI class is a singleton (buf if it is, at least it will work fine).
Why don't you simply create getters and/or setters ? And finally, it is usually not normal that external classes need to access the components of another graphic class. You should wonder if your design is the most fitted for your needs.
Here's a simple GUI to change the background color of a JPanel with a JButton. Generally, this is how you construct a Swing GUI.
package com.ggl.testing;
import java.awt.Color;
import java.awt.FlowLayout;
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.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ChangeDemo implements Runnable {
private boolean isYellow;
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new ChangeDemo());
}
#Override
public void run() {
frame = new JFrame("Change Background Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
JPanel namePanel = new JPanel();
JLabel nameLabel = new JLabel(
"Click the button to change the background color");
nameLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
namePanel.add(nameLabel);
mainPanel.add(namePanel);
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.setBackground(Color.YELLOW);
isYellow = true;
JButton changeButton = new JButton("Change Color");
changeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
isYellow = !isYellow;
if (isYellow) buttonPanel.setBackground(Color.YELLOW);
else buttonPanel.setBackground(Color.RED);
}
});
buttonPanel.add(changeButton);
mainPanel.add(buttonPanel);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
You don't access the Swing components of the GUI from other classes. You create other classes to hold the values of the GUI.
Generally, you use the model / view / controller pattern to construct a Swing GUI. That way, you can focus on one part of the GUI at a time.
Take a look at my article, Java Swing File Browser, to see how the MVC pattern works with a typical Swing GUI.
You don't need to make it static or to create a new JFrame object every time.
Have a look at this simple code :
class UseJFrame {
public static void main(String...args) {
Scanner sc = new Scanner(System.in);
JFrame frame = new GUI();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
System.out.println("Press E to exit");
String ip;
while(true) {
System.out.println("Show GUI (Y/N/E)? : ");
ip = sc.nextLine();
if(ip.equalsIgnoreCase("y") {
frame.setVisible(true);
} else if(ip.equalsIgnoreCase("n") {
frame.setVisible(false);
} else { // E or any other input
frame.dispose();
}
}
}
}
Note : Don't make GUI visible through constructor or it will show window at the very starting of creation of JFrame object.
If you want to use the same JFrame object at other places too then pool architecture would be better approach.
I'm creating an application in which I have a class with a main frame (JFrame), and a class which is a JPanel subclass called OvalPanelClass. I say main frame because the user has the option to open up another JFrame (window). This OvalPanelClass is dynamic and displays its images using a BufferStrategy. It is both launched into a separate JFrame on some occasions and appears at the bottom right section of the main frame at some points too, so I didn't feel it made sense to make this class an inner class of the class containing the main frame.
The problem is that as this JPanel is not a part of a class with a JFrame it cannot make the call to get the BufferStrategy and so on. So to get over this I tried passing a reference to the main frame to the OvalPanelClass constructor but I'm not getting results. My question is what is flawed with my reasoning?
FrameClass
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FrameClass extends JFrame {
public static void main(String[] args) {
FrameClass test = new FrameClass();
test.setup();
}
void setup() {
setPreferredSize(new Dimension(800, 800));
JPanel background = new JPanel(new BorderLayout());
getContentPane().add(background);
setVisible(true);
OvalPanelCanvas shape = new OvalPanelCanvas(this);
//shape.setup(this);
background.add(BorderLayout.CENTER, shape);
pack();
shape.repaint();
}
}
OvalPanelCanvas
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class OvalPanelCanvas extends JPanel {
JFrame frame;
BufferStrategy bs;
public OvalPanelCanvas(JFrame frame) {
this.frame = frame;
setOpaque(false);
}
public void paintComponent(Graphics g) {
frame.createBufferStrategy(2);
bs = frame.getBufferStrategy();
Graphics bufferG = bs.getDrawGraphics();
for (int i = 0; i < 5; i++) {
int width = 50;
int height = 50;
bufferG.setColor(new Color(i*5,i*6,i*50));
bufferG.fillOval(0, 0, width*i, height*i);
}
bufferG.dispose();
bs.show();
}
}
Thanks for your time! I'm being vague about what the project is and have stripped away what I felt were irrelevant details but if you need some more context let me know.
I'm having a similar issue. I think it has more to do with not using Canvas vs. using JPanel. For instance I have images on a sprite sheet that I cannot use because my class extends JFrame and not Canvas. The reason that being is because I am using the JFrame addon from within eclipse that automatically extends JFrame on the creation of the JFrame in the window class.
I want to know how to place JButtons at a particular coordinate in the JFrame. All day I have seen layouts. This does not suit my purpose. I would prefer something like setBounds. Rumour has it that it does not work but setLocation does. I tried it but, the program disregards the setLocation line and sets it to a Layout.
CODE
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;
public class SwingUI extends JFrame {
public SwingUI() {
JFrame frm = new JFrame("OmegaZ");
JButton btn = new JButton("ClickMe");
frm.getContentPane().add(btn, BorderLayout.NORTH);
frm.setSize(400, 400);
frm.setVisible(true);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
btn.setLocation(100, 200);
}
public static void main(String[] args) {
new SwingUI();
}
}
Any help is appreciated.
Many Thanks
You can do absolute positioning with a null layout. You do all the work in that case.